From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Noah Lavine Newsgroups: gmane.lisp.guile.devel Subject: Re: Special variables to relax boxing Date: Thu, 21 Mar 2013 17:11:21 -0400 Message-ID: References: <3101921.Ei70kTLzB2@warperdoze> <87d2usa845.fsf@tines.lan> <12515493.61rmnodEK6@warperdoze> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=bcaec520f083097d4c04d875c93f X-Trace: ger.gmane.org 1363900316 9093 80.91.229.3 (21 Mar 2013 21:11:56 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 21 Mar 2013 21:11:56 +0000 (UTC) Cc: Mark H Weaver , guile-devel To: Stefan Israelsson Tampe Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Thu Mar 21 22:12:22 2013 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UImmb-0000fK-03 for guile-devel@m.gmane.org; Thu, 21 Mar 2013 22:12:21 +0100 Original-Received: from localhost ([::1]:33349 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UImmD-0002Qz-JO for guile-devel@m.gmane.org; Thu, 21 Mar 2013 17:11:57 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:51165) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UImm5-0002Kk-8d for guile-devel@gnu.org; Thu, 21 Mar 2013 17:11:54 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UImm0-0001PG-1O for guile-devel@gnu.org; Thu, 21 Mar 2013 17:11:49 -0400 Original-Received: from mail-da0-x22e.google.com ([2607:f8b0:400e:c00::22e]:49190) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UImlz-0001P5-O7 for guile-devel@gnu.org; Thu, 21 Mar 2013 17:11:43 -0400 Original-Received: by mail-da0-f46.google.com with SMTP id y19so1844644dan.5 for ; Thu, 21 Mar 2013 14:11:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:mime-version:sender:in-reply-to:references:from:date :x-google-sender-auth:message-id:subject:to:cc:content-type; bh=YL6HaNKvXatTy77djaNk5ChQUGPstoY7RLzcZmt5ps0=; b=H3J8OnAgwRRs+b/GKzEz0Q2agXKm3WoawOJSCpXwEsibCmlHNJIKyBs8sNcuXnZ4I4 yCWOkT61oQEkVuuv282UZBcu22bxBHoN11ZNpQIQERYAsDfmgKvdIikzattZnBm45yhF pB3Eg8l+QEqJNIyruF1Aw6RtqrpBymouuN6J+Hmt1V2JxAATQgKLKr1vkn7s6yZvtf81 eaa5PTHOvaEMf4FZbWQHFIZ87S4Ah95IZ3N0V0q5Xu34Ic5ELIA9zFSIAd6euZ1EnyW9 B3SiBx0UFusZ1bfOH4xTZl/idgzpGi6fJ6lWP9rnSPi0jZAJc9j+mN1kDk94AgDgRLs5 GYyw== X-Received: by 10.68.14.165 with SMTP id q5mr16688448pbc.125.1363900302455; Thu, 21 Mar 2013 14:11:42 -0700 (PDT) Original-Received: by 10.68.157.42 with HTTP; Thu, 21 Mar 2013 14:11:21 -0700 (PDT) In-Reply-To: <12515493.61rmnodEK6@warperdoze> X-Google-Sender-Auth: p-Do_enffsv4caO-al5bwBJHIjI X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400e:c00::22e X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:15963 Archived-At: --bcaec520f083097d4c04d875c93f Content-Type: text/plain; charset=ISO-8859-1 Hi, Stefan and Mark, I think you are talking past each other. Stefan is offering a very concrete definition of what he wants, and Mark is looking for a more abstract version. Here is what I think Stefan wants, in the language of R5RS' storage model: A variable is simply a name for a particular location, and each variable refers to its own unique location. When a continuation is captured, that continuation gets its own set of "mirror" locations, one for each variable that is in the scope of the continuation. These "mirror" locations are initialized with the same values that were in the locations of the corresponding variables, but they are distinct from those locations and are immutable. When a continuation is called, it is run in an environment in which each of the variables that was in scope when it was captured points to a new location, which is initialized to have the same value as the corresponding "mirror" location. Note that each variable name gets at least three distinct locations in this description: the original location, when the program was being run, the "mirror" location, when the continuation was captured, and the new location, when the continuation was called. I believe this is sufficient (and necessary?) to give the semantics that Stefan wants. Let me also give a more concrete example, which I believe captures *why* this is important. Let's say you're writing a loop with a counter that says when to terminate: (let ((count 0)) (let iter () ... do-some-stuff ... (when (< count 1000000) (set! count (+ count 1)) (iter)))) Now pretend that do-some-stuff captures its continuation when count is equal to 10. Stefan wants a situation where, no matter how many times that continuation is called, *each call* to the continuation will have (= count 10). I think this is very natural if you're using an imperative style, but I'm not sure what the best way is to achieve it. Best, Noah On Thu, Mar 21, 2013 at 4:15 PM, Stefan Israelsson Tampe < stefan.itampe@gmail.com> wrote: > On Thursday, March 21, 2013 03:03:06 PM Mark H Weaver wrote: > > Stefan, you're still describing your proposal in terms of low-level > > implementation details such as stacks. In the general case, we cannot > > store environment structures on the stack. Furthermore, in the > > general case *all* variables in scheme are bound to locations, not > > values. Only in special cases can we use stacks, and only in special > > cases can we avoid boxing variables. These are only _optimizations_. > > > > If you're serious about this proposal, please read sections 3.1 and > > 3.4 of the R5RS carefully. Explain your proposed _semantics_ (not > > the implementation details) in those terms, where *all* variables are > > bound to _locations_, and where there is no stack at all (everything > > is conceptually stored in a garbage-collected heap). > > > > We need to understand the *semantics* in the simplest possible terms > > before we even begin to think about how to implement it. > > > > Thanks, > > Mark > > Ok, the sematics for the simple version is are, > > Assume k, the continuation associated with with a dynamic wind or > unwind assume that there is a map from each continuation (k,id) > to a value and getting and setting of this value is done through > ref-get and ref-set, assume that the winder and the rewinder lambda > takes a first argument k beeing the continuation under action, finally > make-id will make a unique object. then the semantic would be: > > (define-syntax-rule (with-special (a) code) > (let ((id (make-id))) > (dynamic-wind > (lambda (k) (set! a (ref-get k id))) > (lambda () code) > (lambda (k) (ref-set! k id a))))) > > A possible refinment of this is > associate to k two predicates e.g. > (do-wind? k kind) predicate and a (do-unwind? k kind) wich takes > a parameter kind, then use the semanics > > (define-syntax-rule (with-special (a kind) code) > (let ((id (make-id))) > (dynamic-wind > (lambda (k) > (when (do-wind? k kind) > (set! a (ref-get k id)))) > (lambda () code) > (lambda (k) > (when (do-unwind? k kind) > (ref-set! k id a)))))) > > Hopes this helps! > > /Stefan > > > --bcaec520f083097d4c04d875c93f Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Hi,

Stefan and Mark, I think you ar= e talking past each other. Stefan is offering a very concrete definition of= what he wants, and Mark is looking for a more abstract version. Here is wh= at I think Stefan wants, in the language of R5RS' storage model:

A variable is simply a name for a particular location, and e= ach variable refers to its own unique location. When a continuation is capt= ured, that continuation gets its own set of "mirror" locations, o= ne for each variable that is in the scope of the continuation. These "= mirror" locations are initialized with the same values that were in th= e locations of the corresponding variables, but they are distinct from thos= e locations and are immutable.

When a continuation is called, it is run in an environment i= n which each of the variables that was in scope when it was captured points= to a new location, which is initialized to have the same value as the corr= esponding "mirror" location.

Note that each variable name gets at least three distinct lo= cations in this description: the original location, when the program was be= ing run, the "mirror" location, when the continuation was capture= d, and the new location, when the continuation was called. I believe this i= s sufficient (and necessary?) to give the semantics that Stefan wants.

Let me also give a more concrete example, which I believe ca= ptures *why* this is important. Let's say you're writing a loop wit= h a counter that says when to terminate:

(let ((count 0))=
=A0 (let iter ()
=A0=A0=A0 ... do-some-stuff ...
=A0=A0=A0 (when (< count 1000000)
=A0=A0=A0= =A0=A0 (set! count (+ count 1))
=A0=A0=A0=A0=A0 (iter))))
=
Now pretend that do-some-stuff captures its continuation whe= n count is equal to 10. Stefan wants a situation where, no matter how many = times that continuation is called, *each call* to the continuation will hav= e (=3D count 10). I think this is very natural if you're using an imper= ative style, but I'm not sure what the best way is to achieve it.

Best,
Noah

=
On Thu, Mar 21, 2013 at 4:15 PM, Stefan Isra= elsson Tampe <stefan.itampe@gmail.com> wrote:
On T= hursday, March 21, 2013 03:03:06 PM Mark H Weaver wrote:
> Stefan, you're still describing your proposal in terms of low-leve= l
> implementation details such as stacks. =A0In the general case, we cann= ot
> store environment structures on the stack. =A0Furthermore, in the
> general case *all* variables in scheme are bound to locations, not
> values. =A0Only in special cases can we use stacks, and only in specia= l
> cases can we avoid boxing variables. =A0These are only _optimizations_= .
>
> If you're serious about this proposal, please read sections 3.1 an= d
> 3.4 of the R5RS carefully. =A0Explain your proposed _semantics_ (not > the implementation details) in those terms, where *all* variables are<= br> > bound to _locations_, and where there is no stack at all (everything > is conceptually stored in a garbage-collected heap).
>
> We need to understand the *semantics* in the simplest possible terms > before we even begin to think about how to implement it.
>
> =A0 =A0 Thanks,
> =A0 =A0 =A0 Mark

Ok, the sematics for the simple version is are,

Assume k, the continuation associated with with a dynamic wind or
unwind assume that there is a map from each continuation (k,id)
to a value and getting and setting of this value is done through
ref-get and ref-set, assume that the winder and the rewinder lambda
takes a first argument k beeing the continuation under action, finally
make-id will make a unique object. then the semantic would be:

(define-syntax-rule (with-special (a) code)
=A0 (let ((id (make-id)))
=A0 =A0 (dynamic-wind
=A0 =A0 =A0 =A0(lambda (k) (set! a (ref-get k id)))
=A0 =A0 =A0 =A0(lambda () code)
=A0 =A0 =A0 =A0(lambda (k) =A0(ref-set! k id a)))))

A possible refinment of this is
associate to k two predicates e.g.
=A0(do-wind? k kind) predicate and a (do-unwind? k kind) wich takes
a parameter kind, then use the semanics

(define-syntax-rule (with-special (a kind) code)
=A0 (let ((id (make-id)))
=A0 =A0 (dynamic-wind
=A0 =A0 =A0 =A0(lambda (k)
=A0 =A0 =A0 =A0 =A0(when (do-wind? k kind)
=A0 =A0 =A0 =A0 =A0 =A0(set! a (ref-get k id))))
=A0 =A0 =A0 =A0(lambda () code)
=A0 =A0 =A0 =A0(lambda (k)
=A0 =A0 =A0 =A0 =A0(when (do-unwind? k kind)
=A0 =A0 =A0 =A0 =A0 =A0(ref-set! k id a))))))

Hopes this helps!

/Stefan



--bcaec520f083097d4c04d875c93f--