From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Ian Price Newsgroups: gmane.lisp.guile.devel Subject: Re: Syntax Parameters documentation for guile Date: Sat, 07 Jan 2012 02:05:52 +0000 Message-ID: <87aa60mflr.fsf@Kagami.home> References: <87pqff8f5g.fsf@Kagami.home> <20222.48501.219043.125940@winooski.ccs.neu.edu> <87sjjwz8u9.fsf@Kagami.home> <20227.40509.861506.889987@winooski.ccs.neu.edu> <87mxa0llbd.fsf@pobox.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: dough.gmane.org 1325902302 31063 80.91.229.12 (7 Jan 2012 02:11:42 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 7 Jan 2012 02:11:42 +0000 (UTC) Cc: Guile Mailing List To: Andy Wingo Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Jan 07 03:11:38 2012 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 1RjLkw-0003LS-AI for guile-devel@m.gmane.org; Sat, 07 Jan 2012 03:11:38 +0100 Original-Received: from localhost ([::1]:42835 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RjLkv-0006zX-QR for guile-devel@m.gmane.org; Fri, 06 Jan 2012 21:11:37 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:45544) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RjLks-0006zB-C4 for guile-devel@gnu.org; Fri, 06 Jan 2012 21:11:35 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RjLkr-0007AO-7k for guile-devel@gnu.org; Fri, 06 Jan 2012 21:11:34 -0500 Original-Received: from mail-ww0-f49.google.com ([74.125.82.49]:48390) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RjLkq-0007AD-RL for guile-devel@gnu.org; Fri, 06 Jan 2012 21:11:33 -0500 Original-Received: by wgbdt13 with SMTP id dt13so2057wgb.30 for ; Fri, 06 Jan 2012 18:11:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type; bh=FZebpJHdECSq3y0rZk2OTjK5ylqxxlCg52CalTObPmA=; b=AphtI/1q4IYRUUzCc0RF5ifR8RuvuvWNRR0ARqTZoz/B8erQGI15hmnBwKyedZoLxY UZEbu4BVRO0R/Lqen43DMEis0Ig7tkmpo97XY1VoRBXkkaQ+b5Fes/yuohyCPAm4YTbw jXJ7D2tDwXs2KrC3MAVjfoOd3TJhMLd1fJtjs= Original-Received: by 10.180.94.97 with SMTP id db1mr15050791wib.16.1325902292039; Fri, 06 Jan 2012 18:11:32 -0800 (PST) Original-Received: from Kagami.home (host86-171-77-216.range86-171.btcentralplus.com. [86.171.77.216]) by mx.google.com with ESMTPS id g12sm84230958wiw.10.2012.01.06.18.11.30 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 06 Jan 2012 18:11:30 -0800 (PST) In-Reply-To: <87mxa0llbd.fsf@pobox.com> (Andy Wingo's message of "Fri, 06 Jan 2012 19:47:50 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 74.125.82.49 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:13388 Archived-At: --=-=-= Andy Wingo writes: > I have pushed a couple commits to Guile that provide > define-syntax-parameter and syntax-parameterize on the stable-2.0 > branch, in addition to the support that was already there on master. Excellent > Ian, just edit doc/ref/api-macros.texi. You don't need to know very > much in the way of formatting; just follow the examples there and you'll > be good. Yes, dsmith and ludovic assured me as much on IRC :) -- Ian Price "Programming is like pinball. The reward for doing it well is the opportunity to do it again" - from "The Wizardy Compiled" --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-document-syntax-parameters.patch Content-Description: documentation for syntax parameters >From 3d1426ec8c0b8f1b1524a87fdeb2d17a6580c928 Mon Sep 17 00:00:00 2001 From: Ian Price Date: Sat, 7 Jan 2012 01:59:33 +0000 Subject: [PATCH] document syntax parameters * doc/ref/api-macros.texi (Macros): Add subsection for "Syntax Parameters" --- doc/ref/api-macros.texi | 76 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 76 insertions(+), 0 deletions(-) diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi index 92816ad..7a15e82 100644 --- a/doc/ref/api-macros.texi +++ b/doc/ref/api-macros.texi @@ -40,6 +40,7 @@ languages}, or EDSLs.}. * Syntax Case:: Procedural, hygienic macros. * Defmacros:: Lisp-style macros. * Identifier Macros:: Identifier macros. +* Syntax Parameters:: Syntax Parameters * Eval When:: Affecting the expand-time environment. * Internal Macros:: Macros as first-class values. @end menu @@ -861,6 +862,81 @@ wrapping in @code{#'} syntax forms. @end deffn +@node Syntax Parameters +@subsection Syntax Parameters + +Syntax parameters@footnote{Described in the paper @cite{Keeping it Clean with +Syntax Parameters} by Barzilay, Culpepper and Flatt.} are a mechanism for rebinding a macro +definition within the dynamic extent of a macro expansion. It provides +a convenient solution to one of the most common types of unhygienic +macro: those that introduce a unhygienic binding each time the macro +is used. Examples include a @code{lambda} form with a @code{return} keyword, or +class macros that introduce a special @code{self} binding. + +With syntax parameters, instead of introducing the binding +unhygienically each time, we instead create one binding for the +keyword, which we can then adjust later when we want the keyword to +have a different meaning. As no new bindings are introduced, hygiene +is preserved. This is similar to the dynamic binding mechanisms we +have at run-time like @ref{SRFI-39, parameters} or +@ref{Fluids and Dynamic States, fluids}, except that the dynamic +binding only occurs during macro expansion. The code after macro +expansion remains lexically scoped. + +@deffn {Syntax} define-syntax-parameter keyword transformer +Binds @var{keyword} to the value obtained by evaluating @var{transformer}. The +@var{transformer} provides the default expansion for the syntax parameter, +and in the absence of @code{syntax-parameterize}, is functionally equivalent +to @code{define-syntax}. Usually, you will just want to have the @var{transformer} +throw a syntax error indicating that the @var{keyword} is supposed to be +used in conjunction with another macro, for example: +@example +(define-syntax-parameter return + (lambda (stx) + (syntax-violation 'return "return used outside of a lambda^" stx))) +@end example +@end deffn + +@deffn {Syntax} syntax-parameterize ((keyword transformer) @dots) exp @dots +Adjusts @var{keyword} @dots to use the values obtained by evaluating +their @var{transformer} @dots, in the expansion of the @var{exp} @dots +forms. Each @var{keyword} must be bound to a +syntax-parameter. @code{syntax-parameterize} differs from +@code{let-syntax}, in that the binding is not shadowed, but adjusted, +and so uses of the keyword in the expansion of exp forms use the new +transformers. This is somewhatsimilar to how @code{parameterize} +adjusts the values of regular parameters, rather than creating new +bindings. + +@example +(define-syntax lambda^ + (syntax-rules () + [(lambda^ argument-list body bodies ...) + (lambda argument-list + (call-with-current-continuation + (lambda (escape) + ;; in the body we adjust the 'return' keyword so that calls + ;; to 'return' are replaced with calls to the escape continuation + (syntax-parameterize ([return (syntax-rules () + [(return vals (... ...)) + (escape vals (... ...))])]) + body + bodies ...))))])) + +;; now we can write functions that return early. Here, 'product' will +;; return immediately if it sees any 0 element. +(define product + (lambda^ (list) + (fold (lambda (n o) + (if (zero? n) + (return 0) + (* n o))) + 1 + list))) +@end example +@end deffn + + @node Eval When @subsection Eval-when -- 1.7.7.4 --=-=-=--