11

I've read multiple style guidelines and other resources stating it's a bad idea to use underscores in method/variable/other names.

What are the technical reasons behind this?

I'm very accustomed to e.g. prepending helper functions with _. There are also functions that should be private that I want to make public so I can access them via the REPL. Other naming conventions like using a "helper" suffix just seem cumbersome.

Any thoughts would be appreciated!

Pandora Lee
  • 1,435
  • 2
  • 14
  • 17

4 Answers4

15

The wildcard operator _ is used heavily in Scala. So:

xs map (_.x)  // Call the x method of every element
xs map (_x)   // Pass every element through the _x method

is confusing. You have to look very carefully to see if the underscore is prepended.

However, internal underscores are harder to confuse:

xs map (my_method)  // No similar form where _ stands for the list element

So these are less problematic, but the underscores still catch the eye a little when one is looking for closures. This is probably why they're discouraged, but to be honest, I use them all the time, particularly in things like implicit defs and internal variables where they won't have much or any exposure in an interface.

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
  • 3
    this is a very constructed case: you have an `xs: Seq[T: {def x: U}]`. for the error to occur, you need exactly a `_x: {def apply(y: T): U}`. if either of these three constraints isn’t there, it doesn’t compile. it has to be exactly named `_x`, has to be callable with a single `T` argument, which has to return an `U`. i’m not even slightly convinced. – flying sheep Sep 02 '11 at 09:56
  • 4
    @flying sheep - It's not likely that you'll have a name collision of that sort; the point is that when you are reading quickly through only-somewhat-familiar code, you don't know immediately whether a private method in local code or a public method on the collection element is in play. You can, of course, figure out quite quickly, but you can figure it out _even faster_ if you can tell from shape at a distance. – Rex Kerr Sep 02 '11 at 14:20
5

I only know the reason I avoid underscores in names: they are an important part of Scala syntax that show up all over the place. Sure, you can put them in names, but it tends to slow down the human parser in my experience.

But I must confess I do occasionally use an underscore prefix for private variables in mutable objects, if I want the non-underscored name for public methods. It would be nice if we could use primes (foo') like Haskell, but I think that would be lexically difficult.

Lachlan
  • 3,744
  • 2
  • 26
  • 29
2

i think those specs just talk about underscores in names.

in what (sane) way should you write the following, if not this way?

object getterSetter {
    var _variable: Option[Double] = None
    def variable = _variable
    def variable_=(newVal: Double) { _variable = Some(newVal) }
}

i think the reason for camelCase instead of embedded_underscores is simply that java uses that and when working with java libraries, consistency can be only kept like that.

flying sheep
  • 8,475
  • 5
  • 56
  • 73
2

In addition to the _ being used all over the language not just as a wildcard but also as parts of public APIs like in tuples (someTuple._1 etc) it is also interpreted specially by the compiler in some cases. For instance in setters, which have to be suffixed with _= or in unary operators, which have to be prefixed with unary_.

All this makes it really easy to use a "special name" by accident or misinterpret an "ordinary name" when someone used something similar but not exactly the same as a "special name". It won't matter if it happened by accident or due to lack of knowledge, but when it does you will probably spend a couple of hours looking for a bug. So don't use them unless you really have to. DSLs are as always an exception.

agilesteel
  • 16,775
  • 6
  • 44
  • 55