scoping (was: implementation issues)
Jecel Mattos de Assumpcao Jr.
jecel at lsi.usp.br
Thu Aug 31 19:26:22 UTC 1995
On Wed, 30 Aug 1995 10:19:56 -0700,
David.Ungar at 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:
---- program: descriptor ----
* Author: Jecel Mattos de Assumpcao Jr
* 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 #);
& 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 :-(
More information about the Self-interest