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

This page is part of the web mail archives of SRFI 93 from before July 7th, 2015. The new archives for SRFI 93 are here. Eventually, the entire history will be moved there, including any new messages.

*To*: Per Bothner <per@xxxxxxxxxxx>*Subject*: Re: suggestion: a shorter convenience form*From*: Jens Axel Søgaard <jensaxel@xxxxxxxxxxxx>*Date*: Sat, 24 Jun 2006 17:48:39 +0200*Cc*: srfi-93@xxxxxxxxxxxxxxxxx*Delivered-to*: srfi-93@xxxxxxxxxxxxxxxxx*In-reply-to*: <449E9D54.4030109@xxxxxxxxxxx>*References*: <449AF281.3020807@xxxxxxxxxxx> <449CF423.9050609@xxxxxxxxxxxx> <449E9D54.4030109@xxxxxxxxxxx>*User-agent*: Thunderbird 1.5.0.4 (Windows/20060516)

Per Bothner skrev:

This has one extra longish keyword, an extra parameter name mentioned twice, and an extra level of nesting/indentation.

I need that parameter (at least once) for error reporting.

and at the same time still makes it possible to refer to the original input syntax-object of the transformer.This seems to work: (define-syntax-case name literals (form expression)) For example: (define-syntax-case foo () (form #`(quote form))) Of course this isn't any better than your "common extension", but it's not noticeably worse. And it does allow convenient pattern-matching, about as convenient and compact as Common Lisp's defmacro, but allowing multiple "cases".

Consider Kent's implementation of cond in the reference implementation using the common extension: (define-syntax (cond x) (syntax-case x () [(_ c1 c2 ...) (let f ([c1 #'c1] [c2* #'(c2 ...)]) (syntax-case c2* () [() (syntax-case c1 (else =>) [(else e1 e2 ...) #'(begin e1 e2 ...)] [(e0) #'(let ([t e0]) (if t t))] [(e0 => e1) #'(let ([t e0]) (if t (e1 t)))] [(e0 e1 e2 ...) #'(if e0 (begin e1 e2 ...))] [_ (syntax-error x)])] [(c2 c3 ...) (with-syntax ([rest (f #'c2 #'(c3 ...))]) (syntax-case c1 (else =>) [(e0) #'(let ([t e0]) (if t t rest))] [(e0 => e1) #'(let ([t e0]) (if t (e1 t) rest))] [(e0 e1 e2 ...) #'(if e0 (begin e1 e2 ...) rest)] [_ (syntax-error x)]))]))])) With define-syntax-case (at least if I understand you correctly) it becomes: (define-syntax-case cond () (x (syntax-case x () [(_ c1 c2 ...) (let f ([c1 #'c1] [c2* #'(c2 ...)]) (syntax-case c2* () [() (syntax-case c1 (else =>) [(else e1 e2 ...) #'(begin e1 e2 ...)] [(e0) #'(let ([t e0]) (if t t))] [(e0 => e1) #'(let ([t e0]) (if t (e1 t)))] [(e0 e1 e2 ...) #'(if e0 (begin e1 e2 ...))] [_ (syntax-error x)])] [(c2 c3 ...) (with-syntax ([rest (f #'c2 #'(c3 ...))]) (syntax-case c1 (else =>) [(e0) #'(let ([t e0]) (if t t rest))] [(e0 => e1) #'(let ([t e0]) (if t (e1 t) rest))] [(e0 e1 e2 ...) #'(if e0 (begin e1 e2 ...) rest)] [_ (syntax-error x)]))]))]))

Refering to the original piece of syntax is often neccessary in order to give error messages in terms of user written syntax.I agree with you that the common case should be convenient to write, in this case I'm not sure I think it is worth introducing an extra binding form in order to save relatively few key strokes.It's not the number of keystrokes that matter, it's the number of tokens. Each token adds to the cognitive load required to read a definition. A programmer familiar with the idiom can abstract way the boiler-plate fairly easily, but it is still an extra required but useless mental step.

Adding an extra binding form also adds to the cognitive load for those learning the macro system. For the experienced macro writer it hardly matters which is used. -- Jens Axel Søgaard

**Follow-Ups**:**Re: suggestion: a shorter convenience form***From:*Per Bothner

**References**:**suggestion: a shorter convenience form***From:*Per Bothner

**Re: suggestion: a shorter convenience form***From:*Jens Axel Søgaard

**Re: suggestion: a shorter convenience form***From:*Per Bothner

- Prev by Date:
**Re: suggestion: a shorter convenience form** - Next by Date:
**Quasisyntax** - Previous by thread:
**Re: suggestion: a shorter convenience form** - Next by thread:
**Re: suggestion: a shorter convenience form** - Index(es):