-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Indexing is function evaluation: f[A,B,C]
for orthogonal broadcasts
#40295
Conversation
👍: we should also switch to |
## [Function calls with orthogonal indexing](@id man-orthogonal-functions) | ||
|
||
Just as indexing into an array computes the orthogonal (cartesian) product of the indices to | ||
evaluate for [non scalar indexing](@ref man-indexing), the indexing syntax `f[A, B, C...]` may |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
evaluate for [non scalar indexing](@ref man-indexing), the indexing syntax `f[A, B, C...]` may | |
evaluate for [non scalar indexing](@ref man-array-indexing), the indexing syntax `f[A, B, C...]` may |
Hey, guys/gals, don't make fun of me... https://gist.github.com/mschauer/b04e000e9d0963e40058 !? |
Lines 19 to 20 in 8a931b6
It is truly amazing that such a simple definition introduces a very useful programming tool! ...But, I think it's better to avoid dispatching on the In Julia, anything can potentially define a call overload and so anything can act like a function. With this patch, we can't simply explain that I think a cleaner solution is to add a new (postfix) syntax, just like the usual broadcasting works. This way, we can reason about how the program works (more or less) syntactically. |
I have the same concern as @tkf (and think I also think this is weird: julia> Base.getindex(f::Function, args...) = broadcast(Base.splat(f), Iterators.product(args...))
julia> string["hey"]
3-element Vector{String}:
"h"
"e"
"y" Perhaps any extra verbosity defeats the purpose, and it requires choosing a name, but I would prefer a design like julia> struct Shim{F}
f::F
end
julia> Base.getindex(s::Shim, args...) = broadcast(Base.splat(s.f), Iterators.product(args...))
julia> Shim(cos)[0]
1.0 I think the last line looks so much less weird than julia> cos[0]
1.0 I know we don't have formal interfaces in julia, but I also think this does not seem like |
Shoot, looks like a quaint US tradition doesn't translate well across cultures, my sincerest apologies to everyone who took this seriously. I am not serious here. |
I filled the date as "April Fools, 2021" on a form today and I have to say, you still got me. Thanks for the fun! (but we really should get rid of |
f[A, B, Cs...]
can now be used to evaluate the functionf
over the cartesian product of the argumentsA, B, Cs...
akinto how indexing behaves.
Long have we wanted the ability to broadcast over orthogonal (Cartesian) products of the arguments, and while we've thought about making indexing behave more like broadcasting, it somehow never occurred to us that we should go the other way! This PR implements
f[A,B,C]
to evaluatef
in the manner that indexing would index (with APL-style dim-sum Cartesian products)!For example, we can create the times table quite simply:
But of course we're not limited to arrays of integers or even numbers:
In this case, broadcasting would be especially awkward since we can't use
["foo"]'
.Indexing is the one real API. Let's use it everywhere.