Additions to the Slate spec
RE01 Rice Brian T. EM2
BRice at vinson.navy.mil
Sun Nov 19 15:31:12 PST 2000
Hey Lee, Tunesers, and Slate people,
My access to the web has been sparse and fairly dismal lately, so a lot of
research and communication has been hampered. To complicate this, my Squeak
image seems to have been corrupted by a PC-to-Mac conversion error. It still
functions, but a lot of bugs creep up unexpectedly that make normal work
very tedious. At any rate, I am getting more proficient with VIM and EMACS,
so maybe this is helpful (for coding in other languages). Also, studying
Self 4.1 directly has been quite useful.
Anyway, since I'm not allowed to transfer files onto the LAN where I can use
e-mail, and I can't print out my notes for transcription, I'll summarize
what I've been working out. There are several things to address.
1. Using the lookup phase to make the system more flexible: if we allow the
quoting function to be open and flexible, then we can use the various
"modes" of quoting to distinguish between slots that are part of different
aspects (views) of an object. This could have quite a few benefits.
Keep in mind that the quoting mechanism changes could be really simple, like
(using lisp notation) "(define (quote' object) (lambda object (quote (cons
object foo))))". I'm suggesting that "'foo" would be a simple way to make
slots available for lookup or unavailable depending on the lookup mechanism
specified. Probably a lot of this would be meta-programmed (Slate macros
explained below).
Ex: the stack could be a slot (or set of slots) passed around with its own
unique quoting mechanism. This would essentially allow for a
continuation-passing style of programming when desired. Of course, Faré
would immediately say that those slots should be linearly passed around, and
I'd have to agree. At any rate, it allows objects to look at the "sender" of
the "messages" it receives and act according to that, which gives us a
handle for security without compromising the language design. Of course,
it's undesirable to force users to explicitly pass the stack around all the
time, which is why we should look into the ability to compose rewrites.
(There also shouldn't be anything wrong with implementing the stack using
the low-level stack, as long as it's wrapped properly.)
2. As for linearity/nonlinearity of slots, it seems that this should be
handled by a transaction scheme at the meta-level, but how this should be
done exactly is still fuzzy for me :/. At any rate, here's some pseudo-code
for the kind of transaction I'm considering:
Linear, strict (no copies) case:
Code: "<< my-secure-space private-PGP-key .... print ."
at the my-secure-space access, we're given a namespace whose lookups are
guarded, so we see something like this:
"i'd like slot private-PGP-key"
to which could be replied:
"slot not found. perhaps you don't have the right access key for this
space."
or "accesses from your location are not allowed by this object's author."
(the author could be another program, not just a user)
or perhaps it could simply add annotations to to the stack slots so that if
the rewrite method of that object were requested to be invoked ("."), then
it would block with a similar message.
Linear, non-strict (you get copies, you change copies, but the original is
read-only) case:
This can get elaborate, as you recall we discovered earlier considering
concurrent rewrites on the object graph. This complication will have to get
worked out later. At any rate, our "method" slots would have to work that
way.
Nonlinear case:
Basically no interaction happens except that the object gets marked as
nonlinear so that the GC handles it appropriately.
3. All of the above affects what kind of rewrite methods the system will
have to use. as Tunes specifies, Slate's method structure consists of
objects instead of meta-objects, but the rewrite aspects are handled at the
meta-level. Because this makes rewrite essentially invisible when looking at
source code, it should be relatively consistent all around. For one, the
usual rewrite should essentially be the equivalent of "pop", the
counterpoint of the "pushes" that are happening when we perform lookups.
The exceptions would be where the assignment slot ":" affects its sister
slot "^", or the various cloning rewrites (ones that clone just the slot one
level up, two levels up, or ones that essentially clone whole subsystems)
which would be meta-programmed.
4. Object/code format. Earlier, I was averse to the idea of using Self's
object-initialization syntax, and I tossed out the code format with it.
However, there's a small aspect of it which I think is useful, even more
useful for Slate. Since Slate's syntax is a sequence of symbol-lookups and
application hooks, I can model code as a sequence itself. In the simplest
case, I could take code like the above:
"<< my-secure-space private-PGP-key .... print ^ ."
And turn it into Slate object structure: (using a totally non-syntactic
representation)
print-my-PGP-key:
^:
1: '<
2: '<
3: 'my-secure-space
4: 'private-PGP-key
5: .
6: .
7: .
8: .
9: 'print
10: '^
11: .
Although "." would have to be distinguished from slot-access. Anyway, it's
at this level where lazy evaluation counts.
Also, this simple code shape allows for meta-programming in a couple of
different ways. For one, the lookup method could generate objects on demand
based on the symbol key used, and build the code for it using sequence
manipulation protocols (concatenate, insert, replace, etc.).
5. Speaking of meta-programming, there's a tiny meta-language that I've
discovered can be added to Slate. What it does is basically dynamic slot
creation within the same namespace as the method object. It also allows us
to add a kind of anonymous closure-structure to Slate grammar.
Basically, we could reserve "(" and ")" slots for this purpose. "(" would be
a clone of the surrounding namespace, to which would be mixed-in meta-object
characteristics that would pass around objects like closures do. ")" would
do a similar thing. I have some of the details worked out on my other
computer, but I need to work out the stack slot protocol first. As for
recursive use of "(" and ")", those would merely be the slots of those
objects looked up dynamically within the outer "(" and ")", so the behavior
would be understandable as far as I can tell. Perhaps other kinds of
brackets ("[]" or "{}" or "(* *)"?) would allow for variations on this
method.
At any rate, the availability of the stack itself and the frames there would
allow Slate code to take on lexical structure using the methods I describe
above. Ordinarily, it would be a minimal Forth-like system of code, which
lacks a lot of security and genericity.
That's most of what I have for now, in rough form. As I get more of this
specified, I'll add to the prototype code to see how it flies.
Thanks for the interest,
~
P.S. I will be back home from this long trip in two days. I'd like to meet
with Tril, Faré, Lee, hcf, and other interested parties on IRC to discuss
the documentation and code development.
More information about the Slate
mailing list