2
$\begingroup$

I have a function with more than two possible return values.

A simplified example is the following function that classifies vertices of a graph according to their degrees:

VertexRole[g_, v_] := Which[
  VertexDegree[g, v] == 1, BadVertex,
  VertexDegree[g, v] == 2, MediocreVertex,
  VertexDegree[g, v] == 3, GoodVertex
  ]

However, defining the function in this way would be bad practice since the symbols BadVertex etc. are undefined. Furthermore, I want to evaluate expressions such as

VertexRole[graph, vertex] == BadVertex

Defining BadVertex to be a number (e.g. 42) would also be bad since I actually want

BadVertex == x

to evaluate to False for all x other than BadVertex.

Therefore BadVertex etc. should be symbols similar to True, False, Automatic, All, None. How can I implement that?

[One could use a string as the return value (e.g. "BadVertex"), but that kind of misses the syntactical point I am trying to make. I am rather looking for something that resembles the enum type in C.]

$\endgroup$
  • 2
    $\begingroup$ Why do you think using undefined symbols is a bad practice? $\endgroup$ – happy fish Jul 4 '16 at 15:10
  • $\begingroup$ Why not output a string or some number that encodes your desired output if you insist on not making new symbols? $\endgroup$ – J. M. will be back soon Jul 4 '16 at 15:18
  • $\begingroup$ @happyfish Because undefined symbols are not Protected. $\endgroup$ – Deniz Jul 4 '16 at 15:18
  • $\begingroup$ @Deniz No, user defined symbols are not protected unless you do it manually. You can also protect a undefined symbol, if you are referring undefined as not having own values, down values , etc. $\endgroup$ – happy fish Jul 4 '16 at 15:22
  • 2
    $\begingroup$ Rather than repeated evaluation of VertexDegree[g, v] you might want to consider using Switch $\endgroup$ – Bob Hanlon Jul 4 '16 at 17:15
3
$\begingroup$

Your code looks reasonable to me. If I were doing this, I would

  • manually Protect those symbols on the off chance that for some reason I accidentally assigned them values (though this is not necessary for them to work),
  • assign them ::usage messages so they register correctly into the system (and therefore display in black instead of blue, and
  • use === (i.e. SameQ) instead of == (i.e. Equal) if I wanted to make it very explicit that "BadVertex == x should evaluate to False for all x other than BadVertex".

If you're really worried about it, it would also be acceptable to use strings instead of symbols, but really it looks fine as is.

$\endgroup$
  • 1
    $\begingroup$ One might sometimes consider using MatchQ[] instead of ===, but that depends on the application. $\endgroup$ – J. M. will be back soon Jul 4 '16 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.