since 'restrict' will now create intersections when there is
a complex relationship between the two types, calling it
'intersect' makes a lot more sense.
Adds intersection types as a better way to handle the the case
when restrict cannot structurally intersect two types (e.g. when
you learn within a polymorphic function a variable x of type A
is also an Integer, but we dont know how A relates to Integer).
This allows for non-lossy refinements of type info while typechecking.
This pull request is largely a renaming effort to clean up the TR codebase. There are two primary things I wanted to change:
1. Replace all occurrences of "filter" with "prop" or "proposition"
- The word "filter" is a meaningless opaque term at this point in the Typed Racket implementation. If anything, it just adds confusion to why things are the way the are. We should use "proposition" instead, since that's what they actually are.
2. Avoid using "Top" and "Bottom" in both the type and proposition realm.
- Currently the top type is called Univ and the bottom type is called bottom, while the top proposition is called Top and the bottom proposition is called Bot. This is just unnecessarily confusing, doesn't really line up w/ the user-space names, and doesn't line up with the names we use in TR formalisms. Worse, all of the top types of primitive types---e.g. the type of all structs, StructTop--- use Top, so it is really easy to get confused about what name to use for these sorts of things.
With these issues in mind, I made the following changes to names:
Top -> TrueProp
Bot -> FalseProp
TypeFilter -> TypeProp
NotTypeFilter -> NotTypeProp
AndFilter -> AndProp
OrFilter -> OrProp
-filter t o -> -is-type o t
-not-filter t o -> -not-type o t
FilterSet -> PropSet
NoFilter -> #f
NoObject -> #f
-FS -> -PS
-top -> -tt
-bot -> -ff
implied-atomic? q p -> implies-atomic? p q
filter-rec-id -> prop-rec-id
-no-filter -> -no-propset
-top-filter -> -tt-propset
-bot-filter -> -ff-propset
-true-filter -> -true-propset
-false-filter -> -false-propset
PredicateFilter: -> PredicateProp:
add-unconditional-filter-all-args add-unconditional-prop-all-args
* Fix type of syntax->list
to return `(U False (Listof (Syntaxof Any)))` if it can't prove that the input is a syntax-list.
Fixes https://github.com/racket/typed-racket/issues/347
This makes the type `syntax->list` consistent with the type `stx->list` already has.
* Add tests for syntax->list
This makes the tooltip show the more refined function
type after application typechecking. For example, case->
types will be narrowed to the particular case that fits.
Polymorphic function types will be instantiated at the
appropriate type.
Fixes issue #325
This is used for functions with a single argument imported with
`require/typed`, and avoids unneccessary checks. This produces a
3x speedup on the following benchmark:
#lang racket/base
(module m racket/base
(provide f)
(define (f x) x))
(module n typed/racket/base
(require/typed
(submod ".." m)
[f (-> Integer Integer)])
(time
(for ([x (in-range 1000000)])
(f 1) (f 2) (f 3) (f 4))))
(require 'n)
on top of the previous improvment from using `unsafe-procedure-chaperone`
and `procedure-result-arity`.
This allows the types generated by the struct form, as well as #:struct
clauses of require/typed, to be specified explicitly using a #:type-name
option. This allows the name of a struct and the type it is assigned to
be different.
Closes#261
Guard opaque predicates with an (-> Any Any) contract. This uses the
contract generation infrastructure to avoid wrapping struct predicates.
Also, relax `any-wrap/c` (the contract used for `Any` in positive
position) to allow opaque structures. This also requires an enumeration
of all the other kinds of values that TR understands, so that they are
not confused with opaque structures.
Joint work with @bennn.
Closes#202.
Closes#203.
Closes#241.
`typed-racket-test/main` is now the file to run for almost everything.
`typed-racket-test/run` continues to exist so that DrDr preserves the
timing history.
Integration tests now print a progress meter, which should fix the
Travis timeouts.
See also commit 5cd5f77 “Don't allow promises created with `delay/name` as `(Promise T)`.”.
The contracts in `typed-racket-lib/typed-racket/static-contracts/combinators/structural.rkt` should be just a single identifier, not a lambda expression, because `typed-racket-lib/typed-racket/private/type-contract.rkt` relies on that, and passes the contract name to free-identifier=?, which won't work on a lambda.
* Add `normalise-inputs` to special function env.
* Treat eta-expansion specially. Now
`(lambda (x ...) (f x ...))`
will typecheck like `f` but with a type restricted to
the size of `x ...`.
Currently, this special case only works for non-polymorphic
functions.
New strategy for compiling the (-> Any Boolean) type to a contract.
When possible, uses `struct-predicate-procedure?` instead of
wrapping in `(-> any-wrap/c boolean?)`.
Makes exceptions for untyped chaperones/impersonators over struct predicates;
those are always wrapped with `(-> any-wrap/c boolean?)`.
This change also affects (require/typed ... [#:struct ...]), but not #:opaque
For private `define-values` in classes with multiple variables, don't
eagerly throw type errors in the synthesis step. Instead, wait
until the later checking step when the environment will be correctly
set up.
When the initial synthesis typecheck fails, yield type Any for
the environment. If the typecheck should really fail, this is ok. If
not, then the user can add a type annotation.
A better long-term strategy is to change the handling of environments
so that the type environment gets refined as definitions are checked.
This way all annotations that the user writes are factored into the
initial environment and unannotated variables will have their types
synthesized.
Previously, most of it was actually deterministic enumeration, which meant
repeating the same tests over and over again. We still want to run those,
if only to catch regressions, so now we run both enumeration and truly
random tests, separately.
This does mean that the set of tests being run for a given seed is not the
same as it used to, so old seeds won't give the same results as before.
Most unit forms are supported, including most of the "infer" forms that
infer imports/exports/linkages from the current context.
Notably, none of the structural linking forms for units are supported, and
`define-unit-binding` is also currently unsupported.
When identifiers provided by typed modules were used in
certain submodules of the form (module* n #f ...) or were
used by modules implemented in a language defined by TR,
the wrong redirection was used in the expansion.
The reason was because TR's identifier redirection decided
whether it was in a typed or untyped context at module visit
time, but that's too early in the cases above.
(because TR's #%module-begin may not have begun expanding yet)
The fix uses a rename-transformer that delays the decision
to use the typed or untyped identifier until expansion time.
Closes GH issue #163 and #181
Closes PR 15118
Moves `get-alternate` since its only user is the require-contract
module. In addition, it appears that one of the cases in the
conditional in its body is unnecessary. This likely means that
the extra machinery for typed-renamers are not needed at all.
Also adds a test for `require/typed` of a typed module
Only parse and use the type annotations if they are present on
all fold variables. This matches the default for other forms in TR.
Also, this will usually result in a "insufficient type information"
message which is more helpful than if TR chose some default type.
Closes PR 15138
Closes PR 14893
I had forgotten to adjust the define-struct macro to work
like the struct macro for the #:prefab keyword, which made
TR think prefabs were ordinary structs.
Closes GH issue #188
Previous version replaced calls to, e.g., `cadr` with calls to `cdr`
then `car`, called the typechecker to populate the type table, then
optimized the exploded operations. The call to the typechecker failed
on open terms, limiting the applicability of the optimization, and was
just generally brittle.
The new version instead explodes operations, then optimizes them inside
out for as long as the argument's type guarantees it's safe. This works
on open terms, and should be more robust.
In the case that a let rhs doesn't return and therefore the
bodies of the let are unreachable, the bodies need to be marked
as ignored for the optimizer.
In addition, don't attempt unboxed let optimization at all
if the return type is Nothing since it probably means some
body expressions have no type.
Closes GH issue #165
The old check was broken for cases with type constructors
with more than one type argument and was also too conservative
in some cases (e.g., when one cycle refers to another cycle of
aliases in a non-recursive manner).
The new check is still conservative, but it allows more types
than before.
Closes GH issue #157