`hasfield` and `getkey` in namedtuple

Just a curiosity: is there any particular reason for the slightly odd choice of access functions for named tuples? I would expect to have hasfield and getfield, or alternatively haskey and getkey, but I see a mixture of them instead.

julia> a, c = 1, 2;

julia> nt = (;a, c)
(a = 1, c = 2)

julia> haskey(nt, :a)
true

julia> haskey(nt, :c)
true

julia> haskey(nt, :b)
false

julia> T = typeof(nt)
@NamedTuple{a::Int64, c::Int64}

julia> hasfield(T, :a)
true

julia> hasfield(T, :c)
true

julia> hasfield(T, :b)
false

NamedTuples support retrieving valus via getproperty/getfield and getindex.

See

nt = (; a=1, b=2)

@assert nt.a == nt[:a]

1 Like

getindex/setindex for types that have integer keys (tuples and arrays).

getproperty/setproperty for types with Symbol properties that are known at compile time (structs and named tuples). These can be overloaded for custom types to provide special handling of the dot access to properties.

getfield/setfield for the same as above, but should cannot be overloaded so you can still access the raw fields.

getkey/setkey for Dictionary like types whose keys are set dynamically at runtime.

Edit: fix to reflect that get/set field can’t be overloaded. Thanks @sgaure !

2 Likes

These are builtins, not generics, and can’t be overloaded.

julia> Base.getfield(a::NamedTuple, s::Symbol) = 1
ERROR: cannot add methods to builtin function `getfield`
2 Likes

Thank you all @_bernhard, @mrufsvold, and @sgaure. @mrufsvold , your summary recap is really useful.

I know recognize that my confusion was due to erroneously thinking that hasfield, similarly to hasproperty, could be applied to instances. Instead, it has to be used on types. My bad…