Skip to content

WIP: add type-out provide-spec #301

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 7 commits into
base: master
Choose a base branch
from
Open

WIP: add type-out provide-spec #301

wants to merge 7 commits into from

Conversation

bennn
Copy link
Contributor

@bennn bennn commented Feb 2, 2016

(Work-in-progress because there's a bug with (type-out (struct ...)) -- you can't use the struct inside the defining module.)

Adds initial support for a type-out provide spec.

Design goals:

  • Behavior is a superset of contract-out (currently missing #:exists and #:forall)
  • Look like an ML-style interface, with all type defs. and typed identifiers

Current look:

#lang typed/racket/base

(provide
  (type-out
    (type FullName (List String String))
    (struct person ([name : FullName] [id : Natural]))
    (get-first-name (-> FullName String))))

(define (get-first-name fn)
  (car fn))

Later on, I'd like to add #:exists & #:forall to bind variables across multiple type definitions, and options to export opaque types and ADTs. But I think it's better to address those separately.

;; actually do the work on a module
;; produces prelude and post-lude syntax objects
;; syntax-list -> (values syntax syntax)
(define (type-check forms0)
(define forms (syntax->list forms0))
(define forms (lift-type-declarations (syntax->list forms0)))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Possible issue: I'm re-ordering the top-level forms so that type declarations come first. Without this, type annotations aren't associated with the right definitions.

Not sure whether this will change to fix the bug with structs.

@samth
Copy link
Member

samth commented Feb 2, 2016

A few thoughts:

  • Can you describe the intended semantics of this briefly? Is it a replacement for top-level type annotations, or an ML-style signature (ie, you'd still need annotations internally), or something else?
  • I really don't think struct definitions should go in the provide form. That's not how it works in contract-out -- you have to have a definition of the struct in the module, and it's not how it works in ML either. Changing that should make the struct issue easier to solve.

@bennn
Copy link
Contributor Author

bennn commented Feb 2, 2016

  • Yes, this is intended as a replacement for top-level type definitions.* The idea is to put types where the user is more likely to see them & keep abusing provide as an API. I also want to offer a smooth migration from contract-out -- just change "contract" to "type" and you're rolling.
  • Removing struct defs would solve the issue, but then (type-out (struct ...)) is pretty much a no-op. We can only check that both type annotations (in the provide & at the definition) match.

* Non-provided functions would still need an annotation

@bennn
Copy link
Contributor Author

bennn commented Feb 3, 2016

Leif pointed out that we definitely don't want struct properties declared in a provide form, so now I'm in favor of writing the fields twice (in code & in the type-out). We could then also use the type-out to hide some fields or use different types.

@samth
Copy link
Member

samth commented Feb 3, 2016

I think we should start with something that just handles type annotations, and see how that works. I don't think provide should produce definitions (except as an implementation detail, as in contract-out), and I think information hiding a la ML modules is a larger design issue that deserves more thought before we start implementing.

@bennn
Copy link
Contributor Author

bennn commented Feb 3, 2016

Ok. Do you mind if it allows define-type aliases?

... (type-out T (Listof Integer)) ...

=== becomes ===>

(define-type T (Listof Integer))
(provide T)

@samth
Copy link
Member

samth commented Feb 3, 2016

That's what I mean about definitions. I don't think provide should introduce new bindings in the module. Nothing else in Racket works that way.

@bennn
Copy link
Contributor Author

bennn commented Feb 4, 2016

Checkpoint:

  • No longer makes definitions, just adds annotations & renames. (doc-screenshot)
  • TODO: struct types are currently ignored. We should check that:
    • field types match implementation
    • super declarations are correct
    • all fields are annotated (can't leave out field / super field from type-out)
    • (anything else?)

Is there an easy way to get struct information from the struct type name? I tried struct-type-info but I haven't got the right inspector. (I can probably copy what contract-out does, once I understand that.)

#lang typed/racket/base
(struct s ())
(call-with-values (lambda () (struct-type-info struct:s)) list)
;; struct-type-info: current inspector cannot extract info for structure type

@bennn
Copy link
Contributor Author

bennn commented Feb 14, 2016

Things are pretty good now, but I'm blocked on 1 problem and have a few questions:

Problem: this is currently incompatible with the #:type-name option because I assume the struct name is the type name. How can I get a type name from a struct name?

Questions

  • type-out annotations for struct fields are only checked, not enforced. So (struct s ([x : Integer])) ... (type-out s ([x : Real]))) ... is valid and users will get integers from s-x. Should we fix this, and reject non-exact type-out annotations?
  • Currently check struct recursively to make sure all supertype fields are given annotations. Should we not do that (I'm thinking we should not do that)
  • Order of struct field annotations is not enforced. (Probably should be)

EDIT: supertype fields must not be included, field order is enforced

@bennn bennn changed the title [wip] add type-out provide-spec WIP add type-out provide-spec Oct 2, 2016
@bennn bennn changed the title WIP add type-out provide-spec WIP: add type-out provide-spec Oct 2, 2016
@bennn
Copy link
Contributor Author

bennn commented Jan 4, 2017

status update: this PR is not ready to merge because it doesn't handle structs as well as contract-out. Need to fix #322 first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants