[racket] Null value in macros

From: Diego Sevilla Ruiz (dsevilla at ditec.um.es)
Date: Wed Sep 25 18:33:34 EDT 2013

Hi!

On 23/09/13 17:59, Matthias Felleisen wrote:
>
> Is the following code really that much more complicated that define-macro? -- Matthias

Well, it certainly might not! But I don't find confident enough with 
syntax-case (less with syntax-parse), and I also have some code I will 
reuse that uses define-macro. So, any chance I can get null inserted?

	Anyway, thanks for the pointer and example. At some point I will do all my 
macros with syntax-case/-parse.

	Regards,
	diego.

>
>
>
> #lang racket
>
> (require (for-syntax syntax/parse))
>
> (define-syntax (new-field stx)
>    (syntax-parse stx
>      [(_ f:id) #'(new-field f null)]
>      [(_ f:id default-value)
>       (define field-name (append-id stx "-" #'f))
>       (define set-name (append-id stx #'f "-set!"))
>       #`(begin
>           (field [#,field-name default-value])
>           (define/public (f) #,field-name)
>           (define/public (#,set-name new-value)
>             (set! #,field-name new-value)))]))
>
> ;; Syntax (U String Syntax/Identifier) -> Syntax/Identifier
> (define-for-syntax (append-id stx x y)
>    (define x:str (if (string? x) x (symbol->string (syntax-e x))))
>    (define y:str (if (string? y) y (symbol->string (syntax-e y))))
>    (datum->syntax stx (string->symbol (string-append x:str y:str))))
>
> ;; -----------------------------------------------------------------------------
> ;; some small test
>
> (module+ test
>    (require rackunit)
>
>    (define foo%
>      (class object%
>        (super-new)
>        (new-field f)
>        (new-field g 10)))
>
>    (define foo (new foo%))
>
>    (check-equal? (send foo f) null)
>    (check-equal? (send foo g) 10)
>    (check-equal? (begin (send foo g-set! 20) (send foo g)) 20))
>
>
>
>
>
>
> On Sep 23, 2013, at 5:20 AM, Diego Sevilla Ruiz <dsevilla at ditec.um.es> wrote:
>
>> Dear all:
>>
>> 	I've been developing a library that needs some macro coding. As I come from Common-Lisp and Elisp, I find more pleasing the old-style define-macro. The following function is used as a part of the result building of another define-macro:
>>
>>   (define (new-field-mono f-name (default-value null))
>>     (let ((field-name (append-id "-" f-name))
>>           (set-name (append-id f-name "-set!")))
>>       `(begin
>>          (field [,field-name ,default-value])
>>          (define/public (,f-name) ,field-name)
>>          (define/public (,set-name value)
>>            (set! ,field-name value)))))
>>
>> The problem is in the line of the "field". As default-value is null "()", the field declaration gets:
>>
>> (field -xxx ())
>>
>> Then, the expansions sees this "()", and thinks it is an application of no-function, getting the error:
>>
>> #%app: missing procedure expression;
>> probably originally (), which is an illegal empty application in: (#%app)
>>
>> 	So how could I specify some default value in that function so that the field gets its default value as null? Using '() as default-value doesn't work either, but however, if I generate exactly:
>>
>> (field [,field-name null])
>>
>> it works, so I'm expecting that more macro conversion steps are executed to the unquote operator, but my knowledge doesn't go that far.
>>
>> 	Thanks,
>> 	diego.
>>
>>
>> --
>> Diego Sevilla Ruiz -- http://ditec.um.es/~dsevilla/ -- dsevilla at um.es _.___
>> Dep. Ingeniería y Tecnología de Computadores, Facultad de Informática D|TEC
>> Univ.de Murcia,Campus Espinardo,30080 Murcia (SPAIN),Tel.+34868887571
>> ____________________
>> Racket Users list:
>> http://lists.racket-lang.org/users

-- 
Diego Sevilla Ruiz -- http://ditec.um.es/~dsevilla/ -- dsevilla at um.es _.___
Dep. Ingeniería y Tecnología de Computadores, Facultad de Informática D|TEC
Univ.de Murcia,Campus Espinardo,30080 Murcia (SPAIN),Tel.+34868887571

Posted on the users mailing list.