-
Notifications
You must be signed in to change notification settings - Fork 631
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic support for parsing optional arguments in Ltac2 tactic notations #14136
Conversation
e8b12f6
to
5630156
Compare
Personally, I would prefer The syntax for In this way there is no consistency problem, and we decorrelate the optional presence of the attributes with the way the languages in which the tactics are written do represent optional arguments. If we don't like |
@gares you really can't do that, for quite a lot of reasons.
I think I have not repeated that enough during the talk, but the current PR is about Ltac2 notations. Passing arguments to an Ltac2 function should be performed as ML arguments. There seem to be a lasting confusion between static semantics with runtime semantics, the kind of which led to the Ltac1 nonsense... |
The parsing conflict is easy to fix, we already parse The attribute would apply to the head notation as well, eg |
This might be a recipe for disaster, but what you propose Enrico could give a way to have versioned tactics as in:
I think we thought about something like this when discussing how to allow tactics to evolve while maintaining compatibility before. I find it slightly funny to pass options before the tactic itself but we might get used to it... |
I think I don't see attributes as arguments (of a vernac) anymore, but rather as options for it. In a sense, I prefer |
@gares I am really afraid this doesn't make sense at all in the Ltac2 evaluation model. Look at what attributes are used for in OCaml for a reasonable semantics. |
What I propose is fully static, so something escapes to me. What makes them dynamic? (we ruled out HO stuff) |
Yes, maybe there is a misunderstanding here. This syntax shall never allow to do:
|
@gares OK, I might have misunderstood you. So you want to make any Ltac2 notation take an optional attribute and expand it away statically? If so, how are you even going to make any complex parsing rule work? You'll get those nasty attributes in the way of your syntax factorization almost immediately. |
Also, @mattam82 's proposal subsumes yours in this case. It just enforces the fact that all notations must accept this and that the position is restricted to be the leading one, both features which I believe are defeating the purpose of notations. |
Except that IIUC entries are significant in camlp5 so factorization won't happen across different entries, which is the case for vernac vs. Ltac2. We have to hack the grammar to make this work for the various |
I understand you don't like fighting with the parser. I don't either, but if this is the only thing keeping us away from a uniform syntax, I offer my time to make the parsing engine do what we want (I believe it's time well spent). |
Any tactic notation, not just the ones created via ltac2. It is really like the thing we do with the vernacular commands. E.g. in elpi I have a Tactic Extend for |
But Ltac2 notations do not serve the same purpose as TACTIC EXTEND. The former can be used to define mere pieces of syntax, for which attributes do not make sense. Why would you ever write an attribute for the boolean and notation
No, it's not a matter of uniformity nor parser fighting. It's that in general it doesn't make sense (sorry to insist) to ask for an attribute without completely breaking the point of the notation. Once again, pick the boolean and notation and consider the fact that if ever you were to add an attribute somewhere it would completely break the associativity / precedence of that rule. Why don't you trust the user to let him put attributes where it makes sense instead of imposing a parsing rule that is useless in 99% of the cases? |
I think there is a basic misunderstanding stemming from the semantics attached to attributes. While I understand that we would like to use attributes for general treatment of options for vernac commands (Elpi/Equations/Definition/Function...) I also side with @ppedrot that for tactic notations, we don't need to restrict ourselves to having a prefix |
The syntax of attributes is dumb and open so that we can pass to all commands options without hacking the parser. I think it serves this purpose very well. Here it seems one has to define a specific notation for each tactic he wants to get options to. So the point about being generic seems moot. Moreover, in the running example, there is already an optional argument, the "with db" one. I frankly don't see why the others can't be a key value pairs that follow it, eg I'm sorry, but It still looks like a hack to me. |
One point in favor of reusing the generic attribute syntax: most attributes (though not all) amount to locally setting some option (and some even have a corresponding option that can be set globally). The obvious semantics of That being said, the current proposal still satisfies my initial request which was to avoid syntactic explosion when tactics take many arguments. It satisfies the two important characteristics that the attributes / optional arguments are well parenthesized (so no risk to confuse them with term arguments or any other syntactic part of the tactic) and that the attributes / arguments can be passed in any order. |
I think this is totally possible even with About confusing them with the other arguments, it goes both ways IMO. |
You still need delimiters to work around the fact that people may randomly register keywords. |
I don't think the problem with keywords has anything to do with delimiters
|
But the fix, yes. If you have a delimiter you can basically use an unlimited amount of lookahead to disregard to ident / token difference and roll up your own well-delimited parser for this grammar. |
Just always put the attributes first. |
|
OK, this discussion is going nowhere. I don't like this new syntax and I don't see what it unblocks. At the call Cyril did not like it either because it inconsistent with a very similar syntax we already have. If you think this design is good enough, go ahead, I won't question further. |
Well, I get your point about consistency, and I didn't think of the traditional keyword |
Yes. See my last post. |
FTR, since we are likely to have a tactic in Elpi which will go "in production" soon, I did push the integration of Elpi-written tactics a bit further, as for command, so that one does not have to write "elpi tactic" to run it, but just "tactic". In passing, I tries to add support for attributes (as I did for commands). As you can see, even without modifing Coq the results is quite OK, and the only problem/conflict would vanish (I'll prepare a PR for Coq shortly). Here the doc I wrote:
So, maybe Ltac2 tactic notations are a very different beast, for for ltac1 tactics attributes seem to work fine. |
@ppedrot what do you answer to @gares' proposal? It is delimited, and similar to commands. We just need to put an optional #[ ] delimited attribute list before every tactic call, basically implementing the proposed notation in the grammar. |
More urgently, we need this for 13942 that fixes a number of annoying bugs. |
@mattam82 this. does. not. make. sense. |
I think we should synchronize for a visio on the topic, btw. There seems to be some fundamental misunderstandings goin on. |
5630156
to
eb30833
Compare
It makes sense to me. Sadly we have a parsing conflict with commands because the parser does not change when in proof mode, otherwise I don't see the issue with having |
@gares do you have time to discuss this this week? |
This opt-in proposal has nothing to do with uniformly adding an attribute in front of every single notation, thereby utterly destroying the interest of the notation. We're back to square one because this was the original proposal of the PR. I'm a bit tired to repeat myself here, so I'll wait for the synchronization point before commenting further. |
Ok, I guess I see your point. You would prefer it if attributes stayed opt-in then? People could parse them anywhere in their notations but I guess it does not do much harm. This PR implements that, not a uniform addition over every notation. The only remaining issue is the conflict with the uniform |
I just saw this PR today. Some thoughts in brief:
I might join you if my participation is welcome and if the meeting can be scheduled at a reasonable time for me, say 5 PM or later Paris time. Any day of the week is fine. (I would need to know when a meeting will take place, say, 12 or more hours in advance.) |
We do have a coq call tomorrow, maybe 4:30 pm Paris time would be okish? |
I won't be around tomorrow unfortunately :/ |
The "needs: rebase" label was set more than 30 days ago. If the PR is not rebased in 30 days, it will be automatically closed. |
This PR was not rebased after 30 days despite the warning, it is now closed. |
This PR adds a new scope
attributes
(which could also be calledoptions
, but reuses the genric s-expr structure of attributes) for Ltac2 notations and an API to consume attribute declarations (hiding the ADT but letting users access most of the functionality). Right now they are parsed using@[ attribute_list ]
so one can write tactic notations like:After talking with PMP, this seems like a more lightweight solution than generally extending Ltac2's type system with optional arguments. It also stays at the parsing level, so we don't need to do much at the ML level really. The solution using (delimited) attributes also avoids any potential headache with factorization of rules or crazy GADTs to have a generic mechanism in ML to parse options in any order while writing type-safe code.
Kind: feature / infrastructure.
There is a bit of Ltac2 code used to generically parse flags/options but this is all user customizable: we have more or less access to the raw sexprs of attributes, as in the vernac level.
https://github.com/coq/coq/blob/master/dev/ci/user-overlays/README.md for details)