Julia: Enum.jl is missing broadcasting functions

Created on 23 Aug 2018  路  8Comments  路  Source: JuliaLang/julia

The following example

@enum Tags A B C
x = [A A B C B C]
x .== A

gives me

ERROR: MethodError: no method matching length(::Tags)

The Enum.jl file should include the following functions

length(::Enum) = 1
iterate(x::Enum) = (x, nothing)
iterate(::Enum,::Nothing) = nothing

which would allow x .== A to result in the expected result

1脳6 BitArray{2}:
 true  true  false  false  false  false

The functions could also be defined for the subtype ::Tags via the @enum macro, if this is desirable?


julia> versioninfo()
Julia Version 1.0.0
Commit 5d4eaca0c9 (2018-08-08 20:58 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Xeon(R) CPU E5-2470 v2 @ 2.40GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, ivybridge)

Most helpful comment

I don't think an Enum should be iterable so the solution would be to define Base.broadcastable to return a Ref wrapped instance of the enum.

All 8 comments

Perhaps it makes sense to iterate an enum, but note that you can do this:

julia> @enum Tags A B C

julia> x = [A A B C B C];

julia> x .== Ref(A)
1脳6 BitArray{2}:
 true  true  false  false  false  false

I know @fredrikekre, but going down that road I am sure to write x == Ref(A) some day for a single element, and get invalid code that is not easily detected. Also, the x .== Ref(A) variant generates more than double the instructions if you inspect it via @code_llvm.

I don't think an Enum should be iterable so the solution would be to define Base.broadcastable to return a Ref wrapped instance of the enum.

Would you mind elaborating why not @KristofferC? I see them defined for ::Number in number.jl:

length(x::Number) = 1
iterate(x::Number) = (x, nothing)
iterate(x::Number, ::Any) = nothing

The fact that numbers are iterable has been a point of discussion (https://github.com/JuliaLang/julia/issues/7903) but Enums are not numbers so it doesn't apply here. Why do you want to iterate Enums?

Thank you for pointing me to discussion #7903. I now understand why you want enum values to be broadcastable, but not iterable. I still find it weird though to construct a new iterable object to hold the enum value. I mean Base.broadcastable(x::Enum) = Ref(x) is definitely better than Base.broadcastable(x::Enum) = [x], but I wonder if it is possible handle it purely via the type system? For example, by casting to an IterEnum type?

Using a trait for what is considered scalars w.r.t broadcasting has been discussed but, for now, the way to do it is to wrap it in a length one iterable container.

Closed by #30670

Was this page helpful?
0 / 5 - 0 ratings

Related issues

felixrehren picture felixrehren  路  3Comments

dpsanders picture dpsanders  路  3Comments

Keno picture Keno  路  3Comments

i-apellaniz picture i-apellaniz  路  3Comments

iamed2 picture iamed2  路  3Comments