# Feature request: implicit use of struct member

**URL:** <https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295>\
**Category:** Internals & Design\
**Created:** [January 11, 2018, 5:53pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295 "2018-01-11T17:53:32Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![TravisA9](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/travisa9/32/357_2.png) [@TravisA9](https://discourse.julialang.org/u/TravisA9)\
**Post date:** [January 11, 2018, 5:53pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/1 "2018-01-11T17:53:32Z")

</div>

In the spirit of keeping code clean and terse I think it would be great to be able to implicitly use (reference) a ‘special’ member of a `struct`. My apologies if this is already an existing feature that I have overlooked (don’t think so though).

Consider an example. Let’s say I have something like this:

```julia
mutable struct Layer
    layer::Array{Int64,2}
    res::Array{Int64,2}
    back::Function
    forward::Function
end

```

Then, within functions using `Layers` you might find a few references to the various members but many references to:

```julia
# Assume 'layers' is a previously defined 'Vector' of 'Layer'
layers[x].layer # long clunky reference

# let's shorten it...
l = layers # line needlessly wasted just to shorten expression
l[x].layer # Still ugly ...who knows how many times this will be repeated throughout our code

```

Sure, the later is better than the first but can we do better?  
_I don’t want to get in to recommending any specifics on the syntax but_ …What if I could omit `.layer` for all references? I think it would be very convenient to make that member anonymous. Other members would have to be specified in the normal way.

What it might look like in practice:

```julia
mutable struct Layer
    Array{Int64,2} # To specify we want anonymous/implicit data of this type
    res::Array{Int64,2}
    back::Function
    forward::Function
end

# Create Layer()
julia> layer = Layer(d, σ, δ) # We are obviously not assigning to an anonymous member ..we are creating the struct 

julia> layer = [1 2 3; 4 5 6; 7 8 9] # Assign data to the (now existing) anonymous member of layer

julia> layer[1,2] # access data
2

```

One might expect the criticism that anonymous members make the code less clear but **I would instead argue that it avoids redundancy**. Notice that `layers[x]` is a layer and then we add a dot and say layer again!?! This seems to be quite common. Another way I’ve seen this issue in code in the wild is with member names such as `data`. Well, yes! …of course it’s data! It’s all data, so why use that word? The obvious answer is that generally most languages require every member to have a name. But why should it have to have a name if it is given one on creation? That is where redundancy is generated.

As an example I’ve seen things similar this:

```julia
mutable struct MyFileFormat
    data::Array{Int64,2} # To specify we want anonymous/implicit data of this type
    length # other arbitrary pieces of data
    ...
end

MyFile = MyFileFormat( ... )

# Since the data is the whole point of this. The data is the file!
# why should I have to redundantly specify it?
MyFile.data[] # Not pretty :(

MyFile[] # Better :)

```

I’m looking forward to hearing peoples’ thoughts this idea to see if it’s feasable.

😁 cheers!

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 11, 2018, 6:00pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/2 "2018-01-11T18:00:41Z")

</div>

> [@TravisA9](#):
>
> What if I could omit .layer for all references? I think it would be very convenient to make that member anonymous.

My primary concern would be about readability. One would need to look up non-local information to know that `l[x]` is actually `l[x].layer`.

In case you are treating the fields of a vector as a vector of fields a lot, consider

> **[GitHub - JuliaArrays/StructsOfArrays.jl: Structures of Arrays that behave...](https://github.com/JuliaArrays/StructsOfArrays.jl)**
>
> Structures of Arrays that behave like Arrays of Structures - GitHub - JuliaArrays/StructsOfArrays.jl: Structures of Arrays that behave like Arrays of Structures

---

<div class="post-metadata">

**Author:** ![TravisA9](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/travisa9/32/357_2.png) [@TravisA9](https://discourse.julialang.org/u/TravisA9)\
**Post date:** [January 11, 2018, 6:08pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/3 "2018-01-11T18:08:18Z")

</div>

@Tamas_Papp I believe, that the need to look up what the struct is (how it is made up) would likely be there either way. In the case that it is an anonymous member or not.

As for readability, I think that’s more of an implementation detail. Consider this:

```julia
layers[x].layer
# Vs

layer[x]

```

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [January 11, 2018, 6:16pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/4 "2018-01-11T18:16:24Z")

</div>

I don’t like this because it makes it very easy to confuse the object itself with some member of it, and to say that’s an important distinction would be understating the matter.

One suggestion would be to define `(l::Layer)() = l.layer`. Probably not quite what you’re looking for, but I can’t really imagine a way to do what I think you are suggesting without introducing syntax in which the aforementioned ambiguity is a problem.

Where I might agree with you is that it might be nice to have a language construct which does something like `getfield.(layers, :layer)` in some nice and readable way which is useful in many different contexts. Perhaps a convenient macro? I don’t have any great ideas off the top of my head about what this might look like.

---

<div class="post-metadata">

**Author:** ![TravisA9](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/travisa9/32/357_2.png) [@TravisA9](https://discourse.julialang.org/u/TravisA9)\
**Post date:** [January 11, 2018, 6:35pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/5 "2018-01-11T18:35:35Z")

</div>

Well @ExpandingMan, “I don’t like it” is a valid criticism since the language should be intuitive and easy for all to use.

As with other features this one could potentially be abused I would hope that it’s benefit would outweigh that risk. That’s certainly up for debate though. Ideally, it would only be used when it contributes to the readability of the code.

I would like to mention one additional observation. You mentioned the distinction between an object and it’s member. I think that your point is in many cases quite valid but perhaps not as much in the examples I gave.

For example, the `layer` **_is_** the `Layer`, conceptually speaking. And the `data` is the `file` in the same sense. The other members could be described as attachments, meta-data, or whatever …and also functions. In this type of situation, I think this method has merit. In fact, it could be compared to an array which has an index and size and so forth but you do not reference the array by a member. You just add brackets to the name and index the data directly.

---

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [January 11, 2018, 6:50pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/6 "2018-01-11T18:50:06Z")

</div>

```julia
julia> mutable struct Layer
           data::Array{Int64,2} # To specify we want anonymous/implicit data of this type
           res::Array{Int64,2}
       end

julia> import Base.setindex!
julia> import Base.getindex

julia> getindex(x::Layer, y...) = x.data[y...];
julia> getindex(x::Layer) = x.data;
julia> function setindex!(x::Layer, y, z...) x.data[z...] = y end;
julia> function setindex!(x::Layer, y) x.data = y end;

```

Part of your request is implemented now:

```julia
julia> l = Layer([1 2 3;4 5 6], [1 1;2 2])
Layer([1 2 3; 4 5 6], [1 1; 2 2])

julia> l[] = [3 4 5;]
1×3 Array{Int64,2}:
 3 4 5

julia> l
Layer([3 4 5], [1 1; 2 2])

julia> l[1,2]
4

julia> l[1,3] = 7
7

julia> l
Layer([3 4 7], [1 1; 2 2])

```

`l = [3 4 5;]` instead of `l[] = [3 4 5;]` is IMO against language design because `l` is variable and has to be rebindable!

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [January 11, 2018, 6:52pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/7 "2018-01-11T18:52:18Z")

</div>

This feature looks exactly like [https://github.com/JuliaLang/julia/issues/9821](https://github.com/JuliaLang/julia/issues/9821) (and has the same problems).

---

<div class="post-metadata">

**Author:** ![ggggggggg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ggggggggg/32/265_2.png) [@ggggggggg](https://discourse.julialang.org/u/ggggggggg)\
**Post date:** [January 11, 2018, 6:58pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/8 "2018-01-11T18:58:42Z")

</div>

I like using the `@delegate` macro hiding in DataSructures for this.

```julia
julia> mutable struct Layer
                  data::Array{Int64,2}
                  res::Array{Int64,2}
              end

julia> using DataStructures

julia> DataStructures.@delegate Layer.data [Base.setindex!,Base.getindex]

```

```julia
julia> l = Layer([1 2 3;4 5 6], [1 1;2 2])
Layer([1 2 3; 4 5 6], [1 1; 2 2])

julia> l[] = [3 4 5;] # doesn't work without additional methods

julia> l
Layer([1 2 3; 4 5 6], [1 1; 2 2])

julia> l[1,2]
2

julia> l[1,3] = 7
7

julia> l
Layer([1 2 7; 4 5 6], [1 1; 2 2])

```

---

<div class="post-metadata">

**Author:** ![jballanc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jballanc/32/328_2.png) [@jballanc](https://discourse.julialang.org/u/jballanc)\
**Post date:** [January 12, 2018, 10:28am UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/9 "2018-01-12T10:28:04Z")

</div>

I don’t have much to add in the way of implementation, but I wanted to point out that this seems awfully close to a request for metadata on a type. That is, it would be nice if you could do something like:

```julia
layers[1] # => returns a Layer
getmeta(layers[1]) # => returns a struct containing fields `res`, `back`, `forward`

```

For what it’s worth, Ruby, Clojure, and Lua all have such a concept.

Actually, thinking about it a bit more, it probably wouldn’t be too difficult to define a macro that simultaneously defines a type and a dictionary keyed by that type that could contain the corresponding metadata…(implementation is left as an exercise for the reader 😉 )

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 12, 2018, 10:44am UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/10 "2018-01-12T10:44:29Z")

</div>

Also, there is `@forward` from [Lazy.jl](https://github.com/MikeInnes/Lazy.jl) for the same purpose.

The fact that there are multiple implementations may be an argument for the usefulness of this feature, and potential inclusion into `Base`.

---

<div class="post-metadata">

**Author:** ![smldis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smldis/32/1735_2.png) [@smldis](https://discourse.julialang.org/u/smldis)\
**Post date:** [January 12, 2018, 2:11pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/11 "2018-01-12T14:11:03Z")

</div>

This look similar to inheritance for me, but looks also like composition. Maybe this is a boundary between them, would it be less fragile than [https://github.com/JuliaLang/julia/issues/9821](https://github.com/JuliaLang/julia/issues/9821) constructing a composition (that gets automatically defined methods) based on classical inheritance rules?

The usecase posted is not really motivating enough without showing an advantage usable by the current ecosystem.

3 Toughts:  
That field would need at least a name/way to get access to it.  
And `layer = [1 2 3; 4 5 6; 7 8 9]` is not well defined since `=` (the assignment) is not overridable in Julia for now and so layer would just be of type `array{Int,2}`.  
The fact that thre are mulitple implementations of this may be also driven by people minds still trying to use inheritance.

---

<div class="post-metadata">

**Author:** ![TravisA9](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/travisa9/32/357_2.png) [@TravisA9](https://discourse.julialang.org/u/TravisA9)\
**Post date:** [January 12, 2018, 5:28pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/12 "2018-01-12T17:28:23Z")

</div>

Looking at this from a slightly different angle, we could **compare it to something that already exists** such as an array (yeah, I kinda’ hinted at this above).

An array in the strictest sense is just an iterable collection of values but in practice there’s a need to associate values with the array to describe its dimentions, location in memory and potentially other details. But we still don’t have to reference the array values with a name, it is annonymous because conceptually the **values are the array** and the other data are just details of implementation. This principal is not unique to arrays.

It would be burdensome/sloppy to have to always reference an array’s values like this:

```julia
MyArray.data[n1, n2] = 3 # :( 

```

But the fact is(correct me if I’m wrong) that an array ussually has more data associated with it than just the set of values

In that case, what I proposed is really just a more versatile implementation of the same principal that is already in use. It would be more versatile because:

- you would’t be restricted to one data type (itterable sets of values).
- it has the potential for making cleaner code.
- a bit less typing.

Think of an image; it has many bits of data associated with it but then there’s the image data …that data is the image. In the case of a .bmp, for example, it may be an array. It seems completely reasonable to me to be able to refer to that data without having to give it a second name.

Although, I’ve given mostly examples associated with arrays I do not mean to imply that the only use case is with arrays.

I do recognize there are both pros and cons to this proposal but I am very intersted in determining if it is feasable. Thanks for all the great comments 🕶

---

<div class="post-metadata">

**Author:** ![jandehaan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jandehaan/32/6805_2.png) [@jandehaan](https://discourse.julialang.org/u/jandehaan)\
**Post date:** [January 12, 2018, 5:53pm UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/13 "2018-01-12T17:53:52Z")

</div>

I really would like a feature like this.  
Everytime I wrap another data type, I find myself implementing all the methods that apply to that other datatype, just so that I can delegate to the wrapped type.  
For example:

> +(x::MyNumber, y::MyNumber) = x.value + y.value  
> +(x::Number , y::MyNumber) = x + y.value  
> +(x::MyNumber, y::Number ) = x.value + y

It would be helpful to have a dispatch mechanism that can dispatch on a data type, while ignoring the function.  
If every call where to go thru something like

> apply(f, xs…)

I could implement a methods like

> apply(f, x::MyNumber) = f(x.value)  
> apply(f, x::MyNumber, y::MyNumber) = f(x.value, y.value)

It would be very similar to the way broadcast works:

> broadcast(f, A…)

which works for any function f and I can write specialized methods for it as needed.

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [January 16, 2018, 4:24am UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/15 "2018-01-16T04:24:29Z")

</div>

> [@ggggggggg](#):
>
> julia\> DataStructures.@delegate Layer.data [Base.setindex!, Base.getindex]

The return value of `setindex!` should be the `Layer` argument, so this delegation would be (slightly) wrong.

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [January 16, 2018, 4:32am UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/16 "2018-01-16T04:32:29Z")

</div>

> [@jandehaan](#):
>
> +(x::MyNumber, y::MyNumber) = x.value + y.value

This is a common request, but in other languages that have class inheritance, it is known as the “fragile base class problem”.

Also, shouldn’t that have a return type of `MyNumber` too:

```julia
+(x::MyNumber, y::MyNumber) = MyNumber(x.value + y.value)

```

(although, in this specific case, you would probably actually define promotion rules instead of the later two methods)  
How would you propose dealing with this problem (of sometimes needing to wrap the return value in some way) in general?

---

<div class="post-metadata">

**Author:** ![jandehaan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jandehaan/32/6805_2.png) [@jandehaan](https://discourse.julialang.org/u/jandehaan)\
**Post date:** [January 16, 2018, 5:32am UTC](https://discourse.julialang.org/t/feature-request-implicit-use-of-struct-member/8295/17 "2018-01-16T05:32:56Z")

</div>

I’ve come to the conclusion that there isn’t an easy solution to this.

I found three major patterns:

- functions like isodd(x::MyNumber) = isodd(x.value)
- functions like abs(x::MyNumber) = MyNumber(abs(x))
- functions like sqrt(x::MyNumber) = (sqrt(MyNumber))(sqrt(x))  
The last one assumes that the function results in a different type of number.

Similar patterns occur when all arguments of n-ary functions are of type MyNumber.  
But it may get more complicated if the arguments are of different type.

My suggestion for `apply(f, xs...)` would only cover one of those three major patterns. One would still have to explicitly specify the functions for the other patterns. Since none of the patterns applies to a large majority of cases, I withdraw my suggestion.
