For Programmers: Free Programming Magazines  


Home > Archive > Scheme > March 2008 > Partial evaluation of quoted expression (Scheme48)









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Partial evaluation of quoted expression (Scheme48)
Olof Frahm

2008-03-13, 10:23 pm

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

I want to store the implementation of a function/method in a object
(in a simple object system, prometheus) to be able to save the
definition of that object later on. It's not nearly perfect, but a idea
that works for me ...
Saving works by using a macro that stores the complete s-expression
inside the object and secondly, evaluates the expression.

So, the problem that I encountered was, that in a function:
> (lambda (self resend) x)

if the object is inspected some hours later, it is almost never the
case, that x is the same thing as when the function was defined.
Especially if it was a temporary variable.

To solve this I've got two ideas:
1. a reader macro, which overrides the macro-effect and simply evaluates
all occurences of the token (here it's #^) in the current environment [1]
> '(lambda (self resend) #^x) -> '(lambda (self resend) #{Object})


2. a function which is used inside the macro, "partial-evaluate", which
goes through all elements of the expression and evaluates all
quotation expressions '(quasiquote (unquote foo)) [2]
> '(lambda (self resend) `,x) -> '(lambda (self resend) #{Object})


Both options work with a warning:
> Warning: invalid datum in quotation


So ... does this make any sense? I hope it's not completely over-
engineered though.

Thanks for reading, maybe you can drop a thought ;)
Olof

[1]
> (define-sharp-macro #\^
> (lambda (c port)
> (read-char port)
> (eval (read port) (interaction-environment))))


[2]
> (define (partial-evaluate xs)
> (letrec ((func
> (lambda (arg rest)
> (if (pair? arg)
> (if (eq? (car arg) 'quasiquote)
> (cons (eval (cadadr arg) (interaction-environment)) rest)
> (cons (fold-right func '() arg) rest))
> (cons arg rest)))))
> (fold-right func '() xs)))


[3] The macro is written in a defmacro-style; this part is returned to
be evaluated:
> ...
> `(begin
> (,object 'add-implementation! '(,name ,(partial-evaluate arg)))
> (,object 'add-method-slot! ',name ,arg))
> ...


[] Usage like this [2]:
> (object-add-method-slot! object foo (lambda (self resend) `,x))

or this [1]:
> (object-add-method-slot! object foo (lambda (self resend) #^x))

Objects are used like this:
> (object 'foo arguments ...)


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.8 (GNU/Linux)

iEYEARECAAYFAkfZ3nEACgkQEiTh585nXwC8pACe
JiTbjUaW6zB3RIAItVvoPClv
v/gAnAijAbShLUd0KvWqhcmRDIfGKfDU
=XQft
-----END PGP SIGNATURE-----
oleg@pobox.com

2008-03-14, 4:50 am

On Mar 13, 7:23=A0pm, Olof Frahm <olof.fr...@web.de> wrote:
[color=darkred]
> Both options work with a warning:

Indeed, suppose x is bound to a closure. According to R5RS, the
argument of a quotation is an _external_ representation of a Scheme
datum. Closures, for example, are not guaranteed to have an external
representation.

Please see the explanation in the title comments of
http://okmij.org/ftp/Computation/st...meta-scheme.scm

starting with the phrase `Another interesting question is the
cross-stage facility'. The implementation (which tested in Scheme48 as
well as Petite Chez and SCM) follows the line marked '; Implementing
CSP' near the end of the code.

Pascal J. Bourguignon

2008-03-14, 8:19 am

Olof Frahm <olof.frahm@web.de> writes:

> Hello,
>
> I want to store the implementation of a function/method in a object
> (in a simple object system, prometheus) to be able to save the
> definition of that object later on. It's not nearly perfect, but a idea
> that works for me ...
> Saving works by using a macro that stores the complete s-expression
> inside the object and secondly, evaluates the expression.
>
> So, the problem that I encountered was, that in a function:
> if the object is inspected some hours later, it is almost never the
> case, that x is the same thing as when the function was defined.
> Especially if it was a temporary variable.
>
> To solve this I've got two ideas:
> 1. a reader macro, which overrides the macro-effect and simply evaluates
> all occurences of the token (here it's #^) in the current environment [1]
>
> 2. a function which is used inside the macro, "partial-evaluate", which
> goes through all elements of the expression and evaluates all
> quotation expressions '(quasiquote (unquote foo)) [2]
>
> Both options work with a warning:
>
> So ... does this make any sense? I hope it's not completely over-
> engineered though.
>
> Thanks for reading, maybe you can drop a thought ;)


As mentionned by Oleg, what you have here is to deal with closures.
This is rather hairy.

For example, you could have:

(define items-to-save
(let ((x 1))
(list (lambda (self resend) x)
(lambda (self resend arg) (set! x arg)))))

Now, you want both items in items-to-save to refer the same x when you
load them back.


On the other hand, with:

(define items-to-save
(list (let ((x 1)) (lambda (self resend) x))
(let ((x 1)) (lambda (self resend arg) (set! x arg)))))

you don't want them to share a x when you restore them.

So your macro can't rely only on the name 'x, but also on it's
meaning, that is to what it refers in the environment where the
closure is defined.


So you will have either to rely on implementation specific stuff (to
access the environments from your macros), or restrict the way you can
build these closures (encapsulate everything in your own macro that
will in effect realize a new implementation).


Your option 1. is most probably NOT what is wanted.

(define x 1)
(save 'example (lambda (self resend) x))
(set! x 2)
((load 'example)) --> we expect to get 2, don't we?


--
__Pascal Bourguignon__
Olof Frahm

2008-03-14, 10:44 pm

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Your option 1. is most probably NOT what is wanted.
>
> (define x 1)
> (save 'example (lambda (self resend) x))
> (set! x 2)
> ((load 'example)) --> we expect to get 2, don't we?

Uhm, well yes, I'm not yet quite sure what it should behavelike ;-)

Maybe I'll just see what this implementation got for dealing with
environments, eventually restricting the implementation of this objects
is also a good idea ... maybe it'll work better for me than a general
solution.

Thanks a lot both of you, that gained me some insight.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.8 (GNU/Linux)

iEYEARECAAYFAkfakWkACgkQEiTh585nXwAY3gCf
fV1M+PKNz/xvLLIqFpFGHrEv
25YAmQG+KrNF7fKU/FzbTjNgHYOVafEy
=jTKZ
-----END PGP SIGNATURE-----
Pascal J. Bourguignon

2008-03-14, 10:44 pm

Olof Frahm <olof.frahm@web.de> writes:

> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Uhm, well yes, I'm not yet quite sure what it should behavelike ;-)
>
> Maybe I'll just see what this implementation got for dealing with
> environments, eventually restricting the implementation of this objects
> is also a good idea ... maybe it'll work better for me than a general
> solution.
>
> Thanks a lot both of you, that gained me some insight.


What you could do rather easily, is to walk the lambda forms for free
variables and signal an error if there is one.

I guess that for stored procedures, it wouldn't be too restrictive to
reject closures.


Note that closures are equivalent to Objects. If you are
implementing¹ Objects with closures, in a way, this is circular
thinking, so you're bound to have problems. But when you want to
implement Objects = closures over a database (be it simple files), you
need to store lower-level lisp objects, simplier lisp objects,
therefore closures should be discarded.





¹ I'm not saying if you're just adding syntactic sugar (eg. macros)
over closures to have nice objects. There's no problem with that.

--
__Pascal Bourguignon__
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com