Why no i++ in Scala? - scala
I just wonder why there is no i++ to increase a number. As what I know, languages like Ruby or Python doesn't support it because they are dynamically typed. So it's obviously we cannot write code like i++ because maybe i is a string or something else. But Scala is statically typed - the compiler absolutely can infer that if it is legal or not to put ++ behind a variable.
So, why doesn't i++ exist in Scala?
Scala doesn't have i++ because it's a functional language, and in functional languages, operations with side effects are avoided (in a purely functional language, no side effects are permitted at all). The side effect of i++ is that i is now 1 larger than it was before. Instead, you should try to use immutable objects (e.g. val not var).
Also, Scala doesn't really need i++ because of the control flow constructs it provides. In Java and others, you need i++ often to construct while and for loops that iterate over arrays. However, in Scala, you can just say what you mean: for(x <- someArray) or someArray.foreach or something along those lines. i++ is useful in imperative programming, but when you get to a higher level, it's rarely necessary (in Python, I've never found myself needing it once).
You're spot on that ++ could be in Scala, but it's not because it's not necessary and would just clog up the syntax. If you really need it, say i += 1, but because Scala calls for programming with immutables and rich control flow more often, you should rarely need to. You certainly could define it yourself, as operators are indeed just methods in Scala.
Of course you can have that in Scala, if you really want:
import scalaz._, Scalaz._
case class IncLens[S,N](lens: Lens[S,N], num: Numeric[N]) {
def ++ = lens.mods(num.plus(_, num.one))
}
implicit def incLens[S,N: Numeric](lens: Lens[S,N]) =
IncLens[S,N](lens, implicitly[Numeric[N]])
val i = Lens.lensu[Int,Int]((x, y) => y, identity)
val imperativeProgram = for {
_ <- i++;
_ <- i++;
x <- i++
} yield x
def runProgram = imperativeProgram exec 0
And here you go:
scala> runProgram
res26: scalaz.Id.Id[Int] = 3
No need to resort to violence against variables.
Scala is perfectly capable of parsing i++ and, with a small modification to the language, could be made to modify a variable. But there are a variety of reasons not to.
First, it saves only one character, i++ vs. i+=1, which is not very much savings for adding a new language feature.
Second, the ++ operator is widely used in the collections library, where xs ++ ys takes collection xs and ys and produces a new collection that contains both.
Third, Scala tries to encourage you, without forcing you, to write code in a functional way. i++ is a mutable operation, so it's inconsistent with the idea of Scala to make it especially easy. (Likewise with a language feature that would allow ++ to mutate a variable.)
Scala doesn't have a ++ operator because it is not possible to implement one in it.
EDIT: As just pointed out in response to this answer, Scala 2.10.0 can implement an increment operator through use of macros. See this answer for details, and take everything below as being pre-Scala 2.10.0.
Let me elaborate on this, and I'll rely heavily on Java, since it actually suffers from the same problem, but it might be easier for people to understand it if I use a Java example.
To start, it is important to note that one of the goals of Scala is that the "built-in" classes must not have any capability that could not be duplicated by a library. And, of course, in Scala an Int is a class, whereas in Java an int is a primitive -- a type entirely distinct from a class.
So, for Scala to support i++ for i of type Int, I should be able to create my own class MyInt also supporting the same method. This is one of the driving design goals of Scala.
Now, naturally, Java does not support symbols as method names, so let's just call it incr(). Our intent then is to try to create a method incr() such that y.incr() works just like i++.
Here's a first pass at it:
public class Incrementable {
private int n;
public Incrementable(int n) {
this.n = n;
}
public void incr() {
n++;
}
#Override
public String toString() {
return "Incrementable("+n+")";
}
}
We can test it with this:
public class DemoIncrementable {
static public void main(String[] args) {
Incrementable i = new Incrementable(0);
System.out.println(i);
i.incr();
System.out.println(i);
}
}
Everything seems to work, too:
Incrementable(0)
Incrementable(1)
And, now, I'll show what the problem is. Let's change our demo program, and make it compare Incrementable to int:
public class DemoIncrementable {
static public void main(String[] args) {
Incrementable i = new Incrementable(0);
Incrementable j = i;
int k = 0;
int l = 0;
System.out.println("i\t\tj\t\tk\tl");
System.out.println(i+"\t"+j+"\t"+k+"\t"+l);
i.incr();
k++;
System.out.println(i+"\t"+j+"\t"+k+"\t"+l);
}
}
As we can see in the output, Incrementable and int are behaving differently:
i j k l
Incrementable(0) Incrementable(0) 0 0
Incrementable(1) Incrementable(1) 1 0
The problem is that we implemented incr() by mutating Incrementable, which is not how primitives work. Incrementable needs to be immutable, which means that incr() must produce a new object. Let's do a naive change:
public Incrementable incr() {
return new Incrementable(n + 1);
}
However, this doesn't work:
i j k l
Incrementable(0) Incrementable(0) 0 0
Incrementable(0) Incrementable(0) 1 0
The problem is that, while, incr() created a new object, that new object hasn't been assigned to i. There's no existing mechanism in Java -- or Scala -- that would allow us to implement this method with the exact same semantics as ++.
Now, that doesn't mean it would be impossible for Scala to make such a thing possible. If Scala supported parameter passing by reference (see "call by reference" in this wikipedia article), like C++ does, then we could implement it!
Here's a fictitious implementation, assuming the same by-reference notation as in C++.
implicit def toIncr(Int &n) = {
def ++ = { val tmp = n; n += 1; tmp }
def prefix_++ = { n += 1; n }
}
This would either require JVM support or some serious mechanics on the Scala compiler.
In fact, Scala does something similar to what would be needed that when it create closures -- and one of the consequences is that the original Int becomes boxed, with possibly serious performance impact.
For example, consider this method:
def f(l: List[Int]): Int = {
var sum = 0
l foreach { n => sum += n }
sum
}
The code being passed to foreach, { n => sum += n }, is not part of this method. The method foreach takes an object of the type Function1 whose apply method implements that little code. That means { n => sum += n } is not only on a different method, it is on a different class altogether! And yet, it can change the value of sum just like a ++ operator would need to.
If we use javap to look at it, we'll see this:
public int f(scala.collection.immutable.List);
Code:
0: new #7; //class scala/runtime/IntRef
3: dup
4: iconst_0
5: invokespecial #12; //Method scala/runtime/IntRef."<init>":(I)V
8: astore_2
9: aload_1
10: new #14; //class tst$$anonfun$f$1
13: dup
14: aload_0
15: aload_2
16: invokespecial #17; //Method tst$$anonfun$f$1."<init>":(Ltst;Lscala/runtime/IntRef;)V
19: invokeinterface #23, 2; //InterfaceMethod scala/collection/LinearSeqOptimized.foreach:(Lscala/Function1;)V
24: aload_2
25: getfield #27; //Field scala/runtime/IntRef.elem:I
28: ireturn
Note that instead of creating an int local variable, it creates an IntRef on the heap (at 0), which is boxing the int. The real int is inside IntRef.elem, as we see on 25. Let's see this same thing implemented with a while loop to make clear the difference:
def f(l: List[Int]): Int = {
var sum = 0
var next = l
while (next.nonEmpty) {
sum += next.head
next = next.tail
}
sum
}
That becomes:
public int f(scala.collection.immutable.List);
Code:
0: iconst_0
1: istore_2
2: aload_1
3: astore_3
4: aload_3
5: invokeinterface #12, 1; //InterfaceMethod scala/collection/TraversableOnce.nonEmpty:()Z
10: ifeq 38
13: iload_2
14: aload_3
15: invokeinterface #18, 1; //InterfaceMethod scala/collection/IterableLike.head:()Ljava/lang/Object;
20: invokestatic #24; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
23: iadd
24: istore_2
25: aload_3
26: invokeinterface #29, 1; //InterfaceMethod scala/collection/TraversableLike.tail:()Ljava/lang/Object;
31: checkcast #31; //class scala/collection/immutable/List
34: astore_3
35: goto 4
38: iload_2
39: ireturn
No object creation above, no need to get something from the heap.
So, to conclude, Scala would need additional capabilities to support an increment operator that could be defined by the user, as it avoids giving its own built-in classes capabilities not available to external libraries. One such capability is passing parameters by-reference, but JVM does not provide support for it. Scala does something similar to call by-reference, and to do so it uses boxing, which would seriously impact performance (something that would most likely come up with an increment operator!). In the absence of JVM support, therefore, that isn't much likely.
As an additional note, Scala has a distinct functional slant, privileging immutability and referential transparency over mutability and side effects. The sole purpose of call by-reference is to cause side effects on the caller! While doing so can bring performance advantages in a number of situations, it goes very much against the grain of Scala, so I doubt call by-reference will ever be part of it.
Other answers have already correctly pointed out that a ++ operator is neither particularly useful nor desirable in a functional programming language. I would like to add that since Scala 2.10, you can add a ++ operator, if you want to. Here is how:
You need an implicit macro that converts ints to instances of something that has a ++ method. The ++ method is "written" by the macro, which has access to the variable (as opposed to its value) on which the ++ method is called. Here is the macro implementation:
trait Incrementer {
def ++ : Int
}
implicit def withPp(i:Int):Incrementer = macro withPpImpl
def withPpImpl(c:Context)(i:c.Expr[Int]):c.Expr[Incrementer] = {
import c.universe._
val id = i.tree
val f = c.Expr[()=>Unit](Function(
List(),
Assign(
id,
Apply(
Select(
id,
newTermName("$plus")
),
List(
Literal(Constant(1))
)
)
)
))
reify(new Incrementer {
def ++ = {
val res = i.splice
f.splice.apply
res
}
})
}
Now, as long as the implicit conversion macro is in scope, you can write
var i = 0
println(i++) //prints 0
println(i) //prints 1
Rafe's answer is true about the rationale for why something like i++ doesn't belong in Scala. However I have one nitpick. It's actually not possible to implement i++ in Scala without changing the language.
In Scala, ++ is a valid method, and no method implies assignment. Only = can do that.
Languages like C++ and Java treat ++ specially to mean both increment and assign. Scala treats = specially, and in an inconsistent way.
In Scala when you write i += 1 the compiler first looks for a method called += on the Int. It's not there so next it does it's magic on = and tries to compile the line as if it read i = i + 1. If you write i++ then Scala will call the method ++ on i and assign the result to... nothing. Because only = means assignment. You could write i ++= 1 but that kind of defeats the purpose.
The fact that Scala supports method names like += is already controversial and some people think it's operator overloading. They could have added special behavior for ++ but then it would no longer be a valid method name (like =) and it would be one more thing to remember.
Quite a few languages do not support the ++ notation, such as Lua. In languages in which it is supported, it is frequently a source of confusion and bugs, so it's quality as a language feature is dubious, and compared to the alternative of i += 1 or even just i = i + 1, the saving of such minor characters is fairly pointless.
This is not at all relevant to the type system of the language. While it's true that most static type languages do offer and most dynamic types don't, that's a correlation and definitely not a cause.
Scala encourages using of FP style, which i++ certainly is not.
The question to ask is why there should be such an operator, not why there shouldn't be. Would Scala be improved by it?
The ++ operator is single-purpose, and having an operator that can change the value of a variable can cause problems. It's easy to write confusing expressions, and even if the language defines what i = i + i++ means, for example, that's a lot of detailed rules to remember.
Your reasoning on Python and Ruby is wrong, by the way. In Perl, you can write $i++ or ++$i just fine. If $i turns out to be something that can't be incremented, you get a run-time error. It isn't in Python or Ruby because the language designers didn't think it was a good idea, not because they're dynamically typed like Perl.
You could simulate it, though. As a trivial example:
scala> case class IncInt(var self: Int = 0) { def ++ { self += 1 } }
defined class IncInt
scala> val i = IncInt()
i: IncInt = IncInt(0)
scala> i++
scala> i++
scala> i
res28: IncInt = IncInt(2)
Add some implicit conversions and you're good to go. However, this sort of changes the question into: why isn't there a mutable RichInt with this functionality?
As another answer suggests, the increment operator, as found in i++, was—
supposedly ... added to the B language [a predecessor of the C language] by Ken Thompson specifically because [it was] capable of translating directly to a single opcode once compiled
and not necessarily because such an operator is as useful to have as, say, general addition and subtraction. Although certain object-oriented languages (such as Java and C#) also have an increment operator (often borrowed from C), not all do (such as Ruby).
Related
Does lambda () => 1 result in object creation at run time each time it is passed as an argument?
My understanding was that all non-capturing lambdas shouldn't require object creation at use site, because one can be created as a static field and reused. In principle, the same could be true for lambdas constituting of a class method call - only the field would be non static. I never actually tried to dig any deeper into it; now I am looking at the bytecode, don't see one in the enclosing class and don't have a good idea where to look? I see though that the lambda factory is different than in Java, so this should have a clear answer - at least for a given Scala version. My motivation is simple: profiling is very time consuming. Introducing method values (or in general, lambdas capturing only the state of the enclosing object) as private class fields is less clean and more work than writing them inline and, in general, not good code. But when writing areas known (with high likelihood) to be a hot spot, it's a very simple optimisation that can be performed straight away without any real impact on the programmer's time. It doesn't make sense though if no new object is created anyway. Take for example: def alias(x :X) = aliases.getOrElse(x, x) def alias2(x :X) = aliases.getOrElse(x, null) match { case null => x case a => a } The first lambda (a Function0) must be a new object because it captures method parameter x, while the second one returns a constant (null) and thus doesn't really have to. It is also less messy (IMO) than a private class field, which pollutes the namespace, but I would like to be able to know for sure - or have a way of easily confirming my expectations.
The following proves that at least some of the time, the answer is "no": scala 2.13.4> def foo = () => 1 def foo: () => Int scala 2.13.4> foo eq foo val res5: Boolean = true
Looking at the bytecode produced by this code: import scala.collection.immutable.ListMap object ByName { def aliases = ListMap("Ein" -> "One", "Zwei" -> "Two", "Drei" -> "Three") val default = "NaN" def alias(x: String) = aliases.getOrElse(x, x) def alias2(x: String) = aliases.getOrElse(x, null) match { case null => x case a => a } def alias3(x: String) = aliases.getOrElse(x, default) } The compiler generates static methods for the by-name parameters. They look like this: public static final java.lang.String $anonfun$alias$1(java.lang.String); Code: 0: aload_0 1: areturn public static final scala.runtime.Null$ $anonfun$alias2$1(); Code: 0: aconst_null 1: areturn public static final java.lang.String $anonfun$alias3$1(); Code: 0: getstatic #26 // Field MODULE$:LByName$; 3: invokevirtual #138 // Method default:()Ljava/lang/String; 6: areturn The naive approach would have been for the compiler to generate anonymous classes that implement the Function0 interface. However, this would cause bytecode-bloat. Instead the compiler defers creating these anonymous inner classes until runtime via invokedynamic instructions. Exactly how Scala uses these invokedynamic instructions is beyond my knowledge. It's possible that they cache the generated Function0 object somehow, but my guess is that the invokedynamic call is sufficiently optimized that it's faster to just generate a new one every time. Allocating short lived objects is cheap, and the cost is most often overestimated. Reusing an existing object might even be slower than creating a new one if it means cache misses. I also want to point out that this is a implementation detail, and likely to change at any time. The Scala compiler devs and JVM devs know what they are doing, so you are probably better off trusting that their implementation balances performance well.
Scala: understanding how to make my method return the proper return type of Array
I have written the following Scala code: class MyTestApi { private def toCPArray(inputStr: String): Array[Int] = { val len = inputStr.length //invoke ofDim of Scala.Array val cpArray = Array.ofDim[Int](inputStr.codePointCount(0, len)) var i = 0 var j = 0 while (i < len) { cpArray(j += 1) = inputStr.codePointAt(i) i = inputStr.offsetByCodePoints(i, 1) } cpArray } } This is what I want to accomplish: I would create an instance of class MyTestApi and then invoke the method toCPArray and pass to it a parameter of type String. I would then like this method to return me an `Array[Int]. However as it stands now, the Scala IDE is complaining about this line: **cpArray(j += 1) = inputStr.codePointAt(i)** type mismatch; Found: Unit required: Int Two things I would like to accomplish are: How would I fix this method? (or is it a function) My hope is, after I understand what it takes to fix this method (or function) I will be able to return the appropriate type. Also, I should be in better position to understand the difference between a method and a function. So far my research on stackoverflow and Martin Odersky's book seems to suggests to me that what I wrote is a method because it is invokded on an instance of the underlying class. Is my understanding right on that? After it is fixed, how can i rewrite it in a more Scalaesque way, by getting rid of the var. The code looks more C or java like right now and is a little long in my opinion, after all that I have studied about Scala so far. Thanks for any help in refactoring the above code to accomplish my learning objectives.
You are calling cpArray.update with an assignment statement which evaluates to Unit when it expects an Integer. You need to call it with an Integer: j += 1 cpArray(j) = inputStr.codePointAt(i)
Many questions in one. I try to answer them all. First of all as Jörg pointed out, moving the assignment makes the code work. Contrary to Java and C, Scala's assignment doesn't return the assigned value but Unit. Now for making it idiomatic. Scala's String can be seem as IndexedSeq[Char], meaning you can generally treat them as IndexedSeqs. So you doing do something like: inputStr.map{ x => x.toInt }.toArray This will return an Array[Int]. Notice it will only work for 16-bits char representations. Hopefully it will help in giving an idea of idiomatic Scala, even not being a perfect solution. For the difference between methods and functions, it's simple: methods are generally defs in a class. Functions one the other hands are Objects in the JVM sense. For example, the above map could be defined like: def map(f: Function1[Char, Int]):IndexedSeq[Int] // or def map(f: Char => Int):IndexedSeq[Int] Both are the same, => desugars to one of the scala.FunctionN (N from 0 to 22 inclusive). And x => x.toInt is desugared in a similar way into a instance of scala.Function1. See it's Scaladoc. So, functions are objects of type scala.FunctionN. Note: to keep things simple I omitted a few details like type parameters, vals (which often compiles to JVM methods) and probably a few more details.
In Scala, is assignment operator "=" a method call?
As per Scala book, "Programming In Scala" - Scala is an object-oriented language in pure form: every value is an object and every operation is a method call. For example, when you say 1 + 2 in Scala, you are actually invoking a method named + defined in class Int. In that sense, what about assignment operation using "=" operator? Is that also a method? Seems unlikely, because then it has to be present in all classes or some common super class (say, java.lang.Object ?) that all classes have to inherit it from. Or is it that not all operations are really method calls in Scala?
A little addition to Jatin answer. There is one case when = can be considered as a method call, but actually it's just a syntactic sugar. In OO part of Scala, where ugly vars lives, you can write the following: class Test { private var x0: Int = 0 def x = x0 def x_=(a: Int) = x0 = a } Then you can assign new ints to x: scala> val t = new Test t: Test = Test#4166d6d3 scala> t.x = 1 t.x: Int = 1 The last line will be desugared into t.x_=(1). I think in this case, considering syntactic sugar, it's possible to say that = is a method call.
Nope. Assignment operator (=) is a reserved word. Also the below are: _ : = => <- <: <% >: # # For a more comprehensive list refer § 1.1. Some more information regarding = is described in § 6.12.4. So yes it is not a method call.
While the other answers are correct for standard Scala, there is a variant called Scala-Virtualized where = and other control structures are method calls.
Get arguments back from partially applied function in scala
Is there a way in scala to get the arguments back from a already partially applied function? Does this even make sense, should be done, or fits into any use case? example: def doStuff(lower:Int,upper:Int,b:String)= for(turn <- lower to upper) println(turn +": "+b) Imagine that at one point I know the 'lower' argument and I get a function of applying it to 'doStuff' val lowerDoStuff = doStuff(3,_:Int,_:String) Is there a way for me to get that 3 back ? (for the sake of example, imagine that I am inside a function which only received 'lowerDoStuff' and now needs to know the first argument) Idiomatic scala is prefered to introspection/reflection (if possible).
Idiomatic Scala: no, you can't. You have specifically said that the first argument is no longer relevant. If the compiler can make it disappear entirely, that's best: you say you have a function that depends on an int and a string, and you haven't made any promises about what generated it. If you really need that value, but you also really need to pass a 2-argument function, you can do it by hand: class Function2From3[A,B,C,Z](f: (A,B,C) => Z, val _1: A) extends Function2[B,C,Z] { def apply(b: B, c: C) = f(_1, b, c) } val lowerDoStuff = new Function2From3(doStuff _, 3) Now when you get the function later on, you can pattern match to see if it's a Function2From3, and then read the value: val f: Function2[Int,String,Unit] = lowerDoStuff f match { case g: Function2From3[_,_,_,_] => println("I know there's a "+g._1+" in there!") case _ => println("It's all Greek to me.") } (if it's important to you that it be an integer, you can remove A as a generic parameter and make _1 be an integer--and maybe just call it lower while you're at it). Reflection: no, you can't (not in general). The compiler's smarter than that. The generated bytecode (if we wrap your code in class FuncApp) is: public final void apply(int, java.lang.String); Signature: (ILjava/lang/String;)V Code: 0: aload_0 1: getfield #18; //Field $outer:LFuncApp; 4: iconst_3 5: iload_1 6: aload_2 7: invokevirtual #24; //Method FuncApp.doStuff:(IILjava/lang/String;)V 10: return Notice the iconst_3? That's where your 3 went--it disappeared into the bytecode. There's not even a hidden private field containing the value any more.
What is the difference between a var and val definition in Scala?
What is the difference between a var and val definition in Scala and why does the language need both? Why would you choose a val over a var and vice versa?
As so many others have said, the object assigned to a val cannot be replaced, and the object assigned to a var can. However, said object can have its internal state modified. For example: class A(n: Int) { var value = n } class B(n: Int) { val value = new A(n) } object Test { def main(args: Array[String]) { val x = new B(5) x = new B(6) // Doesn't work, because I can't replace the object created on the line above with this new one. x.value = new A(6) // Doesn't work, because I can't replace the object assigned to B.value for a new one. x.value.value = 6 // Works, because A.value can receive a new object. } } So, even though we can't change the object assigned to x, we could change the state of that object. At the root of it, however, there was a var. Now, immutability is a good thing for many reasons. First, if an object doesn't change internal state, you don't have to worry if some other part of your code is changing it. For example: x = new B(0) f(x) if (x.value.value == 0) println("f didn't do anything to x") else println("f did something to x") This becomes particularly important with multithreaded systems. In a multithreaded system, the following can happen: x = new B(1) f(x) if (x.value.value == 1) { print(x.value.value) // Can be different than 1! } If you use val exclusively, and only use immutable data structures (that is, avoid arrays, everything in scala.collection.mutable, etc.), you can rest assured this won't happen. That is, unless there's some code, perhaps even a framework, doing reflection tricks -- reflection can change "immutable" values, unfortunately. That's one reason, but there is another reason for it. When you use var, you can be tempted into reusing the same var for multiple purposes. This has some problems: It will be more difficult for people reading the code to know what is the value of a variable in a certain part of the code. You may forget to re-initialize the variable in some code path, and end up passing wrong values downstream in the code. Simply put, using val is safer and leads to more readable code. We can, then, go the other direction. If val is that better, why have var at all? Well, some languages did take that route, but there are situations in which mutability improves performance, a lot. For example, take an immutable Queue. When you either enqueue or dequeue things in it, you get a new Queue object. How then, would you go about processing all items in it? I'll go through that with an example. Let's say you have a queue of digits, and you want to compose a number out of them. For example, if I have a queue with 2, 1, 3, in that order, I want to get back the number 213. Let's first solve it with a mutable.Queue: def toNum(q: scala.collection.mutable.Queue[Int]) = { var num = 0 while (!q.isEmpty) { num *= 10 num += q.dequeue } num } This code is fast and easy to understand. Its main drawback is that the queue that is passed is modified by toNum, so you have to make a copy of it beforehand. That's the kind of object management that immutability makes you free from. Now, let's covert it to an immutable.Queue: def toNum(q: scala.collection.immutable.Queue[Int]) = { def recurse(qr: scala.collection.immutable.Queue[Int], num: Int): Int = { if (qr.isEmpty) num else { val (digit, newQ) = qr.dequeue recurse(newQ, num * 10 + digit) } } recurse(q, 0) } Because I can't reuse some variable to keep track of my num, like in the previous example, I need to resort to recursion. In this case, it is a tail-recursion, which has pretty good performance. But that is not always the case: sometimes there is just no good (readable, simple) tail recursion solution. Note, however, that I can rewrite that code to use an immutable.Queue and a var at the same time! For example: def toNum(q: scala.collection.immutable.Queue[Int]) = { var qr = q var num = 0 while (!qr.isEmpty) { val (digit, newQ) = qr.dequeue num *= 10 num += digit qr = newQ } num } This code is still efficient, does not require recursion, and you don't need to worry whether you have to make a copy of your queue or not before calling toNum. Naturally, I avoided reusing variables for other purposes, and no code outside this function sees them, so I don't need to worry about their values changing from one line to the next -- except when I explicitly do so. Scala opted to let the programmer do that, if the programmer deemed it to be the best solution. Other languages have chosen to make such code difficult. The price Scala (and any language with widespread mutability) pays is that the compiler doesn't have as much leeway in optimizing the code as it could otherwise. Java's answer to that is optimizing the code based on the run-time profile. We could go on and on about pros and cons to each side. Personally, I think Scala strikes the right balance, for now. It is not perfect, by far. I think both Clojure and Haskell have very interesting notions not adopted by Scala, but Scala has its own strengths as well. We'll see what comes up on the future.
val is final, that is, cannot be set. Think final in java.
In simple terms: var = variable val = variable + final
val means immutable and var means mutable. Full discussion.
The difference is that a var can be re-assigned to whereas a val cannot. The mutability, or otherwise of whatever is actually assigned, is a side issue: import collection.immutable import collection.mutable var m = immutable.Set("London", "Paris") m = immutable.Set("New York") //Reassignment - I have change the "value" at m. Whereas: val n = immutable.Set("London", "Paris") n = immutable.Set("New York") //Will not compile as n is a val. And hence: val n = mutable.Set("London", "Paris") n = mutable.Set("New York") //Will not compile, even though the type of n is mutable. If you are building a data structure and all of its fields are vals, then that data structure is therefore immutable, as its state cannot change.
Thinking in terms of C++, val x: T is analogous to constant pointer to non-constant data T* const x; while var x: T is analogous to non-constant pointer to non-constant data T* x; Favoring val over var increases immutability of the codebase which can facilitate its correctness, concurrency and understandability. To understand the meaning of having a constant pointer to non-constant data consider the following Scala snippet: val m = scala.collection.mutable.Map(1 -> "picard") m // res0: scala.collection.mutable.Map[Int,String] = HashMap(1 -> picard) Here the "pointer" val m is constant so we cannot re-assign it to point to something else like so m = n // error: reassignment to val however we can indeed change the non-constant data itself that m points to like so m.put(2, "worf") m // res1: scala.collection.mutable.Map[Int,String] = HashMap(1 -> picard, 2 -> worf)
"val means immutable and var means mutable." To paraphrase, "val means value and var means variable". A distinction that happens to be extremely important in computing (because those two concepts define the very essence of what programming is all about), and that OO has managed to blur almost completely, because in OO, the only axiom is that "everything is an object". And that as a consequence, lots of programmers these days tend not to understand/appreciate/recognize, because they have been brainwashed into "thinking the OO way" exclusively. Often leading to variable/mutable objects being used like everywhere, when value/immutable objects might/would often have been better.
val means immutable and var means mutable you can think val as java programming language final key world or c++ language const key world。
Val means its final, cannot be reassigned Whereas, Var can be reassigned later.
It's as simple as it name. var means it can vary val means invariable
Val - values are typed storage constants. Once created its value cant be re-assigned. a new value can be defined with keyword val. eg. val x: Int = 5 Here type is optional as scala can infer it from the assigned value. Var - variables are typed storage units which can be assigned values again as long as memory space is reserved. eg. var x: Int = 5 Data stored in both the storage units are automatically de-allocated by JVM once these are no longer needed. In scala values are preferred over variables due to stability these brings to the code particularly in concurrent and multithreaded code.
Though many have already answered the difference between Val and var. But one point to notice is that val is not exactly like final keyword. We can change the value of val using recursion but we can never change value of final. Final is more constant than Val. def factorial(num: Int): Int = { if(num == 0) 1 else factorial(num - 1) * num } Method parameters are by default val and at every call value is being changed.
In terms of javascript , it same as val -> const var -> var