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$
7
  • 2
    $\begingroup$ Why do you think using undefined symbols is a bad practice? $\endgroup$
    – vapor
    Commented Jul 4, 2016 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$ Commented Jul 4, 2016 at 15:18
  • $\begingroup$ @happyfish Because undefined symbols are not Protected. $\endgroup$
    – Deniz
    Commented Jul 4, 2016 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$
    – vapor
    Commented Jul 4, 2016 at 15:22
  • 2
    $\begingroup$ Rather than repeated evaluation of VertexDegree[g, v] you might want to consider using Switch $\endgroup$
    – Bob Hanlon
    Commented Jul 4, 2016 at 17:15

1 Answer 1

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
  • 1
    $\begingroup$ One might sometimes consider using MatchQ[] instead of ===, but that depends on the application. $\endgroup$ Commented Jul 4, 2016 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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