JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.68k stars 5.48k forks source link

Different problems with @enum #15728

Open SimonDanisch opened 8 years ago

SimonDanisch commented 8 years ago

I found a few problems with the current enum implementation:

Last point got a bit less interesting after fixing the other points made everything compile fast already. I still wrote a toy implementation of it: https://gist.github.com/SimonDanisch/88f73018d6bf5219574ec1c679bc76ef

julia> @time run(`julia "using Vulkan"`) # Base.@enum
  5.362600 seconds (100.65 k allocations: 4.504 MB)

julia> @time run(`julia "using Vulkan"`) # CEnum.@cenum
  5.220823 seconds (60 allocations: 2.266 KB)

What we should at least use from this is:

function is_unit_range(array)
    isempty(array) && return true # well in practice extrema will rather fail, but there is 0:0
    lastval = first(array)
    for val in rest(array, 2)
        val-lastval == 1 || return false
    end
    return true
end
# generate code to test whether expr is in the given set of values
function membershiptest(expr, values)
    lo, hi = extrema(values)
    sv = sort(values)
    if is_unit_range(sv)
        :($lo <= $expr <= $hi)
    elseif length(values) < 20
        foldl((x1,x2)->:($x1 || ($expr == $x2)), :($expr == $(values[1])), values[2:end])
    else
        :($expr in $(Set(values)))
    end
end

For the unique values, we should decide if there should be an extra type Cenum, or if we just don't guarantee mappings to correct names if you decide to use multiple fields with the same value.

Best, Simon

SimonDanisch commented 8 years ago

@vchuravy

yuyichao commented 8 years ago

if you have very small and very large values, membershiptest will be slow or even throw OutOfMemory exceptions.

https://github.com/JuliaLang/julia/pull/15660

in c you very often use enum1 & enum2 == enumx, this functionality might be wanted in Base as well

https://github.com/JuliaLang/julia/pull/2988

It'll be nice to not define the show methods on the concrete type directly since otherwise it cannot be easily redefined.

StefanKarpinski commented 8 years ago

It might be preferable to have an EnumSet{E<:Enum} type that lets you express sets of values of a given Enum type E. The integer values of e ∈ E would be used to indicate the bit offset for e in an EnumSet{E} collection. It seems to me that it makes sense to semantically distinguish between APIs that expect individual enum values and some set of enum values.

Gnimuc commented 6 years ago

Any update on this?

KristofferC commented 6 years ago

The fact that you cant use the Julia enum to map into C enum is quite annoying when you want to generate a wrapper.

visr commented 6 years ago

Which of the above points still hold?

For C enums with multiple fields with the same value, I currently get by with just

@enum Fruit apple=1 orange=2
const kiwi = orange