nim-lang / RFCs

A repository for your Nim proposals.
136 stars 26 forks source link

Change command + `=` syntax #442

Closed metagn closed 1 year ago

metagn commented 2 years ago

Currently this:

foo a = b

parses as this:

foo(a) = b

The proposal is to make this mean (only in statement form):

foo(a = b)

foo a = b, c = d syntax should be an easy outcome of this for a reason explained below.

Reasoning:

This change would definitely break code and macros which use the current syntax. However I genuinely have never seen any code which does, the workaround is simple and all the capabilities of the old syntax seem to be kept. And it can be easily tied to a big, backwards-incompatible release like 2.0.

From what I can think of, this would require some redundancy in the grammar, but there may still be simple ways to include it. It shouldn't cause a giant ambiguity anyway.

Edit: Looking more into the parser, I am changing this proposal to only work in statement form.

Edit: I have found that my own macro library has tests using the old syntax. Thankfully it does nothing more than create an inconsistency with the other macros. It can also easily still support the old invocations. I did not think about how this could affect existing macros rather than just normal code, but AST has been noticeably changed before and in my view no information is lost here.

Edit 2: Old issue about this I didn't see: https://github.com/nim-lang/Nim/issues/15050

mratsim commented 2 years ago

That would break the rule "unary binds stronger than binary". It's an easy enough rule to remember, I'm not sure the exception is worth it. And later all parsing/syntax highlighting packages need to be updated.

metagn commented 2 years ago

That would break the rule "unary binds stronger than binary".

But that rule already doesn't apply for a b + c, or even a b += c or a b := c. = is the exception here.

And later all parsing/syntax highlighting packages need to be updated.

I doubt they parse this correctly already. Even if they didn't, I don't think they would break that much. But yes, this is a breaking change overall.

Araq commented 2 years ago

I like the idea.

c-blake commented 2 years ago

It may be worth observing here that named arguments already work for non-first params:

proc foo(x: int, a=2, b=3) = discard
foo 1, b=2, a=3
metagn commented 2 years ago

Was mentioned but has been included more thoroughly in the proposal. In my opinion that is in favor of the proposed syntax.

c-blake commented 2 years ago

I agree "all arguments working" is a good consistency principle. It took me a while to discover that it worked for non-first args, actually. Sorry if I didn't notice the mention already. It may be the strongest pro-argument here, but I think it would be good for other Nimmers to weigh in.

You may also be interested in what I call "named do" which I think of as closely related - making named parameter passing work in "code block notation" as well as "code expression notation" (which already works). You just need a way to connect the parameter name and foo.do: or do(foo): seem natural fits.