lean4-htt/library/init/meta
Leonardo de Moura 261dc999d0 refactor(frontends/lean/elaborator): mark thunk as opaque, and thunk A to A is now a coercion
@kha I was working in the new declaration type and using tasks there.
Since we don't have tasks yet in Lean, I decided to start refactoring
the `thunk` type. I defined it as:

```
-- TODO(Leo): mark as opaque, it is implemented by the new runtime
structure thunk (α : Type u) : Type u :=
(fn : unit → α)

def thunk.pure {α : Type u} (a : α) : thunk α :=
⟨λ _, a⟩

def thunk.get {α : Type u} (t : thunk α) : α :=
t.fn ()
```

The idea is to use the runtime primitives to implement them.
Then, I realized the support for `thunk`s in the elaborator are quite
hacky. Given `f x`, if `f`'s domain has type `thunk A`, we elaborate
`f x` as `f (fun _, x)` even if `x` has type `thunk A`.
This is quite bad, for example, suppose we have
```
def f (x : thunk A) := ...
```
Then, the following definition is type incorrect.
```
def g (x : thunk A) := f x
```
and we are forced to write
```
def g (x : thunk A) := f (x ())
```
The term `f (x ())` will be elaborated as `f (fun _, x ())` and an
unnecessary closure is created at runtime.

This mechanism inherited from Lean 3 is also incompatible with the
new thunk definition. Given `x : thunk A`, I want to write `x.get`
to retrieve the value instead of `x ()` as in Lean 3.
However, `x.get` expands into the nonsensical `(fun _, x).get`.

So, I decided to view the mapping `A` to `thunk A` as a "coercion".
I used double quotes, because it is a macro instead of a function.
If it were a coercion, then we would be using `thunk.pure` to coerce
values but this is not we want most of the time.
For example, given `f : thunk A -> B` and a term `t : A`, when we write
`f t`, we want it to be converted into `f (fun _, t)` instead of
`f (thunk.pure t)` which would eagerly compute `t`. The transformation
`t` into `fun _, t` is syntactic.
We cannot implement it using type classes. I implemented it as
a hard-coded extra case like the one from `Prop` to `bool`.
We can also add a coercion from `thunk A` to `A` to avoid the `.get`.

That being said, I had a few breakages in the code base since we only
use coercions when the given and expected type do not contain
metavariables.
2018-08-21 15:27:51 -07:00
..
lean refactor(*): create library/init/lean folder 2018-04-27 08:02:40 -07:00
declaration.lean refactor(library/init/lean/declaration): declaration -> constant_info 2018-08-21 09:59:30 -07:00
default.lean chore(library/vm): remove meta rb_map 2018-06-14 17:34:43 -07:00
environment.lean refactor(library/init/lean/declaration): declaration -> constant_info 2018-08-21 09:59:30 -07:00
exceptional.lean refactor(init): init/category ==> init.control 2018-04-27 08:33:08 -07:00
expr.lean chore(library/init/meta): remove level and expr unused functions 2018-06-22 10:54:43 -07:00
format.lean refactor(tests/lean/macro1): move meta type adapters into library 2018-05-17 18:58:33 +02:00
has_reflect.lean chore(library/init): pexpr is now an opaque constant 2018-06-06 09:36:22 -07:00
interaction_monad.lean refactor(init): init/category ==> init.control 2018-04-27 08:33:08 -07:00
interactive.lean refactor(library/init/meta/expr): use lean.expr 2018-06-22 10:29:56 -07:00
interactive_base.lean refactor(library/init/meta/expr): use lean.expr 2018-06-22 10:29:56 -07:00
level.lean chore(library/init/meta): remove level and expr unused functions 2018-06-22 10:54:43 -07:00
name.lean fix(library/init/meta/name): duplicate 2018-06-06 08:47:28 -07:00
options.lean feat(library/init/lean/options): add lean.options 2018-05-18 14:51:40 +02:00
pexpr.lean chore(library/init): pexpr is now an opaque constant 2018-06-06 09:36:22 -07:00
ref.lean chore(library): convert comments to docstrings 2017-06-12 15:17:00 +02:00
tactic.lean refactor(frontends/lean/elaborator): mark thunk as opaque, and thunk A to A is now a coercion 2018-08-21 15:27:51 -07:00
well_founded_tactics.lean chore(library/init): merge sigma/lex.lean with wf.lean 2018-04-30 10:04:03 -07:00