Skip to content

Patched require/untyped-contract to accept a language spec. #1330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,9 @@ syntax transformers that must expand differently in typed and untyped contexts.
@history[#:changed "1.14"
@elem{The module moved from @tt{typed-racket-more} to @tt{typed-racket-lib}.}]

@defform*/subs[[(require/untyped-contract maybe-begin module [name subtype] ...)]
([maybe-begin code:blank (code:line (begin expr ...))])]{
@defform*/subs[[(require/untyped-contract maybe-begin module maybe-language-spec [name subtype] ...)]
([maybe-begin code:blank (code:line (begin expr ...))]
[maybe-language-spec identifier?])]{
Use this form to import typed identifiers whose types cannot be converted into
contracts, but have @emph{subtypes} that can be converted into contracts.

Expand All @@ -130,6 +131,17 @@ it can be imported and used in untyped code this way:
The type @racket[(-> Integer Integer)] is converted into the contract used
for @racket[negate].

Additionally, if the defining module for the imported identifier uses a Typed Racket
variant such as Shallow Typed Racket, @racket[require/untyped-contract] can be directed
to use the appropriate language by providing a language specification:
@racketblock[(require/untyped-contract
"my-numerics.rkt"
typed/racket/shallow
[negate (-> Integer Integer)])]
The type @racket[(-> Integer Integer)] is then expanded to a contract in the context of the
chosen language variant. Omitting the language specification uses the default @racket[typed/racket/base]
language as the expansion context.

The @racket[require/untyped-contract] form expands into a submodule
with language @racketmodname[typed/racket/base]. Identifiers used in
@racket[subtype] expressions must be either in Typed Racket's base type
Expand Down
21 changes: 12 additions & 9 deletions typed-racket-lib/typed/untyped-utils.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
(stx-map (lambda (id) ((make-syntax-introducer) id)) ids))

(define-syntax (require/untyped-contract stx)
(syntax-parse stx #:literals (begin)
[(_ (begin form ...) from-module-spec:expr [name:id T:expr] ...)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keep the indentation like it was

(syntax-parse stx #:literals (begin quote)
[(_ (begin form ...) from-module-spec:expr language-spec:id [name:id T:expr] ...)
(with-syntax* ([(typed-name ...) (generate-temporaries #'(name ...))]
[(untyped-name ...) (freshen #'(name ...))]
[(untyped2-name ...) (generate-temporaries #'(name ...))]
Expand All @@ -39,19 +39,18 @@
[typed-module (generate-temporary #'typed-module)]
[untyped-module (generate-temporary #'untyped-module)]
[*racket/base (datum->syntax #'from-module-spec 'racket/base)]
[*typed/racket/base (datum->syntax #'from-module-spec
'typed/racket/base)]
[*require (datum->syntax #'from-module-spec
'require)]
[*typed/racket (datum->syntax #'from-module-spec (syntax-e #'language-spec))]
[*require (datum->syntax #'from-module-spec 'require)]
[*language-spec (datum->syntax #'racket/base (syntax-e #'language-spec))]
Copy link
Contributor

@bennn bennn Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was typed/racket before. I think it needs to be the language-spec.
EDIT: oh, I misremembered the argument order. This could just be #'here.

Copy link
Author

@Rscho314 Rscho314 Jun 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bennn Thanks for the feedback. I've changed the datum->syntax context to #'_. I'm not really up to good coding style conventions for Racket, so I hope I've done the right thing.

EDIT:

As for the error about an (only-in quote), I agree the message could be improved. From a cursory glance at the source, I think the most feasible way of doing it is to wrap require/untyped-contract in a with-handlers form and providing a custom message. Letting the exception bubble up to handle it more generally immediately brings us to core racket collections that I'd rather not touch. Thoughts ?

Is there anything else I can do to improve this PR ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about changing the syntax from typed/racket/shallow to #:lang typed/racket/shallow --- from :id to keyword +:expr ? that should improve the error and make this easier to use later.

[from-module-spec-for-submod
(syntax-parse #'from-module-spec #:literals (submod)
[(submod (~and base (~or "." "..")) elem ...)
(syntax/loc #'from-module-spec (submod base ".." elem ...))]
[x #'x])])
(syntax/loc stx
(begin
(module typed-module *typed/racket/base ; to bind in `T`s
(*require typed/racket/base) ; to bind introduced `begin`, etc.
(module typed-module *typed/racket ; to bind in `T`s
(*require *language-spec) ; to bind introduced `begin`, etc.
(begin form ...)
(require (only-in from-module-spec-for-submod
[name untyped2-name] ...))
Expand All @@ -70,5 +69,9 @@
(define-typed/untyped-identifier macro-name typed-name untyped3-name) ...)

(require (rename-in (submod "." untyped-module) [macro-name name] ...)))))]
[(_ from-module-spec:expr language-spec:id [name:id T:expr] ...)
(syntax/loc stx (require/untyped-contract (begin) from-module-spec language-spec [name T] ...))]
[(_ (begin form ...) from-module-spec:expr [name:id T:expr] ...)
(syntax/loc stx (require/untyped-contract (begin form ...) from-module-spec typed/racket/base [name T] ...))]
[(_ from-module-spec:expr [name:id T:expr] ...)
(syntax/loc stx (require/untyped-contract (begin) from-module-spec [name T] ...))]))
(syntax/loc stx (require/untyped-contract (begin) from-module-spec typed/racket/base [name T] ...))]))