On Wed, 30 Aug 1995 10:19:56 -0700, David.Ungar@Eng.Sun.COM (David Ungar) wrote:
And, I don't think Beta quite solves the block problem--
Consider that Beta still needs a built-in thing for if's, whereas ST & Self (& Scheme) don't. This is important because it means that it feels pretty heavyweight to use a user-defined control structure in Beta, compared to ST or Self.
When I wrote a Smalltalk-72 interepreter, early this year, I tried very hard to get rid of the built-in "if", but failed completely. This is one of the neatest features of later Smalltalks and Self.
As for Beta, it *is* possible to have a user defined IF. Here is my very first Beta program:
ORIGIN '~beta/basiclib/v1.4/betaenv' ---- program: descriptor ---- (# (* if.bet: * ======================= * Author: Jecel Mattos de Assumpcao Jr * * Purpose: * tests a user-defined IF pattern. * *********************************************************) myIf: (# mthen:< (# do INNER #); melse:< (# do INNER #) #); myBool: (# i: ^myIf; enter i do INNER #); myTrue: myBool (# do i.mthen #); myFalse: myBool (# do i.melse #); do & myIf (# mthen:: (# do '1' -> putline #); melse:: (# do '2' -> putline #) #)  -> myTrue;
& myIf (# mthen:: (# do '3' -> putline #); melse:: (# do '4' -> putline #) #)  -> myFalse;
Of course, you can see that it is so ugly that a built-in IF is very desirable :-)
David Ungar also wrote:
Also, consider that Beta has lexical scoping, as Jecel points out. This is great for some things, but does add complexity to the language-- should it be in or out? (Self has a little of it) I am not sure yet.
I would say that Self has no lexical scoping at all but fakes it with a "runtime patched dynamic scoping".
It is easy to see ( though a bit confusing at times ) that neither slot initializers nor inline objects are lexically scoped. This is a good thing for, as Rainer Blome points out, otherwise we would have problems with objects created graphically rather than by reading a file.
How about blocks, then? I can write:
| a. b | ......... [ | c, d | ....... .................. [ | e | e: a + b + c + d ] ... ....... ]
This certainly looks like lexical scoping. It feels like lexical scoping. It smells like lexical scoping :-) But it is really done by setting up dynamic parents ( self* or <lexicalParent>* ) at runtime so that the normal method lookup scheme does the right thing. Once the compiler inlines the blocks away, any difference between this and real lexical scoping goes away.
I had to think a lot about this when I was designing a Logo-like language that I derived from Self ( I called the language Troy ). Almost all logos are dynamically scoped, but some are lexically scoped. They can pass bits of code around, but don't have Self style blocks. I chose dynamic scoping but had to restrict it in order not to allow a violation of object encapsulation. Again, I was less that totally successful :-(