Today I decided to convert all structure definitions in a Typed Racket file
to lists. For instance,

(struct foo ([x : Integer]))


would become a tagged list:

(define-type foo (Pairof 'foo (List Integer)))

along with a constructor, predicate, and accessors.

Using a macro, I was able to write what I wanted to do once and use it for
multiple structures.
Here's how it looked in one file: all I had to do was write the macro, use
"struct2" instead of "struct", and remove uses of "struct-out". Other files
in the project worked with the new data definition, no problems.

#lang typed/racket
(require (for-syntax racket/base syntax/parse racket/syntax))

(define-syntax (struct2 stx)
  (syntax-parse stx #:datum-literals (:)
   [(_ name:id ([f*:id : t*] ...))
    #:with ((name-f* i*) ...)
      (for/list ([f (in-list (syntax-e #'(f* ...)))]
                 [i (in-naturals 1)])
        (list (format-id stx "~a-~a" (syntax-e #'name) (syntax-e f)) i))
    #:with Name (format-id stx "~a" (string-titlecase (symbol->string
(syntax-e #'name))))
    #:with name? (format-id stx "~a?" (syntax-e #'name))
    (syntax/loc stx (begin
      (define-type Name (Pairof 'name (Listof Any)))
      (provide Name)
      (define (name (f* : t*) ...) : Name
        (list 'name f* ...))
      (provide name)
      (define (name-f* (p : Name)) : t*
        (cast (list-ref p 'i*) t*))
      ...
      (provide name-f* ...)
      (define (name? (v : Any)) : Boolean
        (and (list? v) (not (null? v)) (eq? 'name (car v))))  ))]))

(struct2 posn ([x : Real]
               [y : Real]))
(struct2 block ([x : Real]
                [y : Real]
                [color : Symbol]))
(struct2 tetra ([center : Posn]
                [blocks : (Listof Block)]))
(struct2 world ([tetra : Tetra]
                [blocks : (Listof Block)]))

(: posn=? (-> Posn Posn Boolean))
(define (posn=? p1 p2)
  (and (= (posn-x p1) (posn-x p2))
       (= (posn-y p1) (posn-y p2))))

(provide posn=?)


(Nevermind why I did this, or why I used "Any" and "cast". Hopefully the
macro is interesting.)

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to