Julia: Feature Request ".." operator to broadcast field access

Created on 5 Aug 2019  路  7Comments  路  Source: JuliaLang/julia

For class MyClass.MyMember
And ArrayofMyClass = [ Instance1, Instance2 ... ]

Can we have:
ArrayofMyClass..MyMember = [ Instance1.MyMember, Instance2.MyMember ... ]

Combining the standard "." for object member and Julia "." for vectorising an operator.

broadcast speculative

Most helpful comment

It also just violates the general principle of "don't conflate scalar operations with their vectorized forms" which is the mess we originally inherited from slower languages that need to do that. Let's not make that mistake all over again.

All 7 comments

We currently allow .. to be used as a user- or package-defined operator, which has led to its use in things like Interval arithmetic, EllipsisNotation, and more. So unfortunately changing this would be quite breaking. There's also a competing proposal in https://github.com/JuliaLang/julia/issues/20502 for nested broadcast.

I could have sworn we had an issue for this, but it looks like we just brought it up in the comments of https://github.com/JuliaLang/julia/issues/19169#issuecomment-257475800.

Another idea is to have a clojure-ish synax (.a) meaning x -> x.a. But of course _.a is pretty much just as good.

What about overloading the "." operator and just use x.a
ie, x.a = [x[1].a x[2].a .... ] if x is an array.

Unfortunately, that's not possible because it's ambiguous if you're doing access on the array itself or its elements. Array itself doesn't have any Julia-accessible fields, but other arrays may. Here's a good example 鈥斅爎anges are arrays that have fields, and Dates are elements that have fields. In this case the names are distinct, but it's entirely possible that some other element type might happen to use the same field names.

julia> using Dates

julia> r = now():Day(1):now()+Day(2)
2019-08-06T12:58:14.878:1 day:2019-08-08T12:58:14.878

julia> r.start
2019-08-06T12:58:14.878

julia> r[1].instant
Dates.UTInstant{Millisecond}(63700779494878 milliseconds)

julia> map(x->x.instant, r)
3-element Array{Dates.UTInstant{Millisecond},1}:
 Dates.UTInstant{Millisecond}(63700779494878 milliseconds)
 Dates.UTInstant{Millisecond}(63700865894878 milliseconds)
 Dates.UTInstant{Millisecond}(63700952294878 milliseconds)

It also just violates the general principle of "don't conflate scalar operations with their vectorized forms" which is the mess we originally inherited from slower languages that need to do that. Let's not make that mistake all over again.

With #24990 or similar, you could do (_.a).(myarray) or myarray .|> _.a

It also just violates the general principle of "don't conflate scalar operations with their vectorized forms" which is the mess we originally inherited from slower languages that need to do that. Let's not make that mistake all over again.

But this principle is far from uniform across widely-used julia packages. E.g. one can represent a "table" either as a dataframe, or as an array of named tuples. For a dataframe-table extracting a specific field of each row is easy: df[!, :field_name]; for a named tuple array there is no short notation to that, and the official way is getindex.(df, :field_name).

It gets more and more verbose with just one or two additional levels of nesting, e.g. getindex.(getindex.(getindex.(df, :field_name), 3), :inner_field). Compare it with (hypothetical) df..field_name.[3]..inner_field. You can almost get this syntax using the hack from https://discourse.julialang.org/t/neat-way-of-broadcasting-getindex-and-getfield/28706 and inserting a couple of brackets.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mbauman picture mbauman  路  276Comments

JeffBezanson picture JeffBezanson  路  145Comments

StefanKarpinski picture StefanKarpinski  路  113Comments

StefanKarpinski picture StefanKarpinski  路  166Comments

StefanKarpinski picture StefanKarpinski  路  249Comments