Conversation
f9415d7 to
cf65a51
Compare
|
@jespercockx, are you fine with this change? |
|
I am not sure if I understand the need for this flag, is it just out of principle because we do not (yet) understand it that well or do you have a concrete example of something that goes wrong? In the former case, I think it would be more in line with the Agda philosophy to have the option be enabled by default. |
Mainly because this kind of pattern matching seems to be less well understood. For instance, I have sketched a proof of the statement "
The option is enabled by default, because it is implied by Furthermore I went through some of my code, and only a small part of it depends on this feature. I'd rather not add |
|
I'm still confused, I was under the impression that the semantics of erasure is "it is possible to erase this argument during compilation without changing its results at run-time". If there is no example of a program that violates this principle, then I do not see a reason to disable it. But it seems you have a different semantics in mind of what you mean by "erasure", so we are not talking about the same thing. Perhaps we should make a clear design choice on what kind of erasure we exactly want to have in Agda, so we do not run in this kind of misunderstanding again in the future.
I don't think this is a strong argument anymore since you can add the flag to your agda-lib file. Of course, so can I, so the question is mainly what is less surprising to a "casual" user of Agda who does not necessarily know how to set up an agda-lib file. |
We have not proved that there is no such example.
I'm not sure what you have in mind. However, note that "it is possible to erase this argument during compilation without changing its results at run-time" is rather imprecise. For instance, do you only care about evaluation of closed terms, or also about evaluation of open terms? To take another example, Agda currently does not actually remove all erased arguments (#4193), and this does not work in strict backends. Instead erased arguments are replaced by dummy arguments. If the rules for erasure were set up differently, then one could perhaps fully erase everything. (In Mishra-Linger's theory erased arguments are removed entirely, and he proves that the erasure of a well-typed term is strongly normalising if you start with a PTS with strong normalisation.)
I have a library in which I want to distinguish code that uses single-constructor matching from code which doesn't, so I can't use I agree that it can be inconvenient to edit |
|
I also fail to see why erased single-constructor-matching for non-indexed data/record types should be problematic in non-cubical/non-univalent type theories, given K or not K.
|
I don't think "no one has found a problem with this yet" is sufficient evidence for the soundness of a feature, and I think that any restrictions that apply when In this case I suspect that the addition of this flag would be rather undisruptive, because I suspect that most of the Agda code that uses erasure is written by me or people using agda2hs together with A concrete benefit of having this flag, and turning the feature off by default, is that you do not need to mention the feature at all when writing a paper about code that does not use the feature. If the feature is on by default, then an author might feel compelled to mention explicitly in a paper that the feature was turned off. |
If we go by this argument, we should disable Agda's induction-recursion as well, because no one has proven it sound. |
I believe I do make use of the single-constructor matching feature in my experiments, but that's really all they are (experiments) and I would not mind much to roll back the addition of |
"Compiling Programs with Erased Univalence" contains sketched proofs suggesting that a simplified type theory that is based on what you get with
I think it would be a good idea to make it possible to turn off induction-recursion, as well as other things. However, turning off induction-recursion would break a lot of code, so the default should perhaps be "on". Turning off single-constructor matching would presumably not break a lot of code, so then the default could be "off". Note also that if you do make use of single-constructor matching without having turned on the feature, then you get an error message like the following one: Thus the option is easy to discover. If a feature like this is on by default, then I suspect that it will typically be used even in developments that do not depend on the feature. In this case I did not need to update the standard library, which does not use the feature. However, if the feature had been on by default, then I would have had to turn it off in the standard library. I think we should make it easy to make reusable code, so the defaults for new features should be "off", if possible. |
|
One other consideration: perhaps the flag should use |
|
Nisse persuaded me that this flag makes sense, since it distinguishes between different intepretations of the But I also propose a name change for the flag. It should definitely refer to erasure. How about |
|
I plan to add |
In that case, should |
|
I implemented |
Language wise, Otherwise, I could imagine the format |
Yes, we also have
I don't agree: the flag does not enable matching on erased constructors, but on erased arguments. Is |
|
@nad can this be merged now? I've been convinced that it's probably a good idea to add the flag. |
I implemented this before we reverted (a698313) the change that made parameters non-erased in the types of constructors and projections (for some types). When We should also decide what the single-constructor matching flag should be called. |
I tried to fix this. |
|
If this pull request is merged in its current state, then What is the purpose of
What do you think? |
|
There's no real purpose, I just thought it was good practice to always have a negation for each flag. |
Previously it implied --erasure.
Do you think it should be possible to turn on |
The current implementation uses
Perhaps |
|
A concrete use case for (something like) {-# OPTIONS --safe --without-K --erasure --erased-matches #-}
open import Agda.Builtin.Nat
data Unit : Set where
unit : Unit
block : {A : Set} → @0 Unit → A → A
block unit x = x
module _ (@0 x : Unit) where
stuck : Nat
stuck = block x 12 |
See #6349.