Underscores in numeric literals in scala - scala

Apparently scala does not support the jdk7 and later underscores in numeric literals?
I am using jdk 8
scala> System.getProperty("java.version")
res0: String = 1.8.0_40
Here we try to use a jdk7 (and later) numeric literal:
scala> val x = 1_000_000
<console>:1: error: Invalid literal number
val x = 1_000_000
^
Is there a scala language option for this?

In the Scala land you may have seen things like:
s"My name is $firstName"
and
sql"select id, name from members where id = ${id}"
There's no reason not to have:
i"1 000 000"
or even:
animal"Dog" // checks that Dog is on the list of animal words
There is no i string interpolation built in to the Scala library however you can use:
implicit class IntContext(val sc: StringContext) {
def i(args: Any*): Int = {
val orig = sc.s(args: _*)
orig.replace(" ", "").toInt
}
}
i"1 000 000" // res0: Int = 1000000

Note that starting Scala 2.13, underscore is accepted as a numeric literal separator:
val x = 1_000_000
// x: Int = 1000000
val pi = 3_14e-0_2
// pi: Double = 3.14

You can now write lengthy numeric literals that have a great readability score many thanks to the update done in Java 7. Read More on Adeva's blog https://adevait.com/java/5-best-and-worst-practices-in-java-coding
Before using Underscore:
int minUploadSize = 05437326;
long debitBalance = 5000000000000000L;
float pi = 3.141592653589F;
After making use of Underscore:
int minUploadSize = 05_437_326;
long debitBalance = 5_000_000_000_000_000L;
float pi = 3.141_592_653_589F;
The above-written declarations in Java show the importance of using underscores in numeric literals to improve the readability of codes. When you compare the two declarations above, you would be able to deduce that the one with included underscores is more readable compared to the other one.

Related

Nulls in Scala ...why is this possible?

I was coding in Scala and doing some quick refactoring in Intellij, when I stumbled upon the following piece of weirdness...
package misc
/**
* Created by abimbola on 05/10/15.
*/
object WTF extends App {
val name: String = name
println(s"Value is: $name")
}
I then noticed that the compiler didn't complain, so I decided to attempt to run this and I got a very interesting output
Value is: null
Process finished with exit code 0
Can anyone tell me why this works?
EDIT:
First problem, the value name is assigned a reference to itself even though it does not exist yet; why exactly does the Scala compiler not explode with errors???
Why is the value of the assignment null?
1.) Why does the compiler not explode
Here is a reduced example. This compiles because through given type a default value can be inferred:
class Example { val x: Int = x }
scalac Example.scala
Example.scala:1: warning: value x in class Example does nothing other than call itself recursively
class Example { val x: Int = x }
This does not compile because no default value can be inferred:
class ExampleDoesNotCompile { def x = x }
scalac ExampleDoesNotCompile.scala
ExampleDoesNotCompile.scala:1: error: recursive method x needs result type
class ExampleDoesNotCompile { def x = x }
1.1 What happens here
My interpretation. So beware: The uniform access principle kicks in.
The assignment to the val x calls the accessor x() which returns the unitialized value of x.
So x is set to the default value.
class Example { val x: Int = x }
^
[[syntax trees at end of cleanup]] // Example.scala
package <empty> {
class Example extends Object {
private[this] val x: Int = _;
<stable> <accessor> def x(): Int = Example.this.x;
def <init>(): Example = {
Example.super.<init>();
Example.this.x = Example.this.x();
()
}
}
} ^
2.) Why the value is null
The default values are determined by the environment Scala is compiled to.
In the example you have given it looks like you run on the JVM. The default value for Object here is null.
So when you do not provide a value the default value is used as a fallback.
Default values JVM:
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char '\u0000'
boolean false
Object null // String are objects.
Also the default value is a valid value for given type:
Here is an example in the REPL:
scala> val x : Int = 0
x: Int = 0
scala> val x : Int = null
<console>:10: error: an expression of type Null is ineligible for implicit conversion
val x : Int = null
^
scala> val x : String = null
x: String = null
why exactly does the Scala compiler not explode with errors?
Because this problem can't be solved in the general case. Do you know the halting problem? The halting problem says that it is not possible to write an algorithm that finds out if a program ever halts. Since the problem of finding out if a recursive definition would result in a null assignment can be reduced to the halting problem, it is also not possible to solve it.
Well, now it is quite easy to forbid recursive definitions at all, this is for example done for values that are no class values:
scala> def f = { val k: String = k+"abc" }
<console>:11: error: forward reference extends over definition of value k
def f = { val k: String = k+"abc" }
^
For class values this feature is not forbidden for a few reasons:
Their scope is not limited
The JVM initializes them with a default value (which is null for reference types).
Recursive values are useful
Your use case is trivial, as is this:
scala> val k: String = k+"abc"
k: String = nullabc
But what about this:
scala> object X { val x: Int = Y.y+1 }; object Y { val y: Int = X.x+1 }
defined object X
defined object Y
scala> X.x
res2: Int = 2
scala> Y.y
res3: Int = 1
scala> object X { val x: Int = Y.y+1 }; object Y { val y: Int = X.x+1 }
defined object X
defined object Y
scala> Y.y
res4: Int = 2
scala> X.x
res5: Int = 1
Or this:
scala> val f: Stream[BigInt] = 1 #:: 1 #:: f.zip(f.tail).map { case (a,b) => a+b }
f: Stream[BigInt] = Stream(1, ?)
scala> f.take(10).toList
res7: List[BigInt] = List(1, 1, 2, 3, 5, 8, 13, 21, 34, 55)
As you can see it is quite easy to write programs where it is not obvious anymore to which value they will result. And since the halting problem is not solvable we can not let the compiler do the work for us in non trivial cases.
This also means that trivial cases, as the one shown in your question, could be hardcoded in the compiler. But since there can't exist a algorithm that can detect all possible trivial cases, all cases that are ever found need to be hardcoded in the compiler (not to mention that a definition of a trivial case does not exist). Therefore it wouldn't be wise to even start hardcoding some of these cases. It would ultimately result in a slower compiler and a compiler that is more difficult to maintain.
One could argue that for an use case that burns every second user it would be wise to at least hardcode such an extreme scenario. On the other hand, some people just need to be burned in order to learn something new. ;)
I think #Andreas' answer already has the necessary info. I'll just try to provide additional explanation:
When you write val name: String = name at the class level, this does a few different things at the same time:
create the field name
create the getter name()
create code for the assignment name = name, which becomes part of the primary constructor
This is what's made explicit by Andreas' 1.1
package <empty> {
class Example extends Object {
private[this] val x: Int = _;
<stable> <accessor> def x(): Int = Example.this.x;
def <init>(): Example = {
Example.super.<init>();
Example.this.x = Example.this.x();
()
}
}
}
The syntax is not Scala, it is (as suggested by [[syntax trees at end of cleanup]]) a textual representation of what the compiler will later convert into bytecode. Some unfamiliar syntax aside, we can interpret this, like the JVM would:
the JVM creates an object. At this point, all fields have default values. val x: Int = _; is like int x; in Java, i.e. the JVM's default value is used, which is 0 for I (i.e. int in Java, or Int in Scala)
the constructor is called for the object
(the super constructor is called)
the constructor calls x()
x() returns x, which is 0
x is assigned 0
the constructor returns
as you can see, after the initial parsing step, there is nothing in the syntax tree that seems immediately wrong, even though the original source code looks wrong. I wouldn't say that this is the behavior I expect, so I would imagine one of three things:
Either, the Scala devs saw it as too intricate to recognize and forbid
or, it's a regression and simply wasn't found as a bug
or, it's a "feature" and there is legitimate need for this behavior
(ordering reflects my opinion of likeliness, in decreasing order)

Underscore usage in Scala's identifier

I have a class with getter/setter:
class Person {
private var _age = 0
//getter
def age = _age
//setter
def age_=(value: Int): Unit = _age = value
}
We know that we can invoke setter method like this:
val p = new Person()
p.age= (2)
p age= 11
p.age= 8-4
What made interesthing in this case is: the underscore (_) in def age_= can be removed when the method is invoked.
My question is what is the underscore used for in this case?
Someone told me it is used to separate non-alphanum character in identifier. So I tried this:
var x_= = 20
x_= = 10
x= = 5 // I got error here
Why I can't remove the underscore in this case?
Also, if I tried to use the underscore more than once:
val x_=_x = 1
I got compile error too.
Is there a rule about the underscore usage and what is the term for this underscore usage?
The compile error says it all, really:
scala> var x_= = 20
<console>:10: error: Names of vals or vars may not end in `_='
Only methods are allowed to have names ending in _=. This makes sense, because it would be really confusing to allow a val to be named x_=
However it is true that the underscore is used to separate alpha-numeric characters from special characters. It's just that in the case of a val or var, you can't end it with =
scala> var x_# = 20
x_#: Int = 20
scala> x_# = 10
x_$hash: Int = 10
I don't think another underscore is allowed after the first underscore that precedes special characters.
val x_y_^ = 1 // Ok
val x_^_^ = 1 // Not ok
Based on the Scala language spec :
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.
See also Example 1.1.1 in the linked specification for examples of valid identifiers.

Expressing square in Scala

For some reason (that escapes me), Scala math library does not have a pow-function for integers, but only for Doubles.
I need a square function for integers and was figuring what might be the usual way to do this in Scala.
object TestX extends App {
def pow2(v: Int)= v*v
//class MyRichInt( val v: Int ) {
// def ² : Int = v*v // says: "illegal character" for UTF-8 power-of-two
//}
println( pow2(42) )
//println( 42² )
println( math.pow(42,2).toInt )
}
I was surprised to see that the '²' character is not liked by Scala. Maybe it's taken to be a number? Usually all kinds of weird Unicode values are valid and using 42² in code would, indeed, be fancy.
Never mind. Should I shut up and just start using my own pow2 function?
Yes, use your own pow2. If you need higher powers, you probably won't have room in an Int anyway. Consider using BigInt.pow:
scala> BigInt(40).pow(40)
res0: scala.math.BigInt = 12089258196146291747061760000000000000000000000000000000000000000
Of course, if you need not N2 but 2N, just use shifts. (1 << k = 2k) These work with BigInt also.
Use backticks for Unicode characters, and implicit classes (Scala 2.10) to add operation on arbitrary types:
implicit class PowerInt(i: Int) {
def `²`: Int = i * i
}
Usage:
3 `²`
Result:
9

String interpolation in Scala 2.10 - How to interpolate a String variable?

String interpolation is available in Scala starting Scala 2.10
This is the basic example
val name = "World" //> name : String = World
val message = s"Hello $name" //> message : String = Hello World
I was wondering if there is a way to do dynamic interpolation, e.g. the following (doesn't compile, just for illustration purposes)
val name = "World" //> name : String = World
val template = "Hello $name" //> template : String = Hello $name
//just for illustration:
val message = s(template) //> doesn't compile (not found: value s)
Is there a way to "dynamically" evaluate a String like that? (or is it inherently wrong / not possible)
And what is s exactly? it's not a method def (apparently it is a method on StringContext), and not an object (if it was, it would have thrown a different compile error than not found I think)
s is actually a method on StringContext (or something which can be implicitly converted from StringContext). When you write
whatever"Here is text $identifier and more text"
the compiler desugars it into
StringContext("Here is text ", " and more text").whatever(identifier)
By default, StringContext gives you s, f, and raw* methods.
As you can see, the compiler itself picks out the name and gives it to the method. Since this happens at compile time, you can't sensibly do it dynamically--the compiler doesn't have information about variable names at runtime.
You can use vars, however, so you can swap in values that you want. And the default s method just calls toString (as you'd expect) so you can play games like
class PrintCounter {
var i = 0
override def toString = { val ans = i.toString; i += 1; ans }
}
val pc = new PrintCounter
def pr[A](a: A) { println(s"$pc: $a") }
scala> List("salmon","herring").foreach(pr)
1: salmon
2: herring
(0 was already called by the REPL in this example).
That's about the best you can do.
*raw is broken and isn't slated to be fixed until 2.10.1; only text before a variable is actually raw (no escape processing). So hold off on using that one until 2.10.1 is out, or look at the source code and define your own. By default, there is no escape processing, so defining your own is pretty easy.
Here is a possible solution to #1 in the context of the original question based on Rex's excellent answer
val name = "World" //> name: String = World
val template = name=>s"Hello $name" //> template: Seq[Any]=>String = <function1>
val message = template(name) //> message: String = Hello World
String interpolation happens at compile time, so the compiler does not generally have enough information to interpolate s(str). It expects a string literal, according to the SIP.
Under Advanced Usage in the documentation you linked, it is explained that an expression of the form id"Hello $name ." is translated at compile time to new StringContext("Hello", "."). id(name).
Note that id can be a user-defined interpolator introduced through an implicit class. The documentation gives an example for a json interpolator,
implicit class JsonHelper(val sc: StringContext) extends AnyVal {
def json(args: Any*): JSONObject = {
...
}
}
This is inherently impossible in the current implementation: local variable names are not available at execution time -- may be kept around as debug symbols, but can also have been stripped. (Member variable names are, but that's not what you're describing here).

How to write binary literals in Scala?

Scala has direct support for using hex and octal numbers:
scala> 01267 + 0100
res1: Int = 759
scala> 0x12AF + 0x100
res2: Int = 5039
but how do you do express an integer as a binary number in Scala ?.
If performance is not an issue, you can use a String and convert it to an integer.
val x = Integer.parseInt("01010101", 2)
Binary numbers aren't supported directly in part because you can easily convert from hexadecimal to binary and vice versa. To make your code clearer, you can put the binary number in a comment.
val x = 0x55 //01010101
In 2.10 you can create a string interpolator for that, e.g. it's possible to write b"0010" to mean 2. Using macros you can get rid of associated runtime overhead and do the conversion at compile-time. Take a look at Jason Zaugg's macrocosm to see it in action:
scala> b"101010"
res4: Int = 42
scala> b"102"
<console>:11: error: exception during macro expansion: invalid binary literal
b"102"
^
Using the new "implicit class" and "value class" mechanisms in 2.10, you can write something like this to add convenience methods without the overhead of object creation:
implicit class IntToBase( val digits:String ) extends AnyVal {
def base(b:Int) = Integer.parseInt( digits, b )
def b = base(2)
def o = base(8)
def x = base(16)
}
That allows you to do things like
"555".o // 365 decimal
and no IntToBase object is ever actually created.
You would need to be careful if you're converting from an integer that "looks like" binary as #agilesteel suggests. For example 0101.b would try to convert 65 decimal to binary (initial 0 signifying octal), whereas 101.b would try to convert 101 decimal to binary. It only really makes sense to try to convert from a String, for which there is Integer.parseInt, and from a number to the binary String representation, for which there is Integer.toString(x, 2).
I can't think of too many use-cases for programmatic binary literals. That said, they've made it to Java 7 as a number with prefix 0b, so I'd be surprised if they didn't appear in Scala soon. Java seems to have done fine without them for 15 years though.
If you are planning on using it a lot you can simulate the behavior with an implicit conversion.
object Extensions {
implicit def conversion(x: Int) = new BinaryInt(x)
class BinaryInt(x: Int) {
def b = {
// Conversion code like Integer.parseInt
// as Kim suggested
}
}
}
Now you can do stuff like
import Extensions._
val x = 0101.b
// or
val x = 5.b
You have to decide for yourself, which direction the conversion should go.
If you want to get a string of the binary representation of an Int you can call 4.toBinaryString. Padding is more difficult. You'll have to do something like: 4.toBinaryString.reverse.padTo(8, "0").reverse.mkString
def _0b(row: Int): Int = {
row.toString
.reverse
.split("")
.zipWithIndex
.map(x => (x._1.toInt, x._2))
.filter(_._1 == 1)
.map(x => Math.pow(2,x._2).toInt)
.sum
}
_0b(10011001) = 153
Though it is limited to 32Bit Values