Underscores.jl
Underscores.jl copied to clipboard
Audit _ expansion rules to only expand into "things which look like function calls"
We've had a couple of specific cases where _ expansion is confusing - opened in #6 and #8 and solved by #10.
But because #10 is breaking, I'd like to make sure we have a single consistent-as-possible syntax rule before the next release. Something like:
_expands to a closure which is passed to the outermost "thing which looks like a function call"
See #6 and #8 for extensive discussion.
One question is what to do with macros, it seems that this should work, since it doesn't look like a function call:
@_ data |> @view map(_.re, __)[1:3]
but as you mentioned in #8, sometimes you will need brackets:
a |> @m b |> c # parsed as a |> @m(b |> c)
Would it be crazy for @_ to re-organise such things to a |> (@m b) |> c?
Would it be crazy for
@_to re-organise such things toa |> (@m b) |> c?
I think it's a bit dangerous to second guess the language parsing rules, I think it will lead to irregularities and surprises in the longer term.
For example, the user could write this as a |> @m(b |> c) and they'll be quite surprised when we rearrange the whole thing :-)
An interesting case from https://github.com/c42f/Underscores.jl/issues/18#issuecomment-683570078 which I agree should work.
julia> any(>(3), 1:4) ? "yes" : "no"
"yes"
julia> @_ any(_>3, 1:4) ? "yes" : "no"
ERROR: TypeError: non-boolean (var"#13#14") used in boolean context
Note that such examples won't work very well in pipelines -- I'm unsurprised by (0 |> string) here but was a little surprised by (data |> cond):
julia> :(data |> if any(_,__) 1 else 0 end |> string) |> Meta.show_sexpr
(:call, :|>, (:call, :|>, :data, (:if, (:call, :any, :_, :__), (:block,
:(#= REPL[14]:1 =#),
1
), (:block,
:(#= REPL[14]:1 =#),
0
))), :string)
julia> :(data |> any(_,__) ? 1 : 0 |> string) |> Meta.show_sexpr
(:if, (:call, :|>, :data, (:call, :any, :_, :__)), 1, (:call, :|>, 0, :string))