I've been looking into the implementations of CIC-based theorem provers - mainly Coq and Lean - and it seems that both of them have let binders as part of the kernel, with their own typing and reduction rules.
I get why let binders are useful, but it seems to me they could just be syntactic sugar:
let x:T = y in z --> (fun x:T, z)(y) Is there a type-theoretic reason they're in the kernel as a separate concept, or is it for implementation/software efficiency reasons?
letis not derivable as syntactic sugar in type theory. That only works if types cannot depend onlet-defined names. For example, trying to desugarlet A : Set = Bool in λ (x : A). not xyields(λ (A : Set) (x : A). not x) Boolwhich is ill-typed.We can either add
letto core syntax, or unfold alllet-s during elaboration. The latter may cause a size explosion in elaboration output, andlet-s are very useful in the surface language, so the straightforward solution is to haveletas primitive.