[Squeak-e] Re: Comments on Lex's "Object as Capabilities in Squeak"

Mark S. Miller markm at caplet.com
Sat Feb 1 23:48:28 CET 2003


Answering out of order.

At 12:26 AM 1/31/2003 Friday, Lex Spoon wrote:
>Your notion of 4 levels of effort is a great basis of discussion.  In
>fact, I believe Islands works at level 4, though it is more awkward for
>such thigns than E.  I'll attach my solution to the little-money problem
>at the end of the message.  Still, as you guessed, the goal of the
>project was more for level 1 or maybe level 2 (eg, retracting sound
>access from annoying squeaklets), with hopes of making a basis for level
>4.

As I count it, everyone would like to reach for level 4. So let's proceed 
with that as a shared goal, being willing to pay the incompatibility price 
along the way, so that we can see how big that price is at the end of the 
day, and how we feel about it.


>There is a big engineering effort to get away from dynamic binding of
>class names yet still have limited access to classes.  Happily, though,
>the independent modules efforts for Squeak seem to be solving this exact
>issue along with their other goals.

Where can I read about this?


>The more general dynamic global variables are annoying, but the one case
>of World is hard to do away with in Squeak.  World refers to the current
>morphic rendering unit.  Currently it is an entire desktop, though in a
>Squeaklet it would be more like one page or one subwindow. 

This demonstrates already that it was a mistake to make it global -- it 
needs to be bound to a different object when it appears in a Squeaklet.

>Plus, there is a tricky
>*conceptual* issue with getting rid of the variable.  It's just really
>convenient to have the world floating in the ether, and it would suck if
>Squeak code became significantly harder to write.

I think the real problem is that Squeak currently has a very rigid notion of 
lexically nested levels of instantiation:

Global
Class/Factory
Instance
Method (activation frame)
Block
Block
...

At the bottom of the hierarchy, one can add more levels freely. What is 
needed to address many of the problems that are coming up is the ability to 
add more levels between Global and Class/Factory. I suspect "World" should 
appear in one of these.

The Java ClassLoader mechanism adds exactly one additional level, which 
postpones the pain but doesn't cure the disease. Let's call this the "loader 
scope".

E and W7 have arbitrary and uniform lexical nesting to whatever depth or 
height is desired.

What would it mean for Squeak-E if a full class definition could appear in a 
method, just as a block-closure definition does now? Hell, even Java does 
proper lexically nested class definitions. Imagine perhaps a 
single-class-browser embedded in the method text, making the method editor 
pane into a compound document editor.


>Code uses World all over the place: there are 98 direct accesses to the
>variable, and 119 senders of #currentWorld.

How do I make such queries in my image?


>On another topic, you say that level-1 success, where you have
>completely isolated applets, is useless.  That is not actually true in
>Squeak.  The most important goal of Squeak is to allow a new way of
>composing electronic documents.  Level-1 success means Squeak documents
>can be exchanged safely, which is a huge step forward for Squeak.

"Useless" was harsh. Applets are certainly useless compared to their 
billing. But for interactive diagrams in documents, they should be great. 
I've been puzzled that there are so few even of these.


>Then, instead of writing
>> 
>>     x := ObjectInspector instVatOf: obj at: i
>> 
>> you'd write:
>> 
>>     x := (ObjectInspector new: obj) at: i

Oops, my second line should have said "instVarAt:" rather than "at:".

>I believe this is implemented.  However, the instance methods just call
>the class methods.  :)  I guess you'd actually want to use something
>other than this exact message sequence to *create* an ObjectInspector
>instance, though, in order to defeat using "myObjectInspector class" to
>create arbitrary new ObjectInspectors.

Yes. Which brings up the question, should Squeak-E objects respond to #class 
at all? #class is a query about an object's implementation, which is none of 
its client's business. In E, objects instead respond to __getAllegedType, 
which returns an immutable object (should only be read-only) which describes 
the API the original object responds to. In other words, the query-only
interface-information-only abstraction of messages like 
"allMethodsInCategory:" -- enumerating not the methods, but the names or 
signatures or something of the methods.

In any case, if Squeak-E classes are factories that may themselves have 
authority (having gotten it from an enclosing lexical scope perhaps), then 
it's important that one not be able to access an object's factory by default 
from the object. See http://zesty.ca/e-archive/ .


>Anyway, I never made a serious pass at secure debugging, and it seems
>like a low priority.  It seems very complicated -- e.g., the debugger
>itself may have to worry about being corrupted by the code it is
>debugging!

While I think it's important long term, I've postponed it for E as well. 
When the time comes, KeyKOS and EROS are the places to look for a full 
reconciliation of the tensions between security and debugging. But 
transposing their solution to a language context may require some research.


>Currently, literals in Squeak change all too often;
>specifically, I have a literal change about once a year, and it sucks
>when it happens.  :)  Making literals immutable along with read-only is
>a terrific thing.  The only time they are mutated in Islands, is when
>they are instantiated by the compiler when a method is compiled.

The literal itself is changed? I think I'm confused. This would seem to be 
very bad. I'm reminded of those old Fortran stories where an assignment 
could make all literal "5"s in a program have the value 3.


>(Implementation note: I never made an island-creating capability for
>Islands, and I never implemented a thisIsland facility for grabbing the
>island you are running in.  It seems like these would be very easy,
>however.)

What's the API of an island? If I hold a capability to an island, do I 
thereby have any authority beyond querying? If so, you should not provide 
a thisIsland that anyone can say.


>> This section refers to "methods that are marked as privileged". Even after 
>> reading the later section that explains this, I didn't feel like I 
>> understood how this marking happens, or how the authority to do this marking 
>> is controlled.
>
>You mark it by sending messages to the real, low-level class object, the
>same class object that the VM uses.  Thus it is as privilaged as it can
>be.

Cool.

>I really hope that Islands reaches the 4th level of success that you
>talk about, in which case normal users never need to write privilaged
>methods.  Who needs to define primitives, or access variables from the
>system's most privilaged island, or touch thisContext?  Logically no
>one, and hopefully this works out in practice.

Actually, thisContext or something like it may be fine, as open access to 
*this* stack frame, so long as the parent pointer is no longer open access 
to the parent frame, but instead at most an opaque continuation.


>> Can the same dynamic-variable-using instance be invoked from different 
>> processes (causing different bindings of the same use-occurrence of the same 
>> variable), or are dynamic-variable-using instance partitioned among the 
>> processes that can invoke them. Unfortunately, I suspect it's the first, but 
>> I'll wait to find out before arguing against it.
>
>It's possible for it to be the first.  For example, if a squeaklet forks
>a thread, then the thread will surely be given the same island and thus
>the same bindings.

I think I'm concerned about the opposite problem. If you have per-process 
variables, and objects are disjointly partitioned among processes, so that 
each object "lives" in only one process, and only gets invoked by that 
process, then the process scope becomes like an outer lexical scope. On 
object creation, the process scope is determined according to which process 
the object is created "in". OTOH, if the same object can be reached by 
multiple processes, then per-process-scoped variables must be disqualified 
for many of the same reasons that dynamic scoping is a bad idea.


More later...


----------------------------------------
Text by me above is hereby placed in the public domain

        Cheers,
        --MarkM



More information about the Squeak-e mailing list