Reputation: 43892
The Typed Racket reference indicates that it's possible to use with-type
to created “typed regions” within untyped code.
The
with-type
form allows for localized Typed Racket regions in otherwise untyped code.
It’s a little unclear how to actually use this, though. Obviously, using such a feature needs to take place within an untyped module using #lang racket
or something similar. How should the with-type
binding be imported?
A naïve attempt is just to require
Typed Racket, but this causes failures with how TR overwrites existing syntactic forms.
(require typed/racket)
(struct point (x y)) ; complains about missing type annotations
Trying to use only-in
to simply require with-type
and nothing else sort of works, but then none of the required type bindings (such as Number
or ->
) exist.
It seems like the only way to do this would be to manually use only-in
to import only the things that I need, but this feels laborious. I could also use prefix-in
, but then of course everything would be scattered with prefixes.
Is there a recommended way of doing this, or is this feature somewhat deprecated?
Upvotes: 4
Views: 144
Reputation: 5053
I would just use except-in
(or perhaps rename-in
) to avoid the few identifiers that don't work in both typed and untyped programs. Like this modification of Greg's program:
#lang racket/base
(require (except-in typed/racket struct))
(struct point (x y))
(let ([x 'hello])
(with-type
#:result String
#:freevars ([x String])
(string-append x ", world")))
Upvotes: 1
Reputation: 16260
I don't know the fundamental answer. A guess is that it's the sort of thing that would be useful when writing macros, as opposed to code you'd write directly?
A practical idea: You can use local-require
to limit the "contamination" of the TR require. And you can flip to using except-in
if that's less work then only-in
.
For instance this example from the docs get close, but gives a weird error presumably because it's using TR's quote
:
#lang racket/base
(let ([x 'hello])
(local-require typed/racket)
(with-type
#:result String
#:freevars ([x String])
(string-append x ", world")))
; /tmp/so.rkt:7:21: quote: identifier used out of context
; in: quote
Excluding that with except-in
gives the desired error:
(let ([x 'hello])
(local-require (except-in typed/racket quote))
(with-type
#:result String
#:freevars ([x String])
(string-append x ", world")))
; x: broke its contract
; promised: String
; produced: 'hello
; in: String
; contract from: /tmp/so.rkt
; blaming: /tmp/so.rkt
; (assuming the contract is correct)
; at: /tmp/so.rkt:14.17
But yeah. This is just fiddling with the edges and not getting to the heart of it.
Upvotes: 2