3
votes

define-type and type-case are provided in plai scheme, but for some reason they are not present in typed/racket. I want to implement these constructs in racket using macros.

I want to create a macro "def-user-type" following is the syntax I want to use

    (def-user-type Shape
      [Rectangle ((l Number) (b Number))]
      [Circle    ((r radius))]
      [Blah      (())])

And it should roughly behave as following

    (define-type Shape (U Rectangle Circle Blah))
    (struct: Rectangle ([l : Number] [b Number]))
    (struct: Circle ([r : Number]))
    (struct: Blah ())

This is what I have achieved so far. It is incorrect and the error message given by racket compiler is not helping either.

#lang typed/racket
(define-syntax define-user-type
  (syntax-rules()
    [(define-user-type type-name
       [sub-type ((field-name type) ...)]
       ...)
     ((define-type type-name (U sub-type ...))
     (struct: sub-type ([field-name : type] ...))
     ...)]))

Please guide me. thanks!

1

1 Answers

4
votes

You seem to be asking more than one question.

First, Typed Racket has a define-type but it's probably a little different from the version in #lang plai. You can see the implementations of plai's define-type and type-case here.

Second, there are a couple of problems with your macro.

1) The right-hand side of your syntax-rules clause is applying the result of define-type as a function, which won't work. Try using a begin to combine the expressions.

2) Your use of your def-user-type macro is not following the definition. The definition requires zero or more (field-name type) pairs, but in Blah you give (), which is not a pair.

3) radius is an undefined type

Here is a version of your macro with the suggested changes:

#lang typed/racket

(define-syntax def-user-type
  (syntax-rules ()
    [(_ type-name [sub-type ((field-name type) ...)] ...)
     (begin
       (define-type type-name (U sub-type ...))
       (struct: sub-type ([field-name : type] ...)) ...)]))

(def-user-type Shape
  [Rectangle ((l Number) (b Number))]
  [Circle    ((r Number))]
  [Blah      ()])

And here is an example that uses a Rectangle as a Shape:

> ((λ: ([x : Shape]) x) (Rectangle 1 2))
- : Shape
#<Rectangle>