From: Steve Long
Subject: Objects with Lazy Evaluation Slot Values
Date: 
Message-ID: <BA4B922F.2553%sal6741@hotmail.com>
The Lisp-based ICAD product uses a multi-inheritance data structure
(flavors) with slots having "delayed" evaluation (the values are
"unevaluated" until demanded, and computed by means of methods keyed on that
data structure type.) Modifying a value in a tree of instances requires
re-evaluation of only the evaluated slots beginning at the tree root. This
is very useful behavior, especially when dealing with the computation of
geometric attributes of curves, surfaces, and other complex entities that
should only be computed once or only when required.

Have any of you ever implemented this kind of behavior any other languages
(Java, C++, Python, VB), especially ones in which class instances
automatically evaluate their slot values at instantiation? I may need to
re-implement some of my applications in a non-Lisp enviro, so I'm watching
out for potential potholes.

s long

From: Hannah Schroeter
Subject: Re: Objects with Lazy Evaluation Slot Values
Date: 
Message-ID: <b0hgbj$thp$1@c3po.schlund.de>
Hello!

Steve Long  <·······@hotmail.com> wrote:
>The Lisp-based ICAD product uses a multi-inheritance data structure
>(flavors) with slots having "delayed" evaluation (the values are
>"unevaluated" until demanded, and computed by means of methods keyed on that
>data structure type.) Modifying a value in a tree of instances requires
>re-evaluation of only the evaluated slots beginning at the tree root. This
>is very useful behavior, especially when dealing with the computation of
>geometric attributes of curves, surfaces, and other complex entities that
>should only be computed once or only when required.

>Have any of you ever implemented this kind of behavior any other languages
>(Java, C++, Python, VB), especially ones in which class instances
>automatically evaluate their slot values at instantiation? I may need to
>re-implement some of my applications in a non-Lisp enviro, so I'm watching
>out for potential potholes.

I haven't. But delayed evaluation is simple to do in Common Lisp
(which doesn't provide it out of the box).

(defun lazy-implementation (lambda-with-no-parameters)
  (cons :deferred lambda-with-no-parameters))

(defun force (deferred-value)
  (ecase (car deferred-value)
    (:deferred
      (let ((value (funcall (cdr deferred-value))))
        (setf (cdr deferred-value) value)
        (setf (car deferred-value) :already-evaluated)
        value))
    (:already-evaluated (cdr deferred-value))))

(defmacro lazy (&rest expressions)
  `(lambda () (progn ,@expressions)))

You can do similar things in Python, using their lambda expressions,
you just don't get the syntactic sugar feature of the (defmacro lazy ...).
Use some Deferred class instead of the cons cell I used in the Lisp
example.

In Java, you can do similar things with anonymous inner classes implementing
an interface
	interface Deferred {
		public Object value();
	}	// modulo some surface syntax, I don't do Java usually
Use a Deferred class with a public Object force() method instead of
the Lisp cons cell.

In C++, you could do scary things with function objects and templates.

Now, to do deferred slots (members/fields/...), you have to put
Deferred objects there and manually use accessors that
	return (slotFoo.force());

Kind regards,

Hannah.
From: Steve Long
Subject: Re: Objects with Lazy Evaluation Slot Values
Date: 
Message-ID: <BA54A961.26A1%sal6741@hotmail.com>
On 1/20/03 10:49 AM, in article ············@c3po.schlund.de, "Hannah
Schroeter" <······@schlund.de> wrote:

> Hello!
> 
> Steve Long  <·······@hotmail.com> wrote:
>> The Lisp-based ICAD product uses a multi-inheritance data structure
>> (flavors) with slots having "delayed" evaluation (the values are
>> "unevaluated" until demanded, and computed by means of methods keyed on that
>> data structure type.) Modifying a value in a tree of instances requires
>> re-evaluation of only the evaluated slots beginning at the tree root. This
>> is very useful behavior, especially when dealing with the computation of
>> geometric attributes of curves, surfaces, and other complex entities that
>> should only be computed once or only when required.
> 
>> Have any of you ever implemented this kind of behavior any other languages
>> (Java, C++, Python, VB), especially ones in which class instances
>> automatically evaluate their slot values at instantiation? I may need to
>> re-implement some of my applications in a non-Lisp enviro, so I'm watching
>> out for potential potholes.
> 
> I haven't. But delayed evaluation is simple to do in Common Lisp
> (which doesn't provide it out of the box).
> 
> (defun lazy-implementation (lambda-with-no-parameters)
> (cons :deferred lambda-with-no-parameters))
> 
> (defun force (deferred-value)
> (ecase (car deferred-value)
>   (:deferred
>     (let ((value (funcall (cdr deferred-value))))
>       (setf (cdr deferred-value) value)
>       (setf (car deferred-value) :already-evaluated)
>       value))
>   (:already-evaluated (cdr deferred-value))))
> 
> (defmacro lazy (&rest expressions)
> `(lambda () (progn ,@expressions)))
> 
> You can do similar things in Python, using their lambda expressions,
> you just don't get the syntactic sugar feature of the (defmacro lazy ...).
> Use some Deferred class instead of the cons cell I used in the Lisp
> example.
> 
> In Java, you can do similar things with anonymous inner classes implementing
> an interface
> interface Deferred {
> public Object value();
> }    // modulo some surface syntax, I don't do Java usually
> Use a Deferred class with a public Object force() method instead of
> the Lisp cons cell.
> 
> In C++, you could do scary things with function objects and templates.
> 
> Now, to do deferred slots (members/fields/...), you have to put
> Deferred objects there and manually use accessors that
> return (slotFoo.force());
> 
> Kind regards,
> 
> Hannah.

Thanks for the advice. I've implemented lazy-eval in MCL in a way that
mimmicks the ICAD defpart syntax.

sl