plait icon indicating copy to clipboard operation
plait copied to clipboard

macros over `define-type`

Open shriram opened this issue 3 years ago • 1 comments

This doesn't work:

#lang plait

;; define a uni-variant type
(define-syntax define-record
  (syntax-rules (:)
    [(define-tuple type-name constructor-name
       [field-name : field-type]
       ...)
     (define-type type-name
       (constructor-name [field-name : field-type] ...))]))

(define-record Tuple2 tuple2
  [fst : String]
  [snd : Number])

(Error: rename-out: no binding for identifier in: tuple2?.) However, the #:untyped version of it works fine, suggesting that this should be considered a bug.

[Credit to Kuang-Chen Lu for finding this.]

shriram avatar Oct 15 '20 16:10 shriram

The problem here turns out to be the way define-type from plai uses the context of the whole define-type form (not individual variant names or even if define-type identifier) for generated names like variant predicates:

#lang plai

(define-syntax-rule (dt x)
  (define-type a
    [x]))

(dt x)
x? ; unbound

I think this should be improved. It's obvious how to make define-type better, but not obvious how the improvement would affect existing plai program.

Meanwhile, you can work around that by explicitly propagating the context:

(define-syntax (define-record stx)
  (syntax-case stx (:)
    [(define-tuple type-name constructor-name
       [field-name : field-type]
       ...)
     (datum->syntax
      stx
      (syntax-e
       #`(define-type type-name
           (constructor-name [field-name : field-type] ...))))]))

mflatt avatar Oct 15 '20 17:10 mflatt