Character to replace _ in symbol names?

14

2

In C, _ comes in handy when naming variables and functions, as a replacement for space. For example:

int the_name_of_my_variable;

I find this more readable than CamelCase:

int theNameOfMyVariable;

That's just my taste.

In Mathematica we cannot use _ to replace spaces in variable names, because _ means Blank pattern. Is there an alternative we can use? Another character that is not an operator and can be used as a replacement for space?

becko

Posted 2016-03-29T12:39:25.673

Reputation: 10 287

Check out Non-printing Characters and \[LetterSpace].

– dionys – 2016-03-29T12:57:40.457

You may use any Letter and Letter Like Form as long as it is not a defined symbol. Smiley face, ellipse, white bishop, black king, wolfie; anything. However, I think it will make your code hard to read for others.

– Edmund – 2016-03-29T12:59:17.290

@dionys \[LetterSpace] is close to what I want. But I want something I can see. Is there a form of underscore that is not a symbol? – becko – 2016-03-29T13:09:20.690

2You can use $the$name$of$my$variable – rm -rf – 2016-03-29T14:07:29.623

3

In the past Wolfram Research had the same problem when they implemented NETLink. Their solution was to replace _ by U (see here, and look for "underscore"). It's a clue that there is probably no better way to do that.

– andre314 – 2016-03-29T16:48:09.907

Answers

32

This has been discussed on comp.soft-sys.math.mathematica. The gist is that there are lots of Unicode characters you could use, e.g. \[LetterSpace] or \[UnderBracket] (you could consult https://reference.wolfram.com/language/tutorial/LettersAndLetterLikeForms.html for a long list), but I'd strongly urge you not to do that.

Once you copy the code out of Mathematica, these will be expanded to the above long forms which will make your code very unreadable. I think there are ways to "copy as Unicode", but a lot of these are in Unicode's private use pages, which means they will almost certainly not render properly anywhere outside of Mathematica.

Plus, camelCase is such a widespread convention in Mathematica, that it's probably not worth the trouble working around that just to match your programming style in another language. Mathematica's syntax works differently from C's, and I don't think there's a lot of benefit in trying to make Mathematica look like C. You'll probably save yourself a lot of trouble by simply embracing Mathematica's own conventions.

Martin Ender

Posted 2016-03-29T12:39:25.673

Reputation: 8 374

9"it's probably not worth the trouble working around that just to match your programming style in another language." - I upvoted specifically because of this. When in Rome... – J. M.'s ennui – 2016-03-29T13:22:01.773

Keep in mind that visual parsing of text by the human brain is trained at an early age, and not easily updated. I have been using CamelCase for 2 decades and I still have to slow down to read it, whereas words_separated_with_underscore_I_can_read_at_full_speed. – Shebla Tsama – 2021-01-01T07:54:11.760

@SheblaTsama I agree that snake_case is a lot more readable, and if I could choose I'd always use it, but I've found that going against language conventions is generally not worth it. – Martin Ender – 2021-01-05T16:03:53.183

11

The issue is that Mathematica interprets underscore as Blank and interprets my_variable as a Pattern, when what we'd like is a legitimate symbol name.

    Head[Unevaluated[my_variable]]
    (* Pattern *)

There are a few Unicode alternatives for underscore:

  • combining low-line

  • combining macron below

  • modifier low-letter macron

  • figure dash

  • fullwidth low-line

     varNames = StringReplace["my_variable", "_" -> FromCharacterCode[{#}]] & /@ {717, 817, 818, 8210,65343}
    
     (* {"myˍvariable", "my̱variable", "my̲variable", "my‒variable", "my_variable"} *)
    
     Head[Unevaluated[#]] & /@ (ToExpression /@ varNames)
     (* {Symbol, Symbol, Symbol, Symbol, Symbol} *)
    
     varNameQ[s_String] := Check[Symbol[s]; True, False] // Quiet
    
     varNameQ /@ varNames
     (* {True, True, True, True, True} *)
    

dionys

Posted 2016-03-29T12:39:25.673

Reputation: 4 128

1...and to verify that they are indeed valid symbols, use SyntaxQ[]. – J. M.'s ennui – 2016-03-29T13:58:40.170

@J.M.issomewhatokay. that won't verify that these symbols are valid symbols for variables. E.g. SyntaxQ["1hel_lo5"] also returns True. – Ruslan – 2018-09-29T19:02:13.413

@Ruslan, indeed, so one needs to do another test like StringMatchQ["1hel_lo5", WordCharacter ..]. – J. M.'s ennui – 2018-09-29T19:09:53.263

@J.M.issomewhatokay. I think Symbol["1hel_lo5"] would be a more direct check (if it returns unevaluated and emits Symbol::symname, the symbol is bad, otherwise OK). – Ruslan – 2018-09-29T19:16:22.460

@Ruslan, you'd need to wrap Quiet[] around it if you don't want messages being thrown just for testing, however. – J. M.'s ennui – 2018-09-29T19:17:55.513

4

I use $ as a separator. It is a valid symbol character.

In my application I have a set of variables that need to be identified by coordinates, like for example a17_4_25. I can't just drop the _ since a17425 would be ambiguous, so I use a17\$4\$25.

It's not as pleasing to the eye as '_', but it gets the job done and it is plain ascii.

Obviously CamelCase would not work for me. I would love to find another ascii character that provides more visual separation than \$ but as far as I know there is none.

EDIT: I just did an exhaustive trial of ascii characters and there is no other choice: \$ is the only option!

Shebla Tsama

Posted 2016-03-29T12:39:25.673

Reputation: 141