guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: set! semantics


From: Stefan Israelsson Tampe
Subject: Re: set! semantics
Date: Sun, 17 Mar 2013 16:11:08 +0100
User-agent: KMail/4.9.5 (Linux/3.5.0-25-generic; KDE/4.9.5; x86_64; ; )

On Sunday, March 17, 2013 09:36:29 AM Noah Lavine wrote:
> Hello,
> 
> I believe that keeping the box identity but not the box value is the
> correct behavior of continuations under the Scheme standard. I agree
> it's not intuitive, though.
> 
> I have been thinking that we could eliminate variable boxes for
> mutable variables when we can prove that the continuation is never
> captured. I need to understand more about how continuations work, but
> I don't think we need a new variable type for efficiency reasons.
> 
> If you want a new type of variable because you want different
> semantics, that's a different issue. Could you give more of an
> example? I assume that you're talking about something like this:
> 
> (loop ;; the macro defines a loop counter
>   (call/cc some-other-function))
> 
> So when the continuation of the loop is called more than once, the
> loop counter is incremented too much. Is that right?
> 
> Best,
> Noah
> 
> 
> On Sun, Mar 17, 2013 at 9:07 AM, Stefan Israelsson Tampe <
> 
> address@hidden> wrote:
> > Dear all,
> > 
> > I just noted an issue with a programming style, that I suspect
> > schemers try to avoid but still is quite common in the lisp
> > community
> > and actually makes for simpler macros when e.g. writing loop macros.
> > 
> > The issue here is that one setup local variables with a let and then
> > modify them using set!.
> > 
> > The problem is that this code will always be boxed. Now the overhead
> > of this is almost invisible due to other overhead. What I ask is
> > what
> > happens when we store the stack at a call/cc setup? What will happen
> > is that the box identity is stored but not the box value and hence
> > there will be problems with recurrent calls of a continuation.
> > 
> > Now I could be pretty fine with this because it's a clean statement
> > to say that this behavior is included in the set! semantic. And we
> > actually need keep this semantic to not break backward compability.
> > 
> > Anyway. It's still pretty useful to have a local-set that will only
> > set a variable if it safely can set the local variable on the stack
> > directly I therefore propse for guile to include a new variable
> > binding construct called local-set! personally I would in most cases
> > avoid it's use but I would love to have it in my loop macros.
> > 
> > WDYT
> > /Stefan

I did a test here with,
(define k #f)
(define (f n)
  (call-with-prompt 'a
    (lambda () 
      (let ((s 0)
            (i 0))
        (let loop ()
          (set! s (+ s i))
          (set! i (+ i 1))
          (case i
            ((20 50) (abort-to-prompt 'a s)))
          (if (= i 100)
              'ok
              (loop)))))
      (lambda (_k v)
        (set! k _k)
        v)))

(pk (f 1))
(pk (call-with-prompt 'a k (lambda (k x) x)))
(pk (call-with-prompt 'a k (lambda (k x) x)))

which outputs
;;; (190)

;;; (1225)

;;; (ok)


And what you write is inded what is implemented. I think this is ok!
what I wan't is an ideom, local-set! that only set the variable local
to the function, and errors out if it tries to local-set! a variable
ouside of the functions scope, e.g.

(let ((a 1))
     (lambda () (local-set! a 2)))

Should fail to compile if the lambda is needed for the final
output.

This does have the drawback that we cannot push the values down the
stack for lambdas, remains to design dynamic wind like

(let ((i 0))
  (dynamic-wind-x
    (lambda (w) (set! i (car w)))
    (lambda () code ...)
    (lambda x 
      (dynwind-store (list i)))))
          
And then let the optimizations, when possible, inline things in a nice
form

/Stefan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]