What's the difference between fields and properties?

question

#1

I’m trying to understand this pull request which will be implemented in V0.7/V1.0:

I read the V0.7 documentation but I coudn’t find any clarification on the specific differences between fields and properties.

In fact the functions getfield and setfield! refer to getproperty and setproperty! but the latter functions are not fully documented. The main difference seems to be that field related functions are in Core and the property related functions are in Base. Could someone clarify?

Thanks


#2

fields are simply the “components” of a struct. The struct

struct A
   b
   c::Int
end

has the fields b and c. A call getfield returns the object that is bound to the field:

julia> a = A("foo", 3)
A("foo", 3)

julia> getfield(a, :b)
"foo"

The dot syntax a.b used to “lower” i.e. be the same as writing getfield(a, :b). What has changed now is that a.b lowers to getproperty(a, :b) with the default fallback

getproperty(a::Type, v::Symbol) = getfield(a, v)

So by default, nothing has changed. However, authors of structs can hook into getproperty:

julia> function Base.getproperty(a::A, v::Symbol)
           if v == :c
               return getfield(a, :c) * 2
           elseif v == :q
               return "q"
           else
               return getfield(a, v)
           end
       end

julia> a.q
"q"

julia> getfield(a, :q)
ERROR: type A has no field q

julia> a.c
6

julia> getfield(a, :c)
3

julia> a.b
"foo"

So we can add extra functionality to the dot syntax (dynamically if we want). As a concrete example where this is useful is PyCall where you used to have to write pyobject[:field] while it is possible now to implement it such that you can write pyobject.field.


#3

Great answer thanks. So in my updated mental model I think of property related functions as the mid-level abstraction between dot notation and field related functions.

edit: excited to start using this, it will be uber helpful for some things I need. Perfect timing :sunglasses: