Design pattern with enums with some overlapping elements?

myersm0
Thu, 28 Sep 2023 18:27:33 +0000
General Usage

I would appreciate it if anyone has any advice on elegantly handling this design problem:

I’m writing a package for visualization of some custom types with GLMakie for a specific domain. In the domain, there are several sets of standard colors that are well-known, and I’d like users to be able to pass in a descriptive key(s) from one of those sets and then use the respective color(s) in a plot. Via a Dict, probably. Part of the challenge is that some of the sets of colors will have overlapping names. I could prefix the names with something to make them distinct, but that would be a little clumsy.

I’m aware of EnumX.jl to divide enums into sub-modules, and I think that might be the answer except that I would really like to not have to qualify elements with ModuleName. (The consideration is with users in mind: I want my package to really make things easy for people.)

I know, I have to make the names from the different color sets distinguishable somehow. But could I do so either by either using types, or by allowing the user to load in a set of colors himself or herself to be used so that there’s no ambiguity? Because almost certainly the user will just want to use only one of the sets of colors and doesn’t need the rest.

A short example of the basic setup I have now (which of course doesn’t quite work as is because of the overlap in names, but you see what I’m going for):

# from discourse.julialang.org/t/export-enum/5396
macro exported_enum(name, args...)
    esc(quote
        @enum($name, $(args...))
        export $name
        $([:(export $arg) for arg in args]...)
        end)
    end
export exported_enum

@exported_enum(SetA, Undefined, Red, Green, Blue)
@exported_enum(SetB, Undefined, Red, Green, Yellow)

Base.zero(::SetA) = Undefined::SetA
Base.zero(::SetB) = Undefined::SetB

Ideally also I’d like to avoid redundancy, like not have to define Base.zero(...) separately for the several different color sets.

Conceptually also there’s an advantage of allowing overlap in the enums: the respective elements sharing a name are really a different interpretation the same thing. (E.g. SetA’s concept of Red is just a different perspective on SetB’s concept of the same.)

Is there a good way to handle this via types instead, or is that considered an “abuse” that I should avoid? One consideration, by the way, is that the sets of Colors are going to have 15 - 25 elements each so defining all those types might be cumbersome.

Any suggestions are very welcome, and thanks in advance.

1 post - 1 participant