Join Nostr
2025-04-27 17:44:48 UTC
in reply to

Zhixuan Yang on Nostr: (As usual in the discussion of problems of this kind, it's better to talk about ...

(As usual in the discussion of problems of this kind, it's better to talk about mathematically specific programming languages/type theories instead of Haskell/OCaml/Agda.)

In call-by-value languages, for every type τ, we actually have two different things in the language: (1) values of type τ and (2) computations of type τ. Only values can substitute variables of type τ, and if the language has recursion (or some computational effects), only computations support recursion/effects. Now coming back to inductive data types, because general recursion is not allowed on values, so we don't have to (and shouldn't) include infinite values as _values_ of inductive types. General recursion only forces us to include infinite/divergent computations as _computations_ of inductive types. We can of course separately have coinductive types, whose _values_ have infinite values.

Paul Levy's work on call-by-push-value answers questions like this extremely clearly. I highly recommend checking out the first chapters of this CBPV book. (A while ago I think I saw on mastodon that someone said CBPV isn't about computational effects. I was quite surprised because CBPV is totally about computational effects...)