[racket] structure question

From: Manfred Lotz (manfred.lotz at arcor.de)
Date: Thu Dec 9 11:56:10 EST 2010

On Wed, 8 Dec 2010 16:13:08 -0500
Matthias Felleisen <matthias at ccs.neu.edu>
wrote:

> 
> 
> 
> Here is a version with 'type' annotations that should be easier to
> read and learn from. 
> 
> #lang racket
> 
> ;;
> ----------------------------------------------------------------------------- ;;
> library module 
> 
> ;; syntax def
> ;; definition = ... | (struct/kw name (field ...) options ...)
> ;; meaning:           (struct name (field ...) options ...) 
> ;;                     plus keyword-based constructor: name/kw
> ;; WARNING: the introduction of name/kw is non-hygienic 
> ;; NEW: allow optional default expressions on field-s
> ;; WARNING: this new option will interfere with the #:auto field
> option
> 
> (define-syntax (struct/kw stx)
>   (syntax-case stx ()
>     [(_ name (field ...) . stuff)
>      (let* (;; [Listof Syntax/Field]
>             [field* (syntax->list #'(field ...))]
>             ;; [Listof Syntax/Identfier]
>             [fields (map (lambda (f)
>                            (syntax-case f ()
>                              [(name default) #'name]
>                              [name f]))
>                          field*)]
>             ;; Syntax/Identifier -> Keyword 
>             [symbol-as-keyword
>              (lambda (name)
>                (string->keyword (symbol->string (syntax-e name))))]
>             ;; Parameter = [List Keyword Syntax/Identfier]
>             ;;           U [List Keyword [List Syntax/Identifier
> Syntax]] ;; Syntax/Field -> Parameter 
>             [field-to-kw-param
>              (lambda (f)
>                (syntax-case f ()
>                  [[name default] 
>                   `(,(symbol-as-keyword #'name) (,#'name ,#'default))]
>                  [name 
>                   `(,(symbol-as-keyword f) ,f)]))]
>             ;; [Listof Parameter]
>             [parameters 
>              (foldr (lambda (f r) (append (field-to-kw-param f) r))
> '[] field*)] ;; Syntax/Identfier 
>             [name/kw 
>              (datum->syntax stx 
>                             (string->symbol 
>                              (string-append
>                               (symbol->string (syntax-e #'name))
> "/kw")))]) #`(begin
>            (struct name #,fields . stuff)
>            (define (#,name/kw #, at parameters)
>              (name #, at fields))))]))
> 
> 
> 
> 
> ;;
> ----------------------------------------------------------------------------- ;;
> usage example (could be separate module) (define detail-default "?")
> (struct/kw book (author title [details detail-default]) #:transparent)
> 
> (define book1 (book/kw #:title "The Client" #:author "John Grisham"))
> 
> (define book2 (book/kw #:title "The Client" #:author "John Grisham"
> #:details "?"))
> 
> (string=? (book-author book1) "John Grisham") 
> (string=? (book-details book2) "?")
> 
> 


So I have something to dig my teeth into. Thanks again.


-- 
Manfred




Posted on the users mailing list.