From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: David Kastrup Newsgroups: gmane.lisp.guile.devel Subject: Re: Anything better for delayed lexical evaluation than (lambda () ...)? Date: Tue, 13 Dec 2011 23:23:28 +0100 Message-ID: <87hb14cdr3.fsf@fencepost.gnu.org> References: <87liqtpsl9.fsf@fencepost.gnu.org> <874nxdwkbi.fsf@rapitore.luna> <87d3bvfo5d.fsf@fencepost.gnu.org> <871usaicvi.fsf@netris.org> <87mxaycmlx.fsf@fencepost.gnu.org> <87wra1hcek.fsf@netris.org> <87mxaxihnw.fsf@pobox.com> <87obvclu92.fsf@fencepost.gnu.org> <87aa6wbp0w.fsf@pobox.com> <87fwgolgm5.fsf@fencepost.gnu.org> <8762hkbkwi.fsf@pobox.com> <87borclcem.fsf@fencepost.gnu.org> <87zkewa2vy.fsf@pobox.com> <87zkewjvyz.fsf@fencepost.gnu.org> <87vcpka13n.fsf@pobox.com> <87r508jtti.fsf@fencepost.gnu.org> <87mxaw9u3b.fsf@pobox.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: dough.gmane.org 1323816343 2155 80.91.229.12 (13 Dec 2011 22:45:43 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 13 Dec 2011 22:45:43 +0000 (UTC) Cc: guile-devel@gnu.org To: Andy Wingo Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Tue Dec 13 23:45:39 2011 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Rab6R-000337-94 for guile-devel@m.gmane.org; Tue, 13 Dec 2011 23:45:39 +0100 Original-Received: from localhost ([::1]:40159 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rab6Q-00052A-RM for guile-devel@m.gmane.org; Tue, 13 Dec 2011 17:45:38 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:54356) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rab6N-00051u-Ce for guile-devel@gnu.org; Tue, 13 Dec 2011 17:45:36 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Rab6J-0003wY-Nj for guile-devel@gnu.org; Tue, 13 Dec 2011 17:45:35 -0500 Original-Received: from fencepost.gnu.org ([140.186.70.10]:55744) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rab6J-0003wU-M9 for guile-devel@gnu.org; Tue, 13 Dec 2011 17:45:31 -0500 Original-Received: from localhost ([127.0.0.1]:37432 helo=lola) by fencepost.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rab6J-0003Ro-4E; Tue, 13 Dec 2011 17:45:31 -0500 Original-Received: by lola (Postfix, from userid 1000) id 1CE91E065E; Tue, 13 Dec 2011 23:23:29 +0100 (CET) In-Reply-To: <87mxaw9u3b.fsf@pobox.com> (Andy Wingo's message of "Tue, 13 Dec 2011 19:58:48 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.10 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:13067 Archived-At: Andy Wingo writes: > On Tue 13 Dec 2011 17:54, David Kastrup writes: > >>> Am I missing something? >> >> Performance, space, simplicity, robustness. Compiling five closures >> that do nothing except accessing a single variable each is a bit >> wasteful. > > Sure. > > Let me see if I finally understand the issue here: > > You have a function: > > (define-music-function (foo bar) > (ly:something? bar) ^^^^^^^^^^^^^^^^^^^ Those are predicates, not arguments. > #{ /la /la /la > $bar $bar $bar > #(scheme-expression!) Both # and $ come before Scheme expressions. # is the regular type visible in the parser, and has, for example, the property that it will always serve as exactly one argument of a music function. $ is an "immediate" type that gets camouflaged as a Lilypond token right in the lexer. Using $ for assignments or less static cases than above is prone to surprises since the parser generally operates with one token of lookahead, and $ has to be evaluated before a token even exists. In contrast, # is read in the lexer and evaluated in the parser. So basically the Guile relevant angle of the two is identical. > /ok }#) > Before, you could turn the #{}# into a lambda No, it was turned into a reader expansion. No closure. The reader expansion had as constant contents the #{ ... #} contents as a string, and a capture of the current lexical environment. When this got executed, the parser is let loose on the #{ ... #} contents, and when encountering $ or #, it evaluates them like it would do outside of #{ ... #} except for using a local-eval in the captured environment. In either case, the Scheme reader is used for skipping over the sexp following $ and #. That is still done, but instead of throwing the read sexp away, we now put it in a lambda together with its position in the string (unless it is an obvious constant). When evaluating # or $ at runtime, we first check the alist of positions to lambdas, and if we find a record of that position, evaluate a call to the recorded lambda instead of the read expression. Of course, this is not good for producing lvalues (pardon the Cism). > and get at the $vars and evaluate the #(expressions) in the > procedure-environment of the lambda. Now, you have to munge around in > the expression and, in this case, produce 4 closures: (lambda () bar), > 3 times, and (lambda () (scheme-expression!)). > > Is that right? Yes, that's what we currently do. I don't know whether Scheme will be smart enough to use the same memoization for all lambdas in (list (cons 1 (lambda () bar)) (cons 5 (lambda () bar)) (cons 13 (lambda () bar))) And it is a nuisance that one can't cons that thing together in the reader and just quote it at runtime, because the read extension works in the wrong lexical environment to produce the right kind of lambda. One could at best use two lists instead of an alist, and at least code the position list as a single constant. -- David Kastrup