Julia: RFC: make macros bind tighter than commas

Created on 5 Jul 2020  路  8Comments  路  Source: JuliaLang/julia

Currently, we have that @foo a, b, c parses as @foo((a, b, c)) which seems sensible enough, but it's a major source of frustration when you have a macro inside a function's arguments. As a concrete example, consider a very simple underscore anonymous function macro that would take @_ f(_) + 1 and turn it into x -> f(x) + 1. With the current parsing of macros, if we write

map(@_ f(_) + 1, xs)

this gets parsed as

map(@_((f(_) + 1, xs)))

rather than the desired

map(@_(f(_) + 1), xs)

I'm wondering if anyone has a feeling for how disruptive it would be to change this in 2.0 and if they feel that such a change would be desirable. I'm not sure I've ever seen someone write @foo a, b, c where they didn't intend it to mean (@foo(a), b, c), but this could be a reflection of my ignorance.

Is there some deep and useful reason for the current behaviour that I'm missing?

breaking parser

Most helpful comment

If it passes PkgEval, that's strong evidence that it's not likely to break user code. In that case we'd consider it.

All 8 comments

c.c. @c42f, I remember discussing this with you on Slack, but that conversation is now lost beyond the Slack horizon.

I agree this would be great, thanks for taking the time to capture this into an issue. As far as I'm aware there's no compelling reason for the current parsing, and I haven't personally seen anyone relying on it in the wild.

It's a pity that dot(@view A[1:3], B) doesn't just work. Accepting a tuple and an expression @foo (a, b) expr seems useful sometimes, e.g. for @tensoropt. Brackets are not currently required, but I presume they would be, to treat @foo a, b, c differently from @foo (a, b, c). And likewise @foo expr (a, b) differently from @foo expr a, b?

Brackets are not currently required, but I presume they would be, to treat @foo a, b, c differently from @foo (a, b, c). And likewise @foo expr (a, b) differently from @foo expr a, b?

Good points. I think anything that currently is delimited by parens should be unchanged, but I do think @foo expr a, b should become (@foo(expr a), b) rather than @foo(expr, (a, b))

I'd really like this, too. The place where I'd foresee problems is multi-line DSL macros, since the comma could be seen as a way to split macro args over multiple lines without begin or parens.

julia> :(@foo a,
              b,
              c)
:(#= REPL[2]:1 =# @foo (a, b, c))

julia> :(@foo a
              b
              c)
ERROR: syntax: missing comma or ) in argument list
Stacktrace:
 [1] top-level scope at none:1

I suspect this is too breaking to be done in a 1.x release, but I've marked for consideration in 2.0.

Hypothetically, if I or someone else mocked up a PR and we ran PkgEval and showed that it broke no testsuites, would we still consider this too breaking for 1.x just because of the danger to user code?

I can see myself being convinced either way that this either is or isn't acceptable for 1.x even if no testsuites broke.

If it passes PkgEval, that's strong evidence that it's not likely to break user code. In that case we'd consider it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JeffBezanson picture JeffBezanson  路  145Comments

StefanKarpinski picture StefanKarpinski  路  141Comments

JeffBezanson picture JeffBezanson  路  167Comments

juliohm picture juliohm  路  146Comments

shelakel picture shelakel  路  232Comments