Zulip Chat Archive
Stream: lean4
Topic: Recursive Structures
Mac (Jul 22 2022 at 04:13):
Why is recursion forbidden in structures?
I ran into this limitation again today while refactoring Lake (to make the dependencies of Package
the resolved packages rather than just the declarative specification). Thus, I either need to refactor Package
into an inductive (and lose nice things like the structure syntax) or work around the type system with the via OpaquePackage
. Both seem less than ideal, so I am curious as to the rational behind forbidding recursion.
Mario Carneiro (Jul 22 2022 at 04:40):
Observation: a recursive one-arg constructor supports the anonymous constructor notation, but not foo.1
syntax; however the kernel accepts foo.1
primitive projections:
import Lean
inductive Foo
| mk : Foo → Foo
example (f : Foo) : Foo := f.1 -- failed
open Lean Elab Term
elab "mk_foo" : command =>
addDecl $ .defnDecl {
name := `test
levelParams := []
type := .forallE `x (mkConst ``Foo) (mkConst ``Foo) .default
value := .lam `x (mkConst ``Foo) (.proj ``Foo 0 $ .bvar 0) .default
hints := .opaque
safety := .safe }
mk_foo -- ok
Sebastian Ullrich (Jul 22 2022 at 08:29):
Mac said:
Both seem less than ideal, so I am curious as to the rational behind forbidding recursion.
I think the direct reason is that the structure elaborator does not use the inductive elaborator, so it can only support simple kernel inductive decls. It sounds like you instead want a nested inductive as a structure?
I imagine, without hard evidence, that combining the structure and inductive elaborator would be like putting the two in a particle collider and marveling at the fun bugs resulting from the collision.
Mac (Jul 22 2022 at 08:50):
Sebastian Ullrich said:
so it can only support simple kernel inductive decls. It sounds like you instead want a nested inductive as a structure?
I'm sorry, but my grasp of type theory jargon is not what it should be. What is the difference between a simple inductive and a nested inductive?
Sebastian Ullrich (Jul 22 2022 at 08:55):
If you want something like
structure Package :=
deps : List Package
...
then that is a nested occurrence of Package
inside the inductive type List
. The inductive elaborator has to define Package
as a mutually inductive type together with a specialized copy of List
in this case.
Yuri de Wit (Aug 17 2022 at 18:36):
Thank you, for the link to the previous discussion about this.
Kevin Buzzard (Aug 17 2022 at 19:35):
Maybe use an inductive? Structures are not recursive.
Yuri de Wit (Aug 17 2022 at 20:01):
Yes, that is the approach I am taking but bumping into the nice conveniences (as Mac puts it) of the structure syntax etc that I am missing. For instance, being able to use ..
in pattern matching.
Mario Carneiro (Aug 17 2022 at 23:24):
you should be able to use Value.mk (data := d) ..
as a pattern even if it's an inductive constructor
Last updated: Dec 20 2023 at 11:08 UTC