Broadcast comparison of array of enum objects gives an error

I have an array of @Enum objects. I want to count the array elements having a certain value.

@enum E x = 0 y = 1
Es = [E(0) for i in 1:100]
sum(Es .== E(0))

Above code and just Es .== E(0) gives the following error:

ERROR: MethodError: no method matching length(::E)
Closest candidates are:
length(::Core.SimpleVector) at essentials.jl:582
length(::Base.MethodList) at reflection.jl:732
length(::Core.MethodTable) at reflection.jl:806

I know that I can count elements using for instance
sum([e == E(0) for e in Es])
but I wonder what’s wrong in the 1st approach.

Which version of Julia are you using? Your code works for me on 1.6.1 and 1.7.

Thanks for the quick reply.
I am using LTS version.

I think you’re getting hit by https://github.com/JuliaLang/julia/issues/30669 . It looks like the bug fix wasn’t backported to Julia 1.0.

Do you need to stay on LTS? Note that the LTS is not the “recommended version”, it’s really just for people who basically cannot upgrade.

(I’m still a bit surprised that such bugfixes don’t get backported.)

3 Likes

It surprises me that LTS is not recommended version, because it stands for Long Term.
I always stick to LTS versions, because I want to use (and re-use) code that is best, was tested and has the least number of errors (that would be my idea of LTS).
Why do I do that? For instance, I have some old code from some publication, I might want to open it for 5 min half a year after the publication and if I upgraded the programming language version, I might need two days to make it work again.

That makes sense (I have a similar approach for my OS software) but for Julia it’s not a good idea: the LTS is definitely not the best code, probably not even the most tested since the majority of user upgrade quickly to new versions I think.

I agree it’s confusing because you would expect an LTS to get all the bugfixes, and it’s not the case for some reason. But even if it did get all the fixes, you should use a more recent version: with LTS you’re stuck with old, inferior versions of third-party packages because the developers wanted to use important features introduced in Julia 1.3 for example.

Here’s a recent take from a core developer:

In summary, the language and ecosystem are moving too fast right now for LTS to be the best environment.

Fortunately, Julia has you covered when it comes to running old code :slight_smile: It’s easy to install the old Julia version that was used for an old project (just a zip file to uncompress somewhere). And assuming you have made a Julia project for your publication (and you really should have) then you have a Project.toml and Manifest.toml that describe the versions of packages used in that project. Years later you can get the correct package versions by running ]instantiate. And starting with Julia 1.7, the Julia version itself will be recorded in the manifest.

4 Likes

See also Julia’s Release Process for a discussion about the roles of LTS and other Julia versions and the “risk personas” these are targeted at.

P.S. if you do end up upgrading to 1.7 (which is the current release candidate) or 1.6 (current stable release) I do envy you - Julia has gotten so much better over those 6/7 point releases, with a lot of effort going into making the overall usability experience smoother, that it will by quite the (positive) shock.

3 Likes

That’s because it’s not a bugfix. It’s technically a new feature (that you don’t have to type Ref when broadcasting enums.)

5 Likes

To clarify: the LTS is not the “recommended version” because there is no such thing as a official “recommended version”.
There are at any point in time 3-4 supported versions:
LTS, Stable, Nightly and sometimes (including right now) the beta/release-candidate
All those versions, and even versions that are not currently supported can recommended for some use cases some of the time.

No-one ( not @sijo, not me, not a core developer) can tell you a general recommended version, without a lot more details that you should probably make a separate thread to provide.

Generally it is true that the newer releases with newer features are better for most (but not all people.)
Because Julia wouldn’t be going around adding features that make the language worse, that would make no sense.

How to use Ref when broadcasting enums (like in the example in the 1st post)?

P.S. Thanks to all for general comments. I feel tempted to upgrade :stuck_out_tongue: and I supposed I will do it when starting new project.

@enum E x = 0 y = 1
Es = [E(0) for i in 1:100]
sum(Es .== Ref(E(0)))

A case can also be made that rather than using Ref wrapping it in tuple, which also works:|

julia> sum(Es .== Ref(E(0)))
100

julia> sum(Es .== (E(0),))
100
1 Like

This previously mentioned quote from @StefanKarpinski reads like a recommendation to me:

The vast majority of people should be using whatever the latest Julia version is […] You should only be using the LTS if it’s very expensive or risky for you to go through the process of upgrading, which is not the case for 99% of users.

(I think people understand “recommended” as meaning “for most use cases”.)

I don’t think that’s generally true (that new features outweigh the benefits of stability), but that it’s currently true for Julia in typical use cases.

Let’s not shy away from recommendations. I think those from @StefanKarpinski are useful for new users. On the other hand, “there are all these versions and a lot of details about your use case are required to determine the appropriate one” sounds intimidating/overwhelming and makes the choice seem more difficult than it is.

2 Likes