[e-lang] Terms as Views

Kevin Reid kpreid at mac.com
Thu Aug 17 01:22:53 CDT 2006


Dean Tribble, I, and Mark Miller just thought this up.

I'm barely awake now, but I want to get this written down and out  
before I forget most of it. Dean, MarkM, please explain further if  
this is too condensed.

I also have to say that the idea isn't looking as good as it was  
before I wrote this message.



The original context is that E-on-CL reifies the surface E language  
(including all the syntax which expands to simpler Kernel-E), and  
this seemed difficult to do for E-on-Java. [out-of-order quoting]

http://www.eros-os.org/pipermail/e-lang/2006-July/011415.html :
> In E-on-Java or E-on-Squeak, this would require 65 class  
> definitions, which at least seem much heavier than 65 BNF  
> productions and expansion rules.
...
> Perhaps a more S-expression-ish representation, such as a term-
> tree, would be more  appropriate for this use?

I had been working on a modification of E-on-CL to use term trees for  
E source; there were several problems about how to provide the  
operations currently available on ENodes when the nodes were instead  
generic Terms.

While we were discussing the details of this, Dean brought up the  
fact that working with Terms was often messy.

One reason is that there are necessarily Term versions of lists and  
literal values.

? term`[1, 2, 3]` == [1, 2, 3]
# value: false

? term`[1, 2, 3]`.getArgs()
# value: [term`1`, term`2`, term`3`]

? term`[${"a"}, ${'b'}, ${3}]`
# value: term`[a, 'b', 3]`
(notice that a becomes a tag rather than string data)

The reason for this separation is so that the arguments (children) of  
terms all implement the term protocol (and so can be asked for their  
own tag, data, children, and so on).


Dean proposed that, instead, any object be viewable as a term.

term`[1, 2, 3]` would then be the term-view of an ordinary ConstList  
of integers.

Typically, the maker of an object would be its tag/functor, and its  
uncall components, or something similar, would be its arguments.

For any object, you can get its term-view with a function, say  
'termOf'. This does not provide any additional access to the object;  
it merely lets you look at an object graph in a more abstract or data- 
structure-like manner. termOf provides a permeable, protocol- 
converting membrane.

Today's term`foo(bar)` would construct 'generic objects' that have no  
special behavior but store the term arguments.

Most of the tree manipulation done on ENodes would now be done  
through the term view.


Why do this?

   - It allows a view of objects which is more generically manipulable.

   - It eliminates the term object model as a separate thing, so one  
does not have to choose either term`foo(bar(1))` or makeFoo(makeBar(1)).

   - You can use term-style operations (pattern matching, recursive  
traversal, any libraries that operate on terms etc.) on any object.

    - Currently duplicated implementation of various operations on  
ENodes and terms would become the same code.



Questions/complications:

   - Is this really as broadly useful as we thought at the moment, to  
justify the reduction in local simplicity of the term subsystem?

   - How do quasipatterns -- term`foo(@bar)` -- decide what foo  
stands for? Will it default to generic-term-objects, so that you have  
to define a different quasiparser for using with ENodes or whatever?

   - What is an AstroTag (term.getTag()) in this world?

   - Will application-specific term views be wanted, where the object  
itself does not determine its term form?

   - What happens to the SourceSpans attached to current terms?

   - Is it really possible to have a reasonable default for an  
object's term view?

-- 
Kevin Reid                            <http://homepage.mac.com/kpreid/>




More information about the e-lang mailing list