-
Notifications
You must be signed in to change notification settings - Fork 81
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
Cast elision inside statically typed code #285
Comments
The contract is useless only if It's actually a fairly non-trivial transformation, which I've been considering as out of scope for the near future. |
I am not sure. Since the enclosing block This example is particular because
I agree it's not urgent, and that it needs more justification than "it seems to work": probably a description of the type system together with a proof of the soundness of the transformation under reasonable hypotheses. I just wanted to write down the idea first. |
You can insert dynamically typed blocks in a statically typed context using The comparison with having no type signature is intriguing, though. It's an interesting curiosity to keep in mind. |
Oh, you're right, of course. That's strange, because it means that in one "direction", when an untyped context calls from an inner typed term, then the typed code is always protected and blame safety holds (if it doesn't contain any untyped chunk, at least). But this is not true in the other direction without annotations, that is an inner untyped code calling from enclosing typed code can call anything without firing any contract, making a well-typed term elicit blame, as in this example:
where the well-typed |
There is a sense in which this is the correct behaviour. But it's definitely quirky. |
For the record, (one of) my use-case was the following: currently, we have the list stdlib as
As noted in #226, this currently makes the stdlib unusable in typed context. A second problem appeared during #284 when trying out A simple solution, even if temporary, is to hoist up the type annotations up to the
The gain is twofold:
Sadly, this doesn't work because we don't do generalization automatically, thus The point is, we could have a way of annotating subterms just for the sake of typechecking, but without firing a contract. Maybe it could be special syntax restricted to the stdlib. Or maybe that's already too many different type annotations. |
This has really little to do with automatic generalisation. It's only a limitation in the implementation. I'm surprised about the connection to the To preserve tail calls we may want to be a bit clever about contract check insertion in (mutually) recursive definitions. It's true that not checking them at all is attractive, but it will give less precise blame when using the recursive call in a dynamically typed context. Maybe we can leverage some ideas from the Threesomes, With and Without Blame paper. |
On an very unscientific benchmark™, for a few non random at all samples™ of small size (between 50 and 100), I roughly get a factor 10 in real time with and without contracts (without means that all contracts are directly disabled in the But memory management is also very naive and the whole interpreter as well as the implementation of contracts is pretty much un-optimized, so maybe we can bring down this factor to something reasonable, even without eliding recursive calls. |
Closing for now, since the proposal as issued initially is unsound. There are probably others sound contract optimizations to make, but let's discuss them on dedicated issues. |
Is your feature request related to a problem? Please describe.
Contracts are nice, but they do incur some runtime cost. There are probably many optimization opportunities, one being the elision of unneeded checks. Currently, every type annotation gives rise to a contract at run-time:
This example is contrived but corresponds to a real use-case: using a type annotation inside a statically context, either to introduce a polymorphic type, to debug a type error, or just as a documenting annotation for a subterm.
In that case, the contract should be useless, since as the annotated sub-term is well-typed, it wouldn't elicit positive blame, and since the context is well-typed, it shouldn't elicit negative blame, assuming type soundness and blame safety.
Describe the solution you'd like
Any annotation in a statically typed block would be erased at run-time. This could be done at program transformation time, since typechecking occurs before, rewriting such
Promise(ty, term)
asterm
directly. If the typing information is still needed later, e.g. for thequery
subcommand, we can introduce a new node in the AST, which would be the same as a promise during typechecking but would be transparent at run-time. We could also store typing information as meta-values, with more control over which one give rise to a contract or not.The text was updated successfully, but these errors were encountered: