XEN-F001: Enums


#1

Enumerations are common in the programming world. Most languages provide either built-in facilities for defining enum types or recommendations for emulating them. While some languages provide very basic support which is a layer on top of numbers or strings (C, Python), other languages offer powerful ADT (Algebraic Data Types) systems where an enum item can carry some additional payload.

XOD lacks enumerations. This XEN suggests a minimalistic approach to bring a kind of enums to the language.

Read on: https://github.com/xodio/xod-xens/tree/master/XEN-F001


#2

The only issue I see with this is name collisions if you will pull in values from other libraries. For example, the accelerometer library will pull in sensitivity values from an unrelated light-detector library (or another accelerometer library that uses different ranges). More explicit types (like accel-sensitivity) would help, but not eliminate the problem. Worst-case scenario: an input pin that accepts any value of data-type suddenly becomes an enum because another library used the same data-type name for an enum (not looking for enums in other libraries if none exist in current library would eliminate this issue – and save search time). You might also require flag to indicate that a node is to be used as an enum value (so random nodes don’t get pulled in); enum-2g name instead of just 2g would be one option (“enum-” could be stripped when displayed in drop-down for selection).

One way to eliminate namespace collision would be to provide a method of specifying which library the enum node should apply to. Node names are one option like 4g@nkrkv/accel or 4g(nkrkv/accel); no library implies it is only for the current library (or allow “.” to indicate current library). “@” in node name could be the indicator that it is an enum node. A way to specify multiple libraries where it can be used would be a bonus, but probably much harder to implement.


#3

Ah, I think it is not obvious from the text, but custom types were always fully-qualified. That is the real name of the type is nkrkv/accel/sensitivity. And it can’t collide or implicitly interchange anyhow with gweimer/joysticks/sensitivity. They are two distinct sensitivities and can easily get two different enum variants.


#4

Those work really well in a functional paradigm. I can’t wrap my head around what that would mean in a XOD like world.

I ran into this with the NeoPixel library. It’s needed to set the hardware-color-order. E.g. NEO_RGB vs NEO_GRB.

Many Arduino libraries have a list of constants, which are logically enums. It’s super common in microprocessor attached hardware (I2C registers, etc etc.).

I think this is very worthwhile.

defining few “constant” patch nodes

I think it is very common for it to be “many” rather than a few. NeoPixel RGB order has 30 values. The TCL59116 has 16 registers by name, several needing 6 values each, and more than 10 miscellaneous other “constants”. That’s several sets of enums.

Improvement … Searching for nodes compatible with a particular parameter can discourage a library newbie.

So, I concur.

XOD can look for all patches in the project and available libraries to find those who have a single out of the specific type

I suppose this has the advantage that the list-of-values for the enum is extensible (by other libraries … as you suggest later). As opposed, say, to a single patch of type “xod-enum” with some property that lists the key->value bindings.

Furthermore, an input-sensitivity terminal can also suggest choosing from these values

yes, a drop down please!

The enum custom-type should present as a single patch: “sensitivity”, and have that same drop-down in it’s inspector. The input for various patches that need that enum should give an obvious clue that they want that patch (e.g. input named “sensitivity”).

I suspect a further clue is necessary, so that the user knows to search for a paticular patch, that behaves like an “enum”.

In any case, a user has no chance to send a wrong value to the strictly-one-of input.

Helping the user make the right choice is virtuous. Thus, giving them a correct selection to choose from is the right thing to do. I’m concerned that they shouldn’t be shut out of using some useful value that the library designer overlooked. I’ve noticed that Arduino libraries for hardware devices are often incomplete, so this scenario is not uncommon. So, there should be an escape clause to let them specify a (typically) numeric value.

There might be even libraries entirely made to provide new color choices, pulse frequencies, etc.

Which also suggests a more generic “list of choices” type in XOD. Otherwise behaving as you suggest, it’s output is a standard type (string, for example, or number). Perhaps naming some values is useful: “seizure induce” for .1 second period, “lowest perceptually continuous change” for 30 for pwm values, “leaded solder” for 320 (“lead free” for 600).

pulse frequencies

is a good example of this. I think it would not work to have rates be a custom-type: it is not uncommon to calculate rates. But, some named ones might be friendly.

Perhaps enums should auto-cast from the obvious type (typically number)?

… color …

Color is mentioned several times as an example. But, I don’t see how you would have it also work with “arbitrary” rgb values. A pot input might want to set a green channel to something, and a switch select from 8 named RGB values (enum values).

In summary,

  • I am strongly in favor of a drop-down choosable enum mechanism. But it must support a large number of values (30+).
  • I would be strongly against having each enum value be a user-visible patch (think what it would do to “search”!).
  • I would advise against making too many things a custom-type (enum), e.g. rates, preventing calculated values as inputs. It seems provisions have to be made for enums & calculated values to work together.

#5

Thank you for the constructive feedback!

I see your concern. If we have a choice of 30 we should define these 30 items somehow. And I’m looking for a way to make it possible without introducing as little new concepts and new UI as possible. We have patches, nodes, custom types, comments, pins,… The enums riddle should be made out of them somehow.

So, let’s imagine the Neopixel constants in the frame of the original concept. An author will have to create a custom type neopixel-type by creating a patch node which takes a raw value of XOD byte type and produces the “wrapped” value of type neopixel-type. Now he creates the enumeration items. A patch per item. The patch is a trivial wrapper around neopixel-type with the input pin hard-coded to the corresponding hex value.

rgb
rbg
grb
gbr
brg
bgr
wrgb
wrbg
wgrb
wgbr
wbrg
wbgr
rwgb
rwbg
rgwb
rgbw
rbwg
rbgw
gwrb
gwbr
grwb
grbw
gbwr
gbrw
bwrg
bwgr
brwg
brgw
bgwr
bgrw

Indeed, the search will bury any useful mentions of “RGB” behind the routine variants :thinking: But if we’ll ignore the clutter for a moment, it should work fine. In particular, we’re leaving the way to “force” a forgotten enum value by using the raw neopixel-type node directly.

OK, how can we reduce the clutter without inventing something principally new? One idea which came to my mind is borrowing the naming scheme from generics specializations. So, the patches would be:

neopixel-type
neopixel-type(rgb)
neopixel-type(rbg)
neopixel-type(grb)
neopixel-type(gbr)
neopixel-type(brg)
neopixel-type(bgr)
neopixel-type(wrgb)
neopixel-type(wrbg)
neopixel-type(wgrb)
neopixel-type(wgbr)
neopixel-type(wbrg)
neopixel-type(wbgr)
neopixel-type(rwgb)
neopixel-type(rwbg)
neopixel-type(rgwb)
neopixel-type(rgbw)
neopixel-type(rbwg)
neopixel-type(rbgw)
neopixel-type(gwrb)
neopixel-type(gwbr)
neopixel-type(grwb)
neopixel-type(grbw)
neopixel-type(gbwr)
neopixel-type(gbrw)
neopixel-type(bwrg)
neopixel-type(bwgr)
neopixel-type(brwg)
neopixel-type(brgw)
neopixel-type(bgwr)
neopixel-type(bgrw)

Nodes with parens in the name are already (a) valid and (b) do not appear in search unless the query contains the left parenthesis character. XOD IDE might use the contents in parens to be used as a label in the drop-down list.

I’m sure you’re thinking about a way to encapsulate all items in a single patch completely, but I failed to find a straightforward user flow of doing it. What can you say about the solution above?

I think we’re mixing the enumeration and constants concepts here? The 1-hz, seizure-induce, leaded-solder nodes might be single-output nodes which do not involve any new custom types. XOD IDE may pick up variant values for Inspector inputs like it does for enums. However, in such case, it will leave the field editable, that is allow entering arbitrary values.


#6

How about a new node “enum-val”? It would act as a flag like deprecated/utility, but look like constant so you can set the value with input pin. It can be configured to not show up in searches (which I guess would be the default for an individual node instance…). If you replace the label on the node, it will show up as a description along with value in the drop-down for enum selection [possible format: (val)]. Then all enum values can be grouped in one patch defining the data type.

If others can extend the data-type, the enum drop-down could either merge all values & display in alphabetical order, or the drop-down could list in the order enum-val appears in patch and any values added by extension could be displayed together with a separator between groups of values. Something like:

value1 (42)
68
other val (13)
==========
custom val (777)


#7

Then, what does it mean if I link an arbitrary computation tree to the enum-val’s pin? What value will this enumeration item have?


#8

Hmmm…that might work, but probably a bad idea. How about enum-val more like Constants? Set the output pin instead of allowing an input pin? Probably makes more sense anyway…