No method matching length() for any dot syntax operation involving a struct

I have experienced this problem a lot and it’s beyond frustrating. For some reason any dot syntax call that includes a struct fails. I can use map but is it possible to use dot syntax here? What am I missing?

julia> struct MyType
       name::String
       end

julia> f(m::MyType, i::Integer) = i + 1
f (generic function with 1 method)

julia> arr = [1,2,3]
3-element Vector{Int64}:
 1
 2
 3

julia> my = MyType("John")
MyType("John")

julia> f.(my, arr)
ERROR: MethodError: no method matching length(::MyType)
[...]

julia> map(x-> f(my, x), arr)
3-element Vector{Int64}:
 2
 3
 4

broadcasting treats things as vectors by default. If you want broadcasting to treat MyType as a scalar, define Base.broadcastable(x::MyType) = Ref(x)

1 Like

Wow, thanks - what a great trick. Is there a reason not to use this line in every single type definition? Would I be breaking anything by overriding broadcastable like this?

no, this is what you should do, broadcast is an interface:
https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting

this is not overriding, nor hack, because you own the type, and you need to teach Julia what to do with your types during broadcasting. Another similar concept is number type promotion

Neat!

Could be made default with Base.broadcastable(x::Any) = Ref(x), and only overridden explicitly for objects that can be broadcast such as tuples, arrays and matrices. Why not do things this way? :thinking:

So that is how it works for Numbers. The reason for the decision is that there were deemed to be more collection-like objects rather than scalar-like non-number objects. This is a very subjective decision obviously, and either way, someone needs to change the behavior for their type. Note that if you are defining a lot of similar scalar-like types, you can define broadcastable on a common super-type to give all subtypes that behavior.

2 Likes

People wanted to remove this behavior from numbers make numbers non-iterable? · Issue #7903 · JuliaLang/julia · GitHub but it was too much work at the time, and now it’s too late. I wouldn’t suggest adding collection semantics to other arbitrary types that aren’t actually collections.