<p>This is a tough question to answer, since simplicity is in the eye of the beholder.</p>

<p>Certainly $\lambda$-encodings have their drawbacks, there are reasons why Coq decided to move away from them, the most obvious one is the inability to introspect the subterms during recursion. The second is the general awkwardness in defining deeply or mutually recursive functions.</p>

<p>As you note, the "fix-encoding" avoids this but then it is hard to define non-constant functions (which is the point Damiano brings up)! You have to choose: introspection or recursion. Often we want both.</p>

<p>I'm also a bit skeptical of Gabriel's proposal: how does he compute exponentials on "native" <code>int</code>s without recursion?</p>

<p>In addition, the fact that EAL can only express elementary functions seems intuitively like it should restrict "natural" ways of writing recursions. In particular this shouldn't be well-defined:</p>

<p><code>Fixpoint acker m := match m with
| O =&gt; S
| S m =&gt; (fix acker' f n := match n with
    | O =&gt; f 1
    | S n =&gt; f (acker' f n)
    end)
   (acker m)
end.</code></p>

<p>since it defines a non-elementary function. So what feature of EAL is preventing this definition? If I understand correctly (and I'm not sure I do), the term <code>f (acker' f n)</code> cannot be well-typed, there must be some "stratum" which prevents the final application of <code>f</code>.</p>

<p>So certainly the natural way to write this function is forbidden. What other natural things are forbidden in this framework? It's hard to say without asking a specialist, but my guess is that there will be a fair number of things. Linear type systems can be powerful frameworks, but they aren't very convenient or natural for writing programs.</p>

<p>It's also an important fact (but maybe this is asking for a lot) that $0\neq 1$ is directly provable in Coq, thanks to large elimination. Is adding this feature easy in your proposal?</p>

<p>Finally, there's something I'm always worried about when I hear about type systems with linear logic: how hard is it to write a type checker? Certainly the checker has to figure out which pieces of the context go where when performing checking. Also the user or the front-end has to figure out where to put all the <code>!</code>s, if you want to have any non-linear components (and you usually do!).</p>

<p>To summarize, my answer to the question "is EAL with dependent types simple, consistent and expressive?" is <strong>probably not</strong>: it is probably consistent, but I'm not sure it's simple, and I don't think it is sufficiently expressive.</p>

<p><strong>However</strong>, there is a "simple" way to refute this claim: write down the system definition, ideally prove it consistent, and write down some simple functions using it, probably up to, say, red-black trees or something. If the fully detailed syntax and typing rules is large, then the system is complex, if it is very tough to write down the functions, then it is insufficiently expressive. If it is neither of those, then you've answered a tough open problem in type theory!</p>

CC BY-SA 3.0
2017-07-26T18:33:52.087Z
Amazing answer, thank you! So, I guess you're fairly sure that if I follow your challenge I'll end up with either complex typing rules or an inexpressive system, but still think it is worth trying nether less if only for the learning opportunity, right?
MaiaVictor
CC BY-SA 3.0
2017-07-26T20:44:56.223Z
Absolutely! In addition, even if the system ends up being complex and hard to work with, I think there is legitimate interest in understanding how to work with it, from the point of view of programing (linear types as resource) as well as logic (reverse mathematics and such).
cody
CC BY-SA 3.0
2017-07-26T18:23:10.193Z
2017-07-26T18:23:10.193Z
cody
<p>I have recently asked if <a href="https://cstheory.stackexchange.com/questions/38087/are-there-simple-core-languages-which-are-consistent-and-expressive">there is a simple functional core that is consistent and expressive</a>. In another question, <a href="https://cs.stackexchange.com/questions/49638/do-self-types-make-the-calculus-of-inductive-constructions-obsolete/49959#49959">cody</a> pointed out that this is an open problem to have a language that is:</p>

<ul>
<li><p>Consistent/Normalizing</p></li>
<li><p>Can express all the type families from Coq (or even Agda)</p></li>
<li><p>Allows for a simple expression of recursion over these families</p></li>
<li><p>Simple or has a small number of core constructions (Π,Σ,μΠ,Σ,μ).</p></li>
</ul>

<p>Now, suppose we take the elementary affine logic and extend it with dependent types and <code>fix</code>. It is easy to prove that language is consistent and normalizing as a consequence of EAL. It can, I believe, express all the type families from Coq, with lambda-encodings and since it has <code>fix</code>. A simple expression of recursive algorithms is possible with church-encodings for iteration and scott-encodings for matching. And it is obviously simple, as it only has <code>∀</code>, <code>!</code> and <code>let</code>. Moreover, such language would have the very comforting property that it can be reduced optimally using the abstract fragment of Lamping's algorithm.</p>

<p>All things considered, such language looks like a perfect candidate for the role of a small functional core that serves as an universal code-interchange format, <a href="http://www.haskellforall.com/2014/09/morte-intermediate-language-for-super.html" rel="nofollow noreferrer">as proposed by Gabriel</a>. Is my suspicion correct, or is there any problem with this reasoning?</p>

CC BY-SA 3.0
2017-07-26T17:40:56.303Z
Is it actually easy to prove that the language is consistent and normalizing?
cody
CC BY-SA 3.0
2017-07-26T17:46:41.020Z
@cody is that a rhetorical question? I'm not sure, but I took that info from this answer: https://cstheory.stackexchange.com/questions/36767/can-elementary-affine-logic-be-used-as-the-core-type-system-of-a-practical-progr
MaiaVictor
CC BY-SA 3.0
2017-07-26T17:48:03.187Z
@cody note that I don't agree with Damiano's point that it'd not be natural. It'd be just different. You can use the Scott-Encoding for pattern matching terms that you don't know the length, and the Church-Encoding to express recursive algorithms naturally. A combination of both would allow you to express many things in very simple manners.
MaiaVictor
CC BY-SA 3.0
2017-07-26T18:23:43.350Z
The question was not rhetorical, I understand better thanks to your reference.
cody
CC BY-SA 4.0
2018-07-11T17:44:04.373Z
I read some of your thoughts bout Scott encoding on Morte and the type for natural numbers you propose is `Nat = fix self . (Nat : *) -> (self -> Nat) -> Nat -> Nat`. While this encoding captures pattern matching, it doesn't capture recursion. To allow recursion with pattern matching you need term level fixed points or a more complex machinery (mutually recursive definitions) as the paper on self types says.
user3368561
<type-theory><lambda-calculus><functional-programming>
Wouldn't the calculus of constructions with linear types be a simple functional core that is consistent and expressive?
MaiaVictor
# Wouldn't the calculus of constructions with linear types be a simple functional core that is consistent and expressive?

(Asked by: username_0 on 2017-07-26)

I have recently asked if [there is a simple functional core that is consistent and expressive](https://cstheory.stackexchange.com/questions/38087/are-there-simple-core-languages-which-are-consistent-and-expressive). In another question, [cody](https://cs.stackexchange.com/questions/49638/do-self-types-make-the-calculus-of-inductive-constructions-obsolete/49959#49959) pointed out that this is an open problem to have a language that is:

* Consistent/Normalizing
* Can express all the type families from Coq (or even Agda)
* Allows for a simple expression of recursion over these families
* Simple or has a small number of core constructions (Π,Σ,μΠ,Σ,μ).

Now, suppose we take the elementary affine logic and extend it with dependent types and `fix`. It is easy to prove that language is consistent and normalizing as a consequence of EAL. It can, I believe, express all the type families from Coq, with lambda-encodings and since it has `fix`. A simple expression of recursive algorithms is possible with church-encodings for iteration and scott-encodings for matching. And it is obviously simple, as it only has `∀`, `!` and `let`. Moreover, such language would have the very comforting property that it can be reduced optimally using the abstract fragment of Lamping's algorithm.

All things considered, such language looks like a perfect candidate for the role of a small functional core that serves as an universal code-interchange format, [as proposed by Gabriel](http://www.haskellforall.com/2014/09/morte-intermediate-language-for-super.html). Is my suspicion correct, or is there any problem with this reasoning?

**Tags:** type-theory, lambda-calculus, functional-programming
> **Comments:**
> **username_1**: Is it actually easy to prove that the language is consistent and normalizing?  
> **username_0**: @cody is that a rhetorical question? I'm not sure, but I took that info from this answer: https://cstheory.stackexchange.com/questions/36767/can-elementary-affine-logic-be-used-as-the-core-type-system-of-a-practical-progr  
> **username_0**: @cody note that I don't agree with Damiano's point that it'd not be natural. It'd be just different. You can use the Scott-Encoding for pattern matching terms that you don't know the length, and the Church-Encoding to express recursive algorithms naturally. A combination of both would allow you to express many things in very simple manners.  
> **username_1**: The question was not rhetorical, I understand better thanks to your reference.  
> **username_2**: I read some of your thoughts bout Scott encoding on Morte and the type for natural numbers you propose is `Nat = fix self . (Nat : *) -> (self -> Nat) -> Nat -> Nat`. While this encoding captures pattern matching, it doesn't capture recursion. To allow recursion with pattern matching you need term level fixed points or a more complex machinery (mutually recursive definitions) as the paper on self types says.  

---

## 1 answers

### Answer by username_1 on 2017-07-26. Score: 2 | Accepted answer

This is a tough question to answer, since simplicity is in the eye of the beholder.

Certainly $\lambda$-encodings have their drawbacks, there are reasons why Coq decided to move away from them, the most obvious one is the inability to introspect the subterms during recursion. The second is the general awkwardness in defining deeply or mutually recursive functions.

As you note, the "fix-encoding" avoids this but then it is hard to define non-constant functions (which is the point Damiano brings up)! You have to choose: introspection or recursion. Often we want both.

I'm also a bit skeptical of Gabriel's proposal: how does he compute exponentials on "native" `int`s without recursion?

In addition, the fact that EAL can only express elementary functions seems intuitively like it should restrict "natural" ways of writing recursions. In particular this shouldn't be well-defined:

`Fixpoint acker m := match m with
| O => S
| S m => (fix acker' f n := match n with
| O => f 1
| S n => f (acker' f n)
end)
(acker m)
end.`

since it defines a non-elementary function. So what feature of EAL is preventing this definition? If I understand correctly (and I'm not sure I do), the term `f (acker' f n)` cannot be well-typed, there must be some "stratum" which prevents the final application of `f`.

So certainly the natural way to write this function is forbidden. What other natural things are forbidden in this framework? It's hard to say without asking a specialist, but my guess is that there will be a fair number of things. Linear type systems can be powerful frameworks, but they aren't very convenient or natural for writing programs.

It's also an important fact (but maybe this is asking for a lot) that $0\neq 1$ is directly provable in Coq, thanks to large elimination. Is adding this feature easy in your proposal?

Finally, there's something I'm always worried about when I hear about type systems with linear logic: how hard is it to write a type checker? Certainly the checker has to figure out which pieces of the context go where when performing checking. Also the user or the front-end has to figure out where to put all the `!`s, if you want to have any non-linear components (and you usually do!).

To summarize, my answer to the question "is EAL with dependent types simple, consistent and expressive?" is **probably not**: it is probably consistent, but I'm not sure it's simple, and I don't think it is sufficiently expressive.

**However**, there is a "simple" way to refute this claim: write down the system definition, ideally prove it consistent, and write down some simple functions using it, probably up to, say, red-black trees or something. If the fully detailed syntax and typing rules is large, then the system is complex, if it is very tough to write down the functions, then it is insufficiently expressive. If it is neither of those, then you've answered a tough open problem in type theory!

> **Comments:**
> **username_0**: Amazing answer, thank you! So, I guess you're fairly sure that if I follow your challenge I'll end up with either complex typing rules or an inexpressive system, but still think it is worth trying nether less if only for the learning opportunity, right?  
> **username_1**: Absolutely! In addition, even if the system ends up being complex and hard to work with, I think there is legitimate interest in understanding how to work with it, from the point of view of programing (linear types as resource) as well as logic (reverse mathematics and such).  

---

