I have a custom set and I want to use it in typed racket. I
require it using require/typed
with the #:opaque custom-set?
instruction. It works, except that the code fails at run time when I
call custom-set?
with a syntax object.
I have something like the following:
#lang typed/racket/base
(module UNTYPED racket/base
(require racket/set)
(provide custom-set?
make-immutable-custom-set)
(define-custom-set-types custom-set
#:elem? identifier?
(λ (id1 id2) (eq? (syntax-e id1) (syntax-e id2)))))
(require/typed 'UNTYPED
[#:opaque MySet custom-set?]
[make-immutable-custom-set ((Listof Identifier) -> MySet)])
(custom-set? (make-immutable-custom-set (list #'foo #'bar))) ;; #t
(custom-set? '()) ;; #f
Which type checks and returns #t
or #f
as expected.
Now, if I try to call the same custom-set?
predicate with a syntax object:
(custom-set? #'(foo bar))
Then, I get the following contract violation instead of #f
:
custom-set?: broke its own contract
Attempted to use a higher-order value passed as `Any` in untyped code: #<syntax:stdin:: a>
in: the 1st argument of
a part of the or/c of
(or/c
struct-predicate-procedure?/c
(-> Any boolean?))
contract from: (interface for custom-set?)
blaming: (interface for custom-set?)
The same call into the UNTYPED
module works and returns #f
as expected. Could you tell me why a syntax object breaks the contract here? And can I fix this?
(struct x ()) (custom-set? (x))
– Ben Greenman