[e-lang] Announcing E-on-Common-Lisp (was Re: Is send DeepFrozen?)

Kevin Reid kpreid at attglobal.net
Sun Dec 12 15:48:53 EST 2004


On Dec 12, 2004, at 14:36, Dean Tribble wrote:
>
>> So far I have implemented almost the entire Kernel-E language (except 
>> for escape-catch and meta.getState()) via translation to CL, and 
>> enough of ELib to run interesting code (though no IO as yet).
>
> There were two drivers led to using Squeak as my target (first for 
> Joule and now E), and I'm wondering how you address them:  "big 
> integers" and "everything is an object".  These were already 
> properties of Smalltalk, so I get them almost for free.
> Big integers: Smalltalk directly implements arbitrarily large 
> integers.  Common Lisp may as well, but that leads to the second issue
>
> Everything is an object: Since any particular argument might be an 
> integer (arbitrary precision) or might be an object of some flavor 
> (e.g., user-defined integer, Promise, remote reference), it would seem 
> you need to implement type tests all over the place.  In particular, 
> integers are not polymorphic with closures (which are presumably used 
> for objects?) and so message sending needs to check whether it is to a 
> primitive integer.  How do you handle that?  (e.g., are integers 
> boxed?)

Common Lisp does have an "everything is a value/reference/object" model 
(everything is of (a subtype of) type T), including for large and small 
integers. There is no visible (un)boxing.

However, it has no single-dispatch message system. I implement this 
myself (as does E-on-Java), with a CLOS generic function:

   (defgeneric e-call-dispatch (receiver mverb &rest args))

For objects which are either of standard CL types (integers, floats, 
vectors, etc.) I have a mechanism for defining the methods for that 
type, again using CLOS dispatch.

For objects implemented in the E language, as well as ones which are 
part of my implementation and are most readily implemented this way, I 
define them as closures.

   (defmethod e-call-dispatch ((recip function) mverb &rest args)
     (apply recip mverb args))

For example, the primitive __loop object is defined by:

(e-named-lambda "org.erights.e.elang.interp.Loop"
   :stamped +deep-frozen-stamp+
   (:|__printOn/1| (tw)
     (e-coercef tw +the-text-writer-guard+)
     (e. tw |print| "<__loop>")
     nil)
   (:|run/1| (body)
     (loop until (not (e-is-true (e. body |run|))))))

The e-named-lambda macro expands to, in part:

   (lambda (mverb &rest args)
     (case mverb
       ((:|__printOn/1|)
         (destructuring-bind (tw) args
           (setf tw (e-coerce tw +the-text-writer-guard+))
           (e-call-dispatch tw :|print/1| "<__loop>")
           nil))
       ((:|run/1|)
         (destructuring-bind (body) args
           (loop until (not (e-is-true (e-call-dispatch body 
:|run/0|))))))))

I have omitted the details related to auditing and miranda methods.

Later I may add optimizations to translation to directly call 
function-e-objects when they are known to be such.

(Not quite) the Common Lisp specification:

   http://www.lispworks.com/reference/HyperSpec/Front/index.htm

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



More information about the e-lang mailing list