[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] Binding identifiers with set!
From: |
Bruce Hoult |
Subject: |
Re: [Chicken-users] Binding identifiers with set! |
Date: |
14 Oct 2003 15:15:53 +1300 |
On Tue, 2003-10-14 at 12:53, felix wrote:
> On 14 Oct 2003 12:08:01 +1300, Bruce Hoult <address@hidden> wrote:
>
> >
> > I think that would be immensely better than the current behaviour, but
> > not ideal. Consider something like:
> >
> > (let ((l '((a . 1) (b . 2) (c . 3) (d . 4))))
> > (define elt (caddr l))
> > (define key (car elt))
> > (define val (cdr elt))
> > (print "key=" key " val=" val))
> >
> >
> > => key=c val=3
> >
> >
> > At the moment this works, albeit by polluting the global namespace.
>
> Actually this expands into:
>
> (let ((l0 '((a . 1) (b . 2) (c . 3) (d . 4))))
> (let ((elt1 (##core#undefined))
> (key2 (##core#undefined))
> (val3 (##core#undefined)))
> (let ((t4 (set! elt1 (caddr l0))))
> (let ((t5 (set! key2 (car elt1))))
> (let ((t6 (set! val3 (cdr elt1))))
> (print '"key=" key2 '" val=" val3))))))
>
Sorry, change my example to include some random thing after the let:
(let ((l '((a . 1) (b . 2) (c . 3) (d . 4))))
(print "got here!")
(define elt (caddr l))
(define key (car elt))
(define val (cdr elt))
(print "key=" key " val=" val))
At the moment this creates/modifies three global variables.
So under your proposed change I expect it would be:
(let ((l0 '((a . 1) (b . 2) (c . 3) (d . 4))))
(print "got here!")
(let ((elt1 (##core#undefined))
(key2 (##core#undefined))
(val3 (##core#undefined)))
(let ((t4 (set! elt1 (caddr l0))))
(let ((t5 (set! key2 (car elt1))))
(let ((t6 (set! val3 (cdr elt1))))
(print '"key=" key2 '" val=" val3))))))
I guess that seems pretty good to me. It's not *quite* as efficient as
perhaps possible, but does have useful semantics if you guarantee and
document the evaluation order. And it retains letrec's virtue of
allowing the declaration of mutually-recursive functions. Or
self-recursive ones, if you make even a single internal "define" create
the binding and then set! it.
Of course it depends on the user not giving the -strict-letrec flag!
Perhaps your creative implementation of letrec should be documented
under deviations (enhancements?) from the standard, and not just under
the chicken/csc/csi flags? I guess it's a compatible enhancement. R5RS
says "[in a letrec] it must be possible to evaluate each <init> without
assigning or referring to the value of any <variable>. If this
restriction is violated then it is an error." That means Chicken can
implement it any way that it wants -- can e.g. define and document the
evaluation order -- but *programs* that depend on it are non-portable.
It is compatible because strict R5RS code will still work fine.
I vote for this plan.
--
Bruce Hoult <address@hidden>
Re: [Chicken-users] Binding identifiers with set!, felix, 2003/10/13