-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Proposal: keyword argument broadcasting #34737
Comments
Note that this is actually a lowering error rather than a parser error, so you can create a macro which translates this syntax into a broadcasted closure as @mbauman noted on slack: ((x,y)->f(x; kw=y)).([1, 2, 3], [4, 5, 6]) That would allow you to experiment with the syntax and decide whether you like it in practice. Personally I can see why you'd want this syntax and it has a pleasing consistency with the rest of broadcast notation. |
To capture some other insightful things @mbauman noted on slack (rather than letting them disappear into the history):
|
How does this interact with the idea of using |
A lot of codes like this will be broken by then: julia> struct Alg end
julia> function _diff(x, y; method)
x - y
end
_diff (generic function with 1 methods)
julia> X, Y = rand(4, 4), rand(4, 4);
julia> _diff.(X, Y; method=Alg()) # this currently works
# but would throw a MethodError like this by then
ERROR: MethodError: no method matching length(::Alg)
Closest candidates are:
length(::Core.SimpleVector) at essentials.jl:596
length(::Base.MethodList) at reflection.jl:852
length(::Core.MethodTable) at reflection.jl:938 Codes in the wild JuliaGraphics/Colors.jl#338 |
@johnnychen94 I think you misunderstand. This proposal is not to broadcast on all keywords, but to add a syntax to opt-in to broadcasting. Existing code would continue to work as before. |
I didn't know about this syntax proposal yet. Actually I think your version
Yeah I also don't think it's optimal that the Does the old restriction come from the previously lower performance of keyword arguments vs. positional arguments? |
I would consider it to do the same as if kw was a normal positional argument. The dot would simply enable that argument for broadcasting, so it would act like any other positional argument. The other option would of course be to just lift the broadcasting restriction on keyword arguments altogether, but that's too unlikely even for 2.0 with all the breakage it would cause. |
I think of keyword arguments as the "how to process" and the positional args as my "what to process." I find I'm much more likely to broadcast over the whats than the hows, but there are definitely cases where I've wanted the latter. This would make for an interesting bifurcation wherein you could manually choose which kwargs participate in broadcast, but you cannot choose which positional arguments participate. |
I agree, in many cases it is the same for me. But I actually like having keyword constructors for many of my structs because they are more descriptive when you see them in code. In those cases when I want to construct many different structs by keyword constructors, the broadcasting feature is missing.
I don't think that's completely true, people are using |
Sure, to be more clear — it's opt-in whereas positional arguments are opt-out. |
This feels like a bridge too far syntactically. |
This was exactly my first impression and I originally wrote a reply saying so, but then deleted it :-) I feel we've already committed to In general adding |
If the main argument against this is |
I agree with this, that's why I think keyword broadcasting syntax is acceptable. It should be only a minor effort to discern keyword use from variable assignment.
I don't think this looks quite as nice as the other version at first, but this would allow to skip the semicolon, which would be valuable because of its syntactical consistency. So that the same syntax means the same thing left and right of the semicolon. So maybe that would be a good solution!
To me this often revolves around constructors, as one may want to offer several different options of constructing the same object. For example compare these hypothetical constructors: # let's say we have some variables that don't immediately show their
# intended use through their names
ps # some points
rs # some radii
tris # some triangles
lines # some lines
circles = Circle.(center .= ps, radius .= rs)
# vs
circles = Circle.(ps, rs)
circles = Circle.(outer_triangle .= tris)
# vs
circles = Circle.(tris)
circles = Circle.(inner_triangle .= tris)
# vs
circles = Circle.(tris) # collides, so would need an extra method
circles = Circle.(center .= ps, tangent .= lines)
# vs
circles = Circle.(ps, lines) Keywords can help making the intent of code clear, so you don't have to guess whats happening. |
A part of the problem might be that there is no dispatch on keyword arguments |
Very interesting discussion! |
I think I'm inclined for this (if we do it) to uniformly express it by putting the dot in front of the keyword argument name, so |
Currently, broadcasting excludes keyword arguments:
I don't know what the reasoning for this is, and I couldn't find previous issues about this. I often want to broadcast keyword arguments when I create different objects that offer keyword constructors. In these cases, syntactical convenience is often more important than pure performance to me. It would be a breaking change to enable keyword broadcasting without syntactical changes. However, the following syntax is still available:
I propose adding the
.=
keyword syntax in order to pull selected keywords into the broadcasting expression.The text was updated successfully, but these errors were encountered: