Archived from groups: rec.games.roguelike.development (
More info?)
In article <slrnd7cvs2.mar.sheep@atos.wmid.amu.edu.pl>,
The Sheep <sheep@sheep.prv.pl> wrote:
>Dnia Mon, 2 May 2005 14:09:40 -0400,
> Chris Reuter napisal(a):
>
>> In article <slrnd72dau.3s5.sheep@atos.wmid.amu.edu.pl>,
>> The Sheep <sheep@sheep.prv.pl> wrote:
>>>Dnia Thu, 28 Apr 2005 12:30:53 -0400,
>>> Chris Reuter napisal(a):
>
>
>>>> Ask me how Smalltalk does flow control. I dare you.
>
>>>It's not directed to me, but I'm curious.
😉
>>>How?
>
>> Long answer: Well, you asked. Now you have to read it.
>
>I'm very glad I asked. It's very interesting. And elegant.
>
>Somehow, reminds me of how TCL does it.
>
>Maybe because both ways are only possible when you can pass actual code
>as parameters?
>
>> In Smalltalk, everything[1] is done by sending "messages" to objects.
>> Sending a message is, for the purposes of this discussion, the same
>> thing as calling a method (aka "member function") so I'm going to
>> pretend they're the same thing, but I'll probably keep calling them
>> messages out of habit so I figured I'd warn you now.
>
>That's how OOP was defined in the first place, isn't it?
Depends on the language. Python doesn't (AFAIK) have a concept of a
message but has about the same level of flexibility. C++, on the
other hand, is far more restrictive. Java seems to be somewhere in
between, although I could be wrong.
Messages make a lot more sense if you look at Smalltalk-72, the
original version of the language. (Smalltalk underwent two different
major revamps. The version everyone uses now is actually
Smalltalk-80.)
In Smalltalk-72, the message was whatever text was to the right of the
object and the object would actually parse the message and do what it
wanted with it. This made for a really, really powerful language but
no two Smalltalk programs looked like they were written in the same
language.
Between then and 1980, they fixed that problem by limiting what
messages could be. Along the way, messages sort of turned into method
calls and most OO languages don't really have the concept at all.
In modern Smalltalk, messages mean:
1) Calling a method will work, regardless of its implementation or
the object's inheritance structure, so long as there's a method with
the expected name there.
2) If there's no method corresponding to the message, you can
catch that and add other behaviour.
For example, in QFP, I implement creature stats by making the stats
objects, then catching message sends that follow a particular naming
pattern and doing the right thing.
So when I do something like:
aMonster atStatStrength: 42
there is no method named "atStatStrength:". Instead, it calls
"doesNotUnderstand:", which gets the method name, sees the "atStat"
part, extracts the "Strength" part from the message name, pulls the
Strength object from its hash of stats and stores the argument (42)
there.
3) You can piece together message sends programmatically. For
example, you might create a string and send it as a message to an
object.
Now, I know you can do all of this in Python, and I'm pretty sure
Perl lets you do it as well and neither of those languages have a
concept of "message", so I'm inclined to believe that these days,
messages are more of a convention than anything else.
>> This is true even if the method that created the block has already
>> returned. Is that cool or what?!
>
>It's weird. How about when you destroy the method? (it's an object too,
>isnt it?)
Everything's garbage collected so you don't actually destroy methods,
you just remove them from the class. If a block context hangs around,
it keeps the method alive.
The same is true of method contexts (i.e. the data structure that
holds the local variables of a particular method call--in C, it's a
stack frame). If a method does something like this:
SomeGlobal := [a + b thingee].
the block will live on after the method call that created it returns
but the block will keep the method context alive since, after all, a
and b are local variables. You can then continue to evaluate the
block however often you want.
Also, blocks can contain returns. This:
SomeGlobal := [^a].
SomeGlobal value.
will cause the current method to return but the block that did the
return will still exist because a global keeps it alive. And if you
try to evaluate the block again, you'll get a runtime error because
you can't return more than once.
>Thank you very much for your time to write all this. I could probably find
>it in some SmallTalk tutorial, but I didn't expect it'd be so fun.
Yeah, Smalltalk is way fun. Join ussssssss. Join usssssss.
--Chris
--
Chris Reuter
http://www.blit.ca
"Please stop putting my life in perspective. It's very annoying."
--Pearls Before Swine, 2004/7/23