From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Israelsson Tampe Newsgroups: gmane.lisp.guile.devel Subject: Re: Special variables to relax boxing Date: Sat, 23 Mar 2013 16:34:03 +0100 Message-ID: References: <3101921.Ei70kTLzB2@warperdoze> <87wqt19ts2.fsf@tines.lan> <87d2usa845.fsf@tines.lan> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 X-Trace: ger.gmane.org 1364052852 17422 80.91.229.3 (23 Mar 2013 15:34:12 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 23 Mar 2013 15:34:12 +0000 (UTC) Cc: guile-devel To: Mark H Weaver Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Mar 23 16:34:38 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 1UJQSq-0000Pq-0P for guile-devel@m.gmane.org; Sat, 23 Mar 2013 16:34:36 +0100 Original-Received: from localhost ([::1]:46960 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UJQSS-000185-FX for guile-devel@m.gmane.org; Sat, 23 Mar 2013 11:34:12 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:44609) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UJQSM-00015M-BA for guile-devel@gnu.org; Sat, 23 Mar 2013 11:34:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UJQSK-0002gP-Ri for guile-devel@gnu.org; Sat, 23 Mar 2013 11:34:06 -0400 Original-Received: from mail-da0-x22c.google.com ([2607:f8b0:400e:c00::22c]:57606) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UJQSK-0002gD-Im for guile-devel@gnu.org; Sat, 23 Mar 2013 11:34:04 -0400 Original-Received: by mail-da0-f44.google.com with SMTP id z20so2642504dae.31 for ; Sat, 23 Mar 2013 08:34:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:x-received:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; bh=3b8sXn93w/UnTb9dNIQoXeJFRGv39lsP3vHSpc3h8ro=; b=G0Rjf5WVnnTk3OMruZ5vXkR4o2e/RywWvSzylDV6hDBGLvNtWAzjYMLILo18OTGC2Y w3dZu+f892/tAQjdzueHpQOICpt1eU0K4+Tgt/YXFcioRqLT89kPXV1W6pJMVMyoZoRc ug6QC2XZ5UqETqolTycpm+hIiwCrHWy1nxFSqvL+4qdQVuzN23RQIEzTL6MddJlHkoVb V1FN5JqJdYmvgDnf7/ov4alilAvkyFUuTy8FaPHUT+zSOZ9xaQo0Bmw9I+H0b53NBpvZ V5D4dQOsoJwKCjB97IGWsd8+kez2aw/vmlwg521PoO79Gh9pWnHVS0fonfesyoMvb/R3 o1VQ== X-Received: by 10.68.226.201 with SMTP id ru9mr8538469pbc.102.1364052843748; Sat, 23 Mar 2013 08:34:03 -0700 (PDT) Original-Received: by 10.70.45.8 with HTTP; Sat, 23 Mar 2013 08:34:03 -0700 (PDT) In-Reply-To: <87d2usa845.fsf@tines.lan> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400e:c00::22c 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:15981 Archived-At: Ok, I have felt your punches against the idea and have thought about it somewhat more. 1. I can only conclude that today it's already difficult to reason about code with respect to multiple restarts of continuation and the main reason is that at least I have been sloppy to add a ! to the macros that use set! internally. To a fun example: I have been pondering to poer common-lisp iterate for fun to learn and enjoy guile. In there they have generators e.g. (generati i ...) and then take out the values with (next i) construct. For a simple i = 1 ... one would expand next i to (begin (set! i (+ i 1)) i). So next is really next!. So this will not mix well with undo and redo. It's possible to define i as a special variable though and you will get the feature of proper undo redo support but now another problem appears we will as Mark and Daniel introduce i into any uses of next i in user and can get hard to reason about properties when the value is put into a lambda. So next is not next or next! but what? maybe next~ To indicate that lambdas that include this must expect to mutate when one does a redo!. Conventions like this is problematic because coders will most certainly be sloppy to follow this convention resulting in a mess. One really long for a type system to help clarify the matters here. Typically macro writers that post a binding a, might want users to use the underlying a~, variable as well and it would probably be good practice to let users refer to this at will e.g. reference it with (~ a), set it with (set~ a 1) as well as (set! a 1) and refer to it with e.g. a just as ordinary scheme. I would suggest that both reference a variable with set!,a, and with set~, (~ a) should be an error. Otherwise if the macro writer manages the macro correct and basically uses a user guard that we should provide e.g. (with-user (a) user-code ...) especially this means that if a is set! ed then we know that redo undo cannot work and we will force the underlying variable to be a usual variable. To accomplish this I would formulate the semantics as follows. Consider * k, the r5rs continuation * dynamic-wind, r5rs dynamic wind with the addition that k is an argument to the rewinder. Introduce (with-special ((a:id kind:object) ...) code ...) and (set~ a:id v:obj) Let self identifying the dynamic wind object lexically Introduce (special-set! self k value) (special-ref self k) Also define (guard-special? k kind) A setter and a getter of an object indexed by self and k Then the semantic for with-special in guard mode would be (let ((last #f)) (dynamic-wind (lambda (k) (when (guard-special? k kind) (set! a (special-ref self k)))) (lambda () (call-with-values (lambda () (begin code ...)) (lambda ret (set! last #t) (apply values ret)))) (lambda (k . l) (unless last (special-set! self k a)))) Guard mode is entered only if a is referenced with set~ and never with set! if it can be proved Otherwise guard mode is never entered. The semantics of set~ is the same as with set! otherwise. if with-special is not in guard-mode then it behaves just as (let () code ....) I really hope that I mange to converge a good concept with this discussion! WDYT On Thu, Mar 21, 2013 at 8:03 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