Scala style guideline for underscore in identifiers - scala

I have accepted from many other languages that underscores have as much freedom as alphabets in an identifier. Hence _v and v_. Also that trailing underscores are recommended to avoid ambiguity with reserved keywords (class_, case_).
val abc_=0
<console>:1: error: '=' expected but integer literal found.
val abc_=0
Underscores being an important part of Scala typing system, what is the recommended way to use them in identifiers, so that parser and human can both be happy? What are all possible ambiguities that identifiers with underscores bring?
Leading whitespaces seem to add to confusion _class instead of class_.
Related questions:
What are all the uses of an underscore in Scala?
Scala underscores in names

Trailing underscores are a bad idea because things like x_+ are valid variable names on their own. Don't use trailing underscores at all.
Leading underscores are less bad of an idea, but it's still hard to visually parse things like _myfunc _. There is something of a convention to make private members that hold constructor arguments of the same name start with _: class X(x: Int) { private var _x = x }. My recommendation is don't do it. You're asking for confusion. Use myX or theX or xLocal or xi or something for your internal variable. Still, if you do go with _x, you'll have good company; people will tend to know what you mean.
Underscores within a name are not widely used, since camel case is the standard. The exception that I make is that I use underscores within implicit defs that are not expected to be used by hand, and instead state why the conversion is taking place: tuple2_can_expand might add an expand method to convert a Tuple2 into a Tuple3, for example.

There is only one place you need underscores in identifiers: between alphanumeric characters and other. In fact, that's just what happens in your case: the parser thinks you are declaring val abc_= and don't have = after it! Most common use is for "setter" methods:
def prop: String // or some other type
def prop_=(v: String)
I've also seen predicate_? instead of more Java-like isPredicate.
keyword_ aren't often used, but if you do use them, don't skimp on the whitespace. Write, e.g., val abc_ = 0. But for that matter, val abc = 0 is more readable than val abc=0 as well, so you should have whitespace there anyway. As Rex Kerr says, _privateVariable is acceptable, but not recommended practice.

Related

Are these lines of scala code equivalent?

Given an object myObject which has a method getSomething which takes in a String parameter and returns a String
Are #1 and #2 equivalent?
val foo = myOjbect.getSomething("foo")
val foo = myOjbect getSomething "foo"
And are either acceptable / preferred over the other? When would you use 1 vs 2 and vica versa?
They are strictly equivalent.
Regarding your second question, Stack Overflow is not really meant to decide what is acceptable or preferred. Yet you can refer to the scala documentation on method invocation that states this:
Scala has a special punctuation-free syntax for invoking methods that take one argument. Many Scala programmers use this notation for symbolic-named methods:
// recommended
a + b
// legal, but less readable
a+b
// legal, but definitely strange
a.+(b)
but avoid it for almost all alphabetic-named methods:
// recommended
names.mkString(",")
// also sometimes seen; controversial
names mkString ","
Yes they are identical.
There is no consensus (I don't think it is possible to achieve one) which form are preferable (such questions are offtopic here).
Yes, they are identical.
I mostly use the 2nd version when developing tests like:
result mustEqual "Hello"

Primitive types are not traited Immutable in scala?

Can anyone please share insight into the trait "Immutable" in scala? At first glance I thought this would be a nice control structure to limit a class I'm building, but oddly I noticed that primitive types do not extend this. Is there a reason for this? Is there a way to bind the syntax to Immutable or AnyVal?
class Test {
def test[T<:Immutable](x:T)={
println("passes "+x)
}
case class X(s:String) extends Immutable
test(X("hello")) //passes
// test("fail") - does not pass compiler
}
The only direct subtypes of Immutable in the Scala core library are:
collection.immutable.Traversable
collection.parallel.immutable.ParIterable
Nothing else refers to Immutable at all.
Immutable hasn't been changed since it was added in 2009 in Martin Odersky's "massive new collections checkin". I'm searching through that commit, and it looks like Immutable was never even used as a bound when it was first introduced either.
Honestly, I doubt there's much intent behind these traits anymore. Odersky probably planned to use Immutable to bound the type arguments on immutable collections, and then thought better of it. But that's just my speculation.
So-called primitive types (Boolean, Byte, Char, Short, Int, Long, Float, Double) are intrinsically immutable. 5 is 5 is 5. You cannot do anything to 5 to turn it into anything that is not 5.
Otherwise, immutability is a property of how a value is stored. If stored in a var, that var may be replaced freely with a new value (of a compatible type). By extension, constructed types (classes, traits and objects) may be either immutable or mutable depending on whether they allow any of their internal state to be altered following construction.
Java's String (also used as Scala's String) is immutable.
However, none of this has anything to do with you example, since you did not demonstrate mutability. You simply showed what happens when one applies the + method of one value to another value.
While it is certainly possible that one can implement a + method that mutates its (apparent) left-hand operand, one rarely does that. If there's a need for that kind of mutation, one would conventionally define the += method instead.
+ is somewhat special in that it may be applied to any value (if the argument / right-hand operand) is a String by virtue of an implicit conversion to a special class that defines +(s: String) so that the string concatenation interpretation of + may be applied. In other words, if you write e1 + "e2" and the type of the expression e1 does not define +, then Scala will convert e1 to String and concatenate it with "e2".

Cool class and method names wrapped in ``: class `This is a cool class` {}?

I just found some scala code which has a strange class name:
class `This is a cool class` {}
and method name:
def `cool method` = {}
We can use a sentence for a class or method name!
It's very cool and useful for unit-testing:
class UserTest {
def `user can be saved to db` {
// testing
}
}
But why we can do this? How to understand it?
This feature exists for the sake of interoperability. If Scala has a reserved word (with, for example), then you can still refer to code from other languages which use it as a method or variable or whatever, by using backticks.
Since there was no reason to forbid nearly arbitrary strings, you can use nearly arbitrary strings.
As #Rex Kerr answered, this feature is for interoperablility. For example,
To call a java method,
Thread.yield()
you need to write
Thread.`yield`()
since yield is a keyword in scala.
The Scala Language Specification:
There are three ways to form an identifier. First, an identifier can
start with a letter which can be followed by an arbitrary sequence of
letters and digits. This may be followed by underscore ‘_’ characters
and another string composed of either letters and digits or of
operator characters. Second, an identifier can start with an operator
character followed by an arbitrary sequence of operator characters.
The preceding two forms are called plain identifiers. Finally, an
identifier may also be formed by an arbitrary string between
back-quotes (host systems may impose some restrictions on which
strings are legal for identifiers). The identifier then is composed of
all characters excluding the backquotes themselves.
Strings wrapped in ` are valid identifiers in Scala, not only to class names and methods but to functions and variables, too.
To me it is just that the parser and the compiler were built in a way that enables that, so the Scala team implemented it.
I think that it can be cool for a coder to be able to give real names to functions instead of getThisIncredibleItem or get_this_other_item.
Thanks for your questions which learnt me something new in Scala!

Naming convention for Scala constants?

What is the naming convention for Scala constants? A brief search on StackOverflow suggestions uppercase CamelCase (the first line below), but I wanted to double-check.
val ThisIsAConstant = 1.23
val THIS_IS_ANOTHER_CONSTANT = 1.55
val thisIsAThirdConstant = 1.94
Which is recommended Scala style?
The officially recommended style (and I do mean officially) is the first style, camel case with first letter are upper case. It's laid down clearly by Odersky on Programming in Scala.
The style is also followed by the standard library, and has some support in language semantics: identifiers starting with upper case are treated as constants in pattern matching.
(Section 6.10, p. 107 in the second edition)
(This is an addendum comment to Daniel's answer, but I'm posting it as an answer for the benefit of syntax highlighting and formatting.)
Daniel's point about the style of using an initial capital letter being important in the language semantics is more subtle and important than I originally gave it credit for when I learned Scala.
Consider the following code:
object Case {
val lowerConst = "lower"
val UpperConst = "UPPER"
def main(args: Array[String]) {
for (i <- Seq(lowerConst, UpperConst, "should mismatch.").map(Option.apply)) {
print("Input '%s' results in: ".format(i))
i match {
case Some(UpperConst) => println("UPPER!!!")
case Some(lowerConst) => println("lower!")
case _ => println("mismatch!")
}
}
}
}
Naively I would have expected that to reach all of the cases in the match. Instead it prints:
Input 'Some(lower)' results in: lower!
Input 'Some(UPPER)' results in: UPPER!!!
Input 'Some(should mismatch.)' results in: lower!
What's going on is that the case Some(lowerConst) shadows the val lowerConst and creates a local variable of the same name which will be populated any time a Some containing a string is evaluated.
There are admittedly ways to work around it, but the simplest is to follow the style guide for constant naming.
If you can't follow the naming convention, then as #reggoodwin points out in the comments below, you can put the variable name in ticks, like so
case Some(`lowerConst`) => println("lower!")
Constant names should be in upper camel case. That is, if the member
is final, immutable and it belongs to a package object or an object,
it may be considered a constant .... Method, Value and variable names should be in lower camel case
http://docs.scala-lang.org/style/naming-conventions.html#constants-values-variable-and-methods

Why does Scala choose to have the types after the variable names?

In Scala variables are declared like:
var stockPrice: Double = 100.
Where the type (Double) follows the identifier (stockPrice). Traditionally in imperative languages such as C, Java, C#, the type name precedes the identifier.
double stock_price = 100.0;
Is it purely a matter of taste, or does having the type name in the end help the compiler in any way? Go also has the same style.
Kevin's got it right. The main observation is that the "type name" syntax works great as long as types are short keywords such as int or float:
int x = 1
float d = 0.0
For the price of one you get two pieces of information: "A new definition starts here", and "here's the (result) type of the definition". But we are way past the area of simple primitive types nowadays. If you write
HashMap<Shape, Pair<String, String>> shapeInfo = makeInfo()
the most important part of what you define (the name) is buried behind the type expression. Compare with
val shapeInfo: HashMap[Shape, (String, String)] = makeInfo()
It says clearly
We define a value here, not a variable or method (val)
The name of the thing we define is shapeInfo
If you care about it, here's the type (HashMap[...])
As well as supporting type inference, this has an ergonomic benefit too.
For any given variable name + type, chances are that the name is the more important piece of information. Moving it to the left makes it more prominent, and the code more readable once you're accustomed to the style.
Other ergonomic benefits:
With val, var or def before member names, instead of their type, they all neatly line up in a column.
If you change just the type of a member, or drop it entirely in favour of inference, then a fine-grained diff tool will clearly show that the name is unaltered
Likewise, changing between a val/var/def is very clear in diffs
inference should be considered default behaviour in Scala, you only need type specifications in certain specific scenarios, even then it's mostly done for the compiler. So putting them at the very start of a declaration emphasises the wrong thing.
"name: Type" instead of "Type name" more closely matches the way most programmers will actually think about a declaration, it's more natural.
The differing C/C++ and Java conventions for pointers and arrays (i.e * being a prefix on the following name and not a suffix on the preceeding type in C/C++, or [] being a valid suffix on both names and types in Java) are still confusing to newcomers or language converts, and cause some very real errors when declaring multiple variables on a single line. Scala leaves no room for doubt and confusion here.
It's afterwards so that it can be removed for type inference:
var stockPrice: Double = 100.0
var stockPrice = 100.0
However, it is not true that imperative languages traditionally have types first. For example, Pascal doesn't.
Now, C does it, and C++, Java and C# are based on C's syntax, so naturally they do it that way too, but that has absolutely nothing to do with imperative languages.
It should be noted that even C doesn't "traditionally" define the type before the variable name, but indeed allows the declarations to be interleaved.
int foo[];
where the type for foo is declared both before and after it, lexically.
Beyond that, I'm guessing this is a distinction without a difference. The compiler developers certainly couldn't care one way or another.