tweag / nickel

Better configuration for less

Home Page:https://nickel-lang.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Contract elision for static type annotations

yannham opened this issue · comments

As part of #1622, metrics show that the base used for benchmarks is performing an awful lot of array contract applications and their derived subcontracts, in particular polymorphic contracts. This is probably due to the usage of stdlib functions, which are all typed with a polymorphic type.

Indeed, consider std.record.map, whose type is forall a b. (a -> b) -> Array a -> Array b. If we apply it to a 5000 elements array, this will cause the execution of 20 000 small contracts: one to seal all elements of the array argument with a, one to unseal the same elements when f is applied (corresponding to _a_ -> b), one sealing the result of the application to b (the b in a -> _b_), and finally one that will map the unsealing key over the resulting array.

What's sad is that the function is statically typechecked. Thus, under the assumption that the type system is reasonably behaved (blame safety), the polymorphic contract can never blame. In the same spirit, it's not useful to check anything on the return value of the function: the typechecker already proves that it must be Array b.

I discussed contract elision rules in #285, which is a bit different, but related.

Proposal

Rewrite static types before contract generation to:

  • get rid of polymorphic contracts in positive position
  • get rid of first-order contracts in positive position