|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Darren New <dne### [at] sanrrcom> wrote:
> nemesis wrote:
> > The "On Lisp" book by Paul Graham is very good too. It's available in PDF and
> > explores Lisp macros as no other.
>
> Yep. Got it, read it. :-) I wish I had a use for it. :-)
Dude, slow down on that coffee! X^D
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
nemesis wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> nemesis wrote:
>>> The "On Lisp" book by Paul Graham is very good too. It's available in PDF and
>>> explores Lisp macros as no other.
>> Yep. Got it, read it. :-) I wish I had a use for it. :-)
>
> Dude, slow down on that coffee! X^D
Heh. Got it, read it many moons ago.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Nicolas Alvarez wrote:
> OMG, *that* is how they implemented it?!
Yeah. Generics are kludged in approximately the same way, with the extra
excuse that it allows generic code to interoperate with previously compiled
non-generic code.
They've locked themselves into a specific JVM, and nothing can change that now.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Warp <war### [at] tagpovrayorg> wrote:
> sounds like you could argue in favor of languages like brainfuck which
> have a minimal set of instructions, yet are still Turing-complete.
Scheme:
Minimalist. check
Power. check
Flexibility. check
Brainfuck:
Minimalist. check
> Eg. just because tail recursion is enough to perform any kind of
> looping construct doesn't necessarily mean that special looping constructs
> wouldn't be a useful tool.
That's why you got for-each in the standard and a few more. (which, obviously,
are macros wrapping tail-recursive calls)
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
nemesis <nam### [at] gmailcom> wrote:
> More than that, Common Lisp has CLOS:
> http://en.wikipedia.org/wiki/Common_Lisp_Object_System
"Like the OO systems in most dynamic languages, CLOS does not enforce
encapsulation. Any data member (or slot) can be accessed using the
slot-value function or via (optionally auto-generated) accessor
methods."
Your definition of object-oriented programming may vary, but in my view
data hiding, ie. modularity, is an integral part of OO programming. If the
internal structure of the object is exposed to the outside, you lose most
of the benefits of modularity.
I think that the typical impossibility or difficulty in data hiding in
languages which do not have specific support for modularity is a sign that
the "OOP" is, after all, just a kludge.
--
- Warp
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Warp wrote:
> Your definition of object-oriented programming may vary, but in my view
> data hiding, ie. modularity, is an integral part of OO programming.
It's pretty easy to fix in LISP if you really care - just make all your
local names gensyms. (If we're still talking about minimal support for lots
of paradigms, you could do this with some pretty simple macros, methinks.)
CLOS doesn't do this, because people who use LISP are usually pretty good
programmers.
> If the
> internal structure of the object is exposed to the outside, you lose most
> of the benefits of modularity.
Like, in unsafe languages, where a stray pointer can change private
variables without going thru the class methods? :-)
By this factor, I know of almost no actual OO languages besides Smalltalk
and Ada. (And Ada has OO features without being what I'd call an OO
language.) And I'm not sure you can't cast pointers inappropriately in Ada,
either. I'll look it up some day when I'm bored. :-)
C# and Java both have reflection that let you get to private members from
outside. C++ not only lets you return pointers to private members (which
isn't particularly bad in *my* opinion, see below, but you might disagree)
but also allows unsafe (in the technical sense[2]) access to private members
via undefined operations. It's pretty trivial to bypass all the modularity
in C++ since you need to be able to see the class declarations of the
private parts in order to access the class[1]. Python has the __dict__
element (et al) even if you had private variables. Pretty much anything
designed so you can serialize it has external access to private members.
> I think that the typical impossibility or difficulty in data hiding in
> languages which do not have specific support for modularity is a sign that
> the "OOP" is, after all, just a kludge.
Now, ya see, I see the point of modularity is to let me reason about the
code. If I have a private integer X, and the only things I set it to are 0,
1, or 2, then I should be able to have a switch with those three cases and
never miss one. Or, for a better example, if I have a buffer, and my class
is the only thing that writes to the buffer, I can ensure I never have a
buffer overflow. This isn't the case in C++ any more than it is in LISP or
Python. The only difference is, in LISP it's much harder to break by
accident. I don't see the advantage of making variables private if the
privacy isn't enforced well enough to give me more guarantees about the
program's execution. It's like having type declarations that aren't checked
at compile time or runtime - what's the point?
It would seem to be no harder to track down a bug caused by someone
accessing a private variable in a LISP object inappropriately than it would
be to track down someone overflowing a public array and clobbering a private
member in C++, especially since in LISP you'd actually have the name of the
private member somewhere in the source code module causing the trouble.
What do *you* think modularity is good for, that simply saying "stuff that
starts with an underline is private to the class" isn't adequate? I'm
seriously asking, because I'm wondering if I'm missing something.
[1] For example, you could declare an identical class with a different name,
except with all the privates public, then cast a pointer to the private
class into a pointer to the public class. Don't even need to depend on
compiler-specific knowledge about element layout and such. Or just declare a
child class that is happy to change any of its private variables.
[2] "Unsafe" means there are features with undefined behavior which may
affect the future state of the program, such that you can put values of the
wrong type into variables. That is, you can put values that don't belong to
the type into a variable of that type, or access values inappropriately
(such as accessing private variables from outside the scope you're supposed
to access them from).
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Darren New escreveu:
> Warp wrote:
>> Your definition of object-oriented programming may vary, but in my view
>> data hiding, ie. modularity, is an integral part of OO programming.
>
> It's pretty easy to fix in LISP if you really care - just make all your
> local names gensyms. (If we're still talking about minimal support for
> lots of paradigms, you could do this with some pretty simple macros,
> methinks.)
>
> CLOS doesn't do this, because people who use LISP are usually pretty
> good programmers.
Yes. Straight-jackets are generally viewed as a limiting "feature" by
people who actually know how to program rather than being a low-paid
drone. What really amazes me is when very smart programmers actually
enjoy being in the jacket and ask for more. :P
The best I've ever read on the subject comes from Larry Wall:
"The trend over the last 25 years or so has been to design computer
languages that enforce a state of paranoia. You're expected to program
every module as if it were in a state of siege. Certainly there are
some feudal cultures where this is appropriate, but not all cultures are
like this. In Perl culture, for instance, you're expected to stay out
of someone's home because you weren't invited in, not because there are
bars on the windows."
http://books.google.com.br/books?id=oh8lz4A3sUsC&pg=PA289&lpg=PA289&dq=larry+wall+house+invited&source=bl&ots=NcO4joArZd&sig=SaR-z_PriPfBbQaxNRAHpBfD_gc&hl=pt-BR&ei=dynBSYutLNuvtwfE0MXSCg&sa=X&oi=book_result&resnum=3&ct=result
Of course, such attitude would not stand the barbarism going on in
enterprise by thousands of code monkeys typing a bad rerun of
Shakespeare, but for one guy or 2 in the know alone working on a private
project, giving up all bureacratic measures for you not to shoot your
own foot may lead to an increased productivity with no sensible bug issues.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
nemesis wrote:
> Of course, such attitude would not stand the barbarism going on in
> enterprise by thousands of code monkeys typing a bad rerun of
I think by the time you get people so disconnected from each other that you
have to literally defend your code against them, you also have a
sufficiently big management structure that you can afford code reviews and
things like that. And if someone *does* need to bypass your API and access
the private variables, chances are you can either (1) get them to change the
implementation of the public API, or (2) if the author is (say) in another
company, it's a good thing you can bypass the lack of ability to do what you
need. :-)
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Warp wrote:
> "Like the OO systems in most dynamic languages, CLOS does not enforce
> encapsulation. Any data member (or slot) can be accessed using the
> slot-value function or via (optionally auto-generated) accessor
> methods."
BTW, this is only true in CLOS. If you actually implement OO using closures,
this isn't the case.
As a sort of C++ equivalent, consider C++'s upcoming lambda expressions. If
you write something like
{ int x, y;
x = 3; y = 4;
std::function pdq = [x,y](z) {return x+y+z;}
x = 8; y = 9;
// What here could you write to get the "4" that's in y inside pdq?
}
(Assuming I'm close on the syntax, and I think I'm saying pass x and y by
value to the pdq lambda thingie.)
Building OO via closures is like that, except the x and y serve the purpose
of instance variables. (C++ doesn't have actual closures, so the analogy is
flawed here, of course, but if you don't see how closures can make objects,
that should clarify it.)
If you could pass x and y by reference, declared several std::functions that
used them by reference, and then return collection of those functions
without actually losing the stack frame those referneces referred to, you'd
have objects-on-closures, with no access to internal instance variables.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
|
| |
| |
|
|
From: Fredrik Eriksson
Subject: Re: This is the sort of brokenness...
Date: 18 Mar 2009 13:43:54
Message: <op.uqz0vkjo7bxctx@e6600>
|
|
|
| |
| |
|
|
On Wed, 18 Mar 2009 17:44:23 +0100, Darren New <dne### [at] sanrrcom> wrote:
>
> [1] For example, you could declare an identical class with a different
> name, except with all the privates public, then cast a pointer to the
> private class into a pointer to the public class. Don't even need to
> depend on compiler-specific knowledge about element layout and such. Or
> just declare a child class that is happy to change any of its private
> variables.
Except that the compiler is not required to generate the same layout in
those two cases, so you would still depend on compiler-specific knowledge.
--
FE
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|