At 02:35 AM 9/17/2007, Colin Putney wrote:
Alan, can you elaborate on what
you mean by "super time bombs?"
Sure. I simply meant that a block containing an assignment to the
internal state of an object can be passed around willy nilly to other
objects and some random time in the future can be sent value and
presto! you've cause a side effect on the internal state of the object
that will be very hard to track down if it's a bug.
That seems really bad (and is not scalable). It is like using getters and
setters instead of goals, but worse. Neither of these would be what I
would call real object-oriented design, which would emphasize the
separations between insides and outsides, between goals and methods,
between asking and telling.
Cheers,
Alan
On Sep 14, 2007, at 3:51 PM,
Alan Kay wrote:
Re: unification of blocks and
methods (procedures).
I first saw this in EULER (Wirth and Weber ca 1966), but then saw
an earlier similar notion by Landin in ISWIM and its predessors. I
used the idea in my first OOP language (FLEX ca 1967-9), which also
had complete static nesting of scopes, etc.
But later I decided I didn't like blocks as values because they are
super time bombs when passed around and completely violate
encapsulation. I really wanted external objects (not internal
blocks) to be passed around, and wanted a simpler way to think of
contexts internally. So we left them out of the first few
Smalltalks. (I still don't like them ...)
On Sep 16, 2007, at 2:52 AM, Marcel Weiher responded:
A block is just an
unattached/anonymous method body and a method
just a block with a name that's attached to a class.
However,
with that unified view it becomes immediately obvious that there is
something wrong with blocks. After all, we don't directly
call
methods in other cases, that's early binding and a Bad Thing.
Instead we send messages to objects. How does not naming the
method body make this type of early binding and leaking
implementation better?
That's not quite true. In Smalltalk, blocks *are* objects, and it's
not possible to directly "call" a block. Instead, you send
the
message #value to it. This isn't early binding, because there are
other things that respond to #value - MessageSends, for example, or
Seaside's Continuations. Heck, Object provides a trivial
implementation too.
I see what Alan was getting at about violating encapsulation: if
you
create a block that can access an object's internal state, then use
it as a method of some *other* object, you end up with two objects
that are quite intertwined, a sort of quantum entanglement between
objects. I've done some neat stuff with that in Javascript, but I
do
agree that it dilutes the strict purity of object orientation that
one finds in Smalltalk.
This is a bit strange, but I'm coming around to the idea that one
of
Smalltalk's greatest strengths is actually its block syntax. It'd
be
pretty tough to find a lighter-weight syntax for a closure. Even
Lisp
requires you to type out L-A-M-B-D-A, although the pain can be
mitigated with macros. Ruby comes close, but {} doesn't actually
create a real object. Javascript would be soooo much better if you
didn't have to type out "function(){}" to create a closure.
The
lightness of Smalltalk blocks is what makes gems like
#ifTrue:ifFalse: not only possible but practical.
Alan, can you elaborate on what you mean by "super time
bombs?"
Colin