Reflection and quotation
RE01 Rice Brian T. EM2
BRice@vinson.navy.mil
Fri, 18 Aug 2000 20:36:23 -0700
My schedule got pretty hectic for a bit, so my reply was delayed a bit.
> -----Original Message-----
> From: Kyle Lahnakoski [mailto:kyle@arcavia.com]
> Sent: Friday, August 18, 2000 6:01 AM
> To: RE01 Rice Brian T. EM2
> Cc: 'tunes@tunes.org'
> Subject: Re: Reflection and quotation
> "RE01 Rice Brian T. EM2" wrote:
> > > I consider quoting as only a special form of referencing:
> > > referencing by unique attribute.
> >
> > That's odd. I thought that Tunes defined attributes in
> terms of functions.
> > :)
> >
> > Indeed, right on the HLL Semantics page
> > (http://www.tunes.org/HLL/semantics.html), attributes are
> listed as unary
> > functions. Now, if you want Tunes goals, then
> meta-programming has to be
> > considered, and higher-order attributes simply *are*
> functions, whether you
> > like that or not.
> >
> > In fact, many languages do this in order to provide
> "object-orientedness".
> > And if memory serves me correctly, ML has higher-order
> references, since it
> > can hold a reference (not a pointer) as a variable, which
> can in turn also
> > be a higher-order functional term.
> >
> > Attributes, in other words, are just artifacts of a view on
> a system that
> > supposes the notion of state implicitly.
>
> A distinction between state and the ability to access the
> state must be made. I do agree that accessing the state can/
> must be done though functions when considering meta-programming.
> But I do not care how the state is realized, it can be primitive.
That's an interesting way to look at it, and we obviously agree beyond the
level of terminology. However, I think I need to add one minor point to
this: when I speak of state or attributes as based on functions, I also mean
that I don't distinguish between "accessing state" and what a function does.
This is roughly similar to what Self and Smalltalk allow (and much more
similar to Lisp object systems) in that accessors are syntactically
indistinguishable from other functions on the object in question. One of the
ideas (hidden albeit) in the idea of the Tunes orthogonally-persistent store
is that state is just caching (memoization, if you will) of function values.
If you're thinking of your objects as denoting some "non-mathematical" idea
(one not usually associated with functional ideas like Jecel's pegboard idea
in Self in the other current e-mail thread), then the functions are just
"user-choices" which *must* be memoized because (or if?) they can't be
reproduced algorithmically. This relates to my idea of Arrow where the
important part of a computing system is that it conserves information until
discarded (coupled with Chaitin's idea of algorithmic information theory, of
course).
But this strays from the topic at hand...
> > > First I will make a simple, but necessary, distinction. A
> > > function is a
> > > static entity. Much like in set theory a function can be
> > > seen as a set
> > > of ordered pairs, a function can not DO anything. Performing the
> > > operation that a function specifies is a different concept
> > > altogether.
> >
> > This seems a totally arbitrary distinction to me,
> especially when you
> > consider higher-order functional programming. For instance,
> for any two
> > functions f and g, I could "define" a new function object
> using composition:
> > f*g or f(g) or even f+g. These functions at the language
> level exist only
> > for the duration of the context they produce: for example,
> for "f(g)(x)",
> > f(g) does not persist beyond the function call, but both f
> and g naturally
> > do.
>
> It depends on what you mean by exist. If you mean exist in terms of
> being explicitly referenced in a machine, then I would agree. On the
> other hand I like my functions to always exist in a giant function
> space. f, g, f*g, fog anf f+g always exist, it is only a matter of
> whether the machine is referring to those functions at any given
> moment.
I'd like to mean both, of course (since both are needed by computer
languages). In one case, I want my contexts to denote objects that
specifically define what that object can do. In other cases, I'd like the
object to act as a container for all objects of a specific type or
specification. In the latter case, a hook from the lookup function in the
meta-object allows those objects to be generated and cached on-demand.
> > And a function when considered in its enclosing context
> surely *does* have
> > state and can be muted, otherwise there's no point in
> programming such a
> > system (unless you care to express your programs in a
> calculus without any
> > notion of reference at all).
>
> Of course. I was trying to say that above and below. Many of our
> simple references mean nothing without the contextual baggage
> needed to
> interpret them. I was unclear trying to portray the fact that the
> baggage is also part of the reference.
Okay.
> > > Furthermore, the code that specifies the function is also
> a different
> > > concept. There are many languages that can express the same
> > > function.
> > > A function, as defined above, can be referred to using a
> variety of
> > > methods. The simplest is through the use of source code; the code
> > > identifys/specifies a function uniquely. But we could
> also a unique
> > > name, or integer ID. Note these three examples all
> require a frame of
> > > reference to be effective references. The source code needs
> > > a language
> > > definition, the unique name needs a name space and the unique
> > > ID needs a
> > > key space. Using this unique structure to refer to the
> > > function called
> > > referencing. Specifically: using source code to refer to a
> > > function is
> > > called quoting.
> >
> > But in Tunes, "source code" had better be a Tunes object,
> which means there
> > are various views of it, that for example consider it as an
> aggregate or a
> > stream or a generic function or whatever else you please.
> Besides, I believe
> > the notion of source code you're using is just an artifact of the
> > single-representation notion of code that languages are
> currently tied to,
> > which means *non*-reflective (lexically, syntactically, and
> semantically).
>
> I agree.
So, given all of the above discussion, what are your thoughts on quotation?
> > > The more general concept of referencing is what I define next.
> > > Referencing is the use of unique attributes to identify an object
> > > uniquely. For example I can refer to myself using "The Kyle
> > > Lahanakoski
> > > that lives in Canada".
> >
> > But what if there are two (or many) Kyle Lahanakoski's that
> live in Canada?
> > It's relative to context, of course, which is why
> reflection (and therefore
> > using (higher-order where necessary) functions instead of
> references per se)
> > is what's called for. I'm assuming here that context can
> change without the
> > computing environment's "permission", which it always does,
> even though
> > software systems are designed to enforce a particular
> implicit model of
> > various situations.
>
> There will be many assumptions in almost all references I would ever
> write down. That is because I would not have time to write all the
> assumptions. Yes, I did assume that my sentence is true for
> the time of writing, and not for all time. I hope you got my point
anyway.
>
> Some references require a temporal assumption, like my example above.
> The addition of this temporal assumption allows me to reduce the number of
> fields/slots I must use had I must assume "for all time".
> The addition of assumptions is of course just for textual brevity. Of
> course, a formal system would try to avoid these assumptions to
> maximize reflection.
The concept of assumptions is terrible. It's simply logically impossible to
enumerate anything close to "all assumptions", which is why I suggested a
constructive approach. That is, to build the functions that determine a
quoted expression's denotation, and have *that* function act as a context
building-block. That's what my lookup actions in the Slate MOP are doing in
the most general sense, and I intend to use all possible senses that suit
it.
> > > Computers refer to data structures
> > > using memory
> > > addresses though pointers.
> >
> > This last sentence is horrible. Am I supposed to think you mean the
> > processor itself? In that case, it's totally oblivious to
> data structures,
> > which makes the sentence meaningless. This is a totally
> low-level set of
> > semantics. Data structures are objects, and talking about
> their low-level
> > allocation and maintenance is just placing it within the
> context of a linear
> > type system. Of course, this allows one's references to be
> the pointers'
> > values themselves. In other words, I could have a Slate
> object act as a
> > linear memory namespace, whose slot names are what you
> would call the
> > "pointers" or "references". I could name them at *various* levels of
> > abstraction, and at the meta-level (the meta-object
> implementation of the
> > namespace) this would be provided by *functions* (which
> dynamically generate
> > behavior of slots based on the results of a function
> applied to the slot
> > name). Now do you see what I mean? I could label memory at
> the bit-level or
> > at the word-level or even abstractly using a segment-based scheme of
> > dividing the memory area which uses segments of variable size.
>
> Absolutely. Note that state is primitive construction wrt the machine
> hardware. The functions you propose are only accessing the state.
See the above notes about orthogonally-persistent stores and memoization as
a *sole* basis for "stored state". The view you suggest has an equally valid
dual view. I'm not saying you're "wrong" only that *both* views are
something to be got beyond when trying to build Tunes.
> > > Everything appears to be a reference. In the case of
> > > functions: source
> > > code and compiled bytes are both references to the same
> > > function object,
> > > but the function object is never realized in the machine. Every
> > > reference in a machine is really a representation of a
> > > reference. I say
> > > it is a representation of a reference because references need
> > > interpretation to become references. A representation of a
> > > reference is
> > > again a reference of a reference. Here we see a sort of
> > > recursion, and
> > > only a primitive/base case will allow use to make something
> > > useful. It
> > > looks as though Brian has seen this through his use of arrows.
> >
> > I think my reply concerning functions versus attributes as
> references should
> > make things clearer between us, especially with what you're
> trying to say
> > here (which sounds like higher-order functions in disguise).
>
> Yea, maybe.
> > > > In C, we have a hackish answer to this problem which I
> > > > believe suggests a Tunes way of handling this situation in
> > > general. We have
> > > > a finite set of symbols in our current protocol, and not
> > > all of them can be
> > > > part of the set of inputs directly, because the protocol
> > > outside the quotes
> > > > must be the same as that within (otherwise you can't
> have your full
> > > > expressiveness within the quotation). So in C (does even
> > > Lisp do this for
> > > > string types?) and other languages we reserve things like
> > > control characters
> > > > to allow for those characters. But what kind of
> > > functionality does this
> > > > provide in general terms? Control characters allow for a
> > > limited form of
> > > > recursion of quoting within languages like C. But in Tunes,
> > > we need to build
> > > > source objects from more simple object types using generic,
> > > flexible, and
> > > > above all, OPEN, functions.
> > >
> > > The quoting issue you raise is an ASCII limitation. As you
> > > pointed out,
> > > C solves this problem. I will go though several
> iterations of quoting
> > > my name Kyle:
> > > "Kyle"
> > > "\"Kyle\"" <- I escaped my quotes
> > > "\"\\\"Kyle\\\"\"" <- Escaping \ and "
> > > "\"\\\"\\\\\\\"Kyle\\\\\\\"\\\"\" <- And so on
> > >
> > > As a typed data structure, the quoting is much simpler:
> > >
> > > "Kyle"
> > > A -> "Kyle"
> > > B -> A
> > > C -> B
> > >
> > > "->" is read as "refers to". We can note that there is
> an equality
> > > between A and "\"Kyle\"" because they both refer to the
> same thing.
> > > ASCII is doing a bad job because it does not have an infinite
> > > alphabet.
> > > C takes care of that, but is ugly. A second solution
> uses a method to
> > > define new letters as references to established objects.
> Typed data
> > > structures allow the latter to happen quite simply. Just
> > > define objects
> > > that reference.
> >
> > The problem is that we want a functional notation for this.
>
> And like I said, the method used now is the creation of reference
> objects that can be used with relatively short names in the source
> code. Of course you need state for that.
Or orthogonally-persistent memoizaion of functions. ;)
Yes, I'm trying to drive this point home for you and many other Tunesers.
This should really be spelled out more clearly in the online Tunes
documentation (HINT, HINT).
> > But the way that it's done in Slate is open and extensible and
> > meta-programmable. *That's* the difference.
> Yea, of course!
Okay, something got through here, then. :)
What's important about this is that Slate's namespaces are not multi-sets
(i.e. no duplicate domain values in the lookup function). This directly
relates to the notion of identity in the object system used to "label" Slate
objects at any level, and if we want to transcend textual labels, then this
issue needs to be looked into.
> > Sorry, I'll reply to the rest later tonight, I promise. But the last
> > sentence you made is correct, and the part about how Slate
> creates and
> > rewrites its object graph is what I will address next.
>
> Thanks
>
My time for e-mail is short. I'll pursue this a bit later.
Thanks,
~