[racket] structure question
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