lean4-htt/library/init
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
..
control feat(library/init/control/coroutine_io): coroutine_io 2018-08-21 08:43:10 -07:00
data chore(library/init/data/string/basic): rename string.iterator's next_to_string to remaining_to_string 2018-07-05 10:42:37 +02:00
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
meta 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
coe.lean feat(library/init/{io,control/except}): use lift_t to automatically upcast io and other errors 2018-08-21 08:43:09 -07:00
core.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
default.lean refactor(library/system/io): move into init 2018-08-21 08:43:09 -07:00
env_ext.lean doc(library/init/env_ext): document environment extensions in use 2018-05-30 14:28:49 -07:00
function.lean chore(library/init): remove funext and quot modules 2018-04-30 09:25:26 -07:00
init.md chore(*.md): fix/remove broken links 2016-02-23 10:11:24 -08:00
io.lean chore(library/init/io): remove dead code 2018-08-21 09:00:14 -07:00
platform.lean feat(library/vm): add support for system.platform.nbits in the VM 2018-05-03 15:54:54 -07:00
util.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
version.lean.in chore(leanpkg/lean_version): recognize nightlies as releases separate from master 2018-03-20 15:14:45 -07:00
wf.lean feat(kernel/inductive/inductive): dependent elimination for inductive predicates 2018-06-12 13:03:26 -07:00