[racket] Null value in macros

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Mon Sep 23 11:59:46 EDT 2013

Is the following code really that much more complicated that define-macro? -- Matthias



#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



Posted on the users mailing list.