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
Related
I have recently been relearning C++ as I develop a game in the Unreal engine. Its been about 3 years since I have touched C++, and I have been mostly using Java since then.
Due to the differences between java and c++ I can already tell there are different best practices for similar concepts.
I have 2 methods like this.
void UMarchingSquares::Generate(std::map<Vector2, int> automata) {
std::map<Vector2,ControlNode*> controlNodes = getControlNodes(automata);
}
std::map<Vector2,ControlNode*> UMarchingSquares::getControlNodes(std::map<Vector2, int> automata) {
std::map<Vector2,ControlNode*> controlNodes = std::map<Vector2, ControlNode*>();
for(pair<Vector2,int> pair : automata) {
Vector2 pos = pair.first;
ControlNode node = ControlNode(pos,pair.second);
controlNodes[pos] = &node;
}
return controlNodes;
}
I probably am breaking a few different C++ best practices, but there is one that I really want clarifications on one specific area.
I am initializing the ControlNode object in the getControlNodes() method's for loop. I know now that doing it this way is bad, because I am storing a pointer to a local variable, which then goes out of scope every loop iteration. I would prefer to store pointers instead of the actual Control node (though I may be convinced otherwise, since a Control Node holds a position [2 floats], a material [1 integer], and two other objects that both have a position and material of their own.)
What is the best way to create a non-local variable pointer? I know I can just use "new ControlNode()", but from what I know, that ends up being a fairly expensive call, and requires cleanup (which may be expensive as well).
I am going to be calling this part of the code fairly frequently, so I would like it to be efficient.
Thank you!
C++ changed a lot in the last few years to make life easier for those using it.
Looking at your code, it raises a lot of questions:
Why is the value of your map a raw pointer to ControlNode instead of a ControlNode by value or a unique_ptr to it
In your for-loop, why do you write the explicit type of pair (which is different from the iterator), auto could help you here to have fewer copies
As your question is about the first, I'll ignore the second one.
Looking at this, you have 3 ways of fixing the code:
std::map<Vector2,ControlNode> getControlNodes(std::map<Vector2, int> automata) {
auto controlNodes = std::map<Vector2, ControlNode>{};
for(auto &&pair : automata) {
auto &&pos = pair.first;
auto node = ControlNode(pos,pair.second);
controlNodes[pos] = std::move(node);
}
return controlNodes;
}
In this code, you can see that the * has been removed from the map. This implies that that ownership of the ControlNode is moved instead of the map. (Also note the std::move) This would be similar to how you have the int stored in the map that comes in as an argument.
If you however require memory allocation, as you will be moving this around and the address needs to be stable, std::unique_ptr is a good solution.
std::map<Vector2,std::unique_ptr<ControlNode>> getControlNodes(std::map<Vector2, int> automata) {
auto controlNodes = std::map<Vector2, std::unique_ptr<ControlNode>>{};
for(auto &&pair : automata) {
auto &&pos = pair.first;
auto node = std::make_unique<ControlNode>(pos,pair.second);
controlNodes[pos] = std::move(node);
}
return controlNodes;
}
As you can see, this code is very similar to the previous, I've replaced the type in the map and changed the construction of the ControlNode to std::make_unique. Hence, you have a unique_ptr containing the ownership to the allocated memory (and as long as you have the unique_ptr, things are staying valid).
The third solution should only be used if you can't change the signature and is considered bad practice in C++ as it passes ownership via raw pointers. Now your caller is responsible for explicitly cleaning up the memory as C++ doesn't have garbage collection.
std::map<Vector2,ControlNode*> getControlNodes(std::map<Vector2, int> automata) {
auto controlNodes = std::map<Vector2, ControlNode*>{};
for(auto &&pair : automata) {
auto &&pos = pair.first;
auto node = new ControlNode(pos,pair.second);
controlNodes[pos] = node;
}
return controlNodes;
}
PS: I've added some auto to the code to make the changes between the snippets minimal.
Use a vector of control nodes for storage. Whenever you need a new control node, append a one to that vector. Instead of using a pointer, use an iterator to that vector. Make sure you have reserved enough slots in that vector up front, or else your iterators will get invalidated.
I have a method which swaps the value of two variables.
void switchValue(int* a , int* b){
//logic here...
}
C++ works on a lower level than Kotlin but can I do this on Kotlin?
It's impossible to do this with a function in Kotlin or Java, because references can only be passed by value. (Unless you're satisfied with using a wrapper class and you swap what two wrapper instances are referencing, but this would be clumsy.)
This is probably the easiest way to swap two variables' values:
var x = 0
var y = 1
//swap:
x = y.also { y = x }
Edit: A bit of correction. You can sort of do it with properties using reflection. This wouldn't work on local variables, though.
fun <T> swap(first: KMutableProperty0<T>, second: KMutableProperty0<T>) {
first.set(second.get().also { second.set(first.get()) })
}
swap(::x, ::y)
In my opinion, this kind of practice (remotely changing variable values), although common in C/C++, should be avoided.
Simple example: I have some functions and I need to call them all, to modify a structure, only in one function. With these simple functions the task can be made in ways that don't use void, but in others tasks you have to use void. So what can you do?
type player = { mutable name : string; mutable points : int } ;;
let putname brad = match brad with
{ name = x; points = y } -> { name = brad; points = y } ;;
let putpoint guy score = match guy with
{ name = x; points = y } -> { name = x; points = score } ;;
let loosers listplayer guy = guy :: listplayer ;;
Here is the problem - How can I do the next function?
let someoneloses guy = void
guy = putpoint guy 0 ;;
listplayer = loosers (listplayer guy) ;;
Given you are using the name "void" I'm assuming you are more familiar with C (or C++). In OCaml the equivalent of "void" (the name of the type for no value) is "unit". There is another difference though: while in C the syntax is complex enough that it have constructs for no values (for instance, you can either "return a_value;" or "return;", two differents yet syntactically valid use cases for the keyword "return"), in OCaml the syntax is simpler and always require a value. So we have a notation for "nothing", which is, astutely but maybe also confusedly, is written "()".
So, the OCaml equivalent of the C:
void do_nothing(void) { return; }
is written:
let do_nothing () = ()
(notice how OCaml syntax is simpler and easier to grok once you got the "()" trick).
Now that this is hopefully clearer, back to your question.
A function that returns nothing is a function that return "()", either explicitly (as "do_nothing" above) or because it ends with an expression that has "()" as its value. For instance, an assignment (something tell me you'll love assignments), such as:
let putpoint guy score = guy.points <- score
Now back to your problem. You seem to be doing some kind of game with players represented as mutable records and some functions modifying those records as the game develop. You need not use pattern matching for that. Actually, functions such as "putpoint" above is probably what you want. But then you need some more state in your program: the list of loosers for instance is probably going to be a reference to a list that you modify etc.
This is the "imperative" side of OCaml but there is another one, which is usually regarded as more elegant although often slower in general (but not in functional languages which are optimised for this technique), consisting of refraining from altering state (changing values of things) but instead using functions merely taking values and returning values. Implemented like this, a player would be represented as an immutable record and each function acting a user would take an "old user" and return a "new user", and the same goes with the list of loosers, and so on. Actually, the whole game state would be represented as a big value that the "main loop" of your program would, given the previous value, and possible also the time and user inputs, would compute the "new state" and return it.
Have fun!
Also, your question has nothing to do with ocaml-batteries.
since you are using mutable data, you just have to assigned the value directly.
let p = {name = "me";points=0};;
let update x = x.name <- "you";
x.points <- 3;;
update p ;;
I once landed an interview and was asked what the purpose of assigning a variable by reference would be (as in the following case):
int i = 0;
int &j = i;
My answer was that C++ references work like C pointers, but cannot assume the NULL value, they must always point to a concrete object in memory. Of course, the syntax is different when using references (no need for the pointer indirection operator, and object properties will be accessed via the dot (.) rather than the arrow (->) operator). Perhaps the most important difference, is that unlike with pointers, where you can make a pointer point to something different (even after it was pointing to the same thing as another pointer), with references, if one reference is updated, then the other references which pointed to the same thing are also updated to point to the very same object.
But then I went on to say that the above use of references is pretty useless (and perhaps this is where I went wrong), because I couldn't see a practical advantage to assigning by reference: since both references end up pointing to the same thing, you could easily do with one reference, and couldn't think of a case where this wouldn't be the case. I went on to explain that references are useful as pass-by-reference function parameters, but not in assignments. But the interviewer said they assign by reference in their code all the time, and flunked me (I then went on to work for a company that this company was a client of, but that's besides the point).
Anyways, several years later, I would like to know where I could have gone wrong.
To begin with, I'd hope for that company's sake that wasn't the ONLY reason they didn't hire you, since it's a petty detail (and no, you don't really know exactly why a company doesn't hire you).
As touched on in the comment, references NEVER change what they refer to within their lifetime. Once set, a reference refers to that same location, until it "dies".
Now, references are quite useful to simplify an expression. Say we have a class or structure with a fair amount of complicated content. Say something like this:
struct A
{
int x, y, z;
};
struct B
{
A arr[100];
};
class C
{
public:
void func();
B* list[20];
};
void C::func()
{
...
if (list[i]->arr[j].x == 4 && list[i]->arr[j].y == 5 &&
(list[i]->arr[j].z < 10 || list[i]->arr[j].z > 90))
{
... do stuff ...
}
}
That's a lot of repeats of list[i]->arr[j] in there. So we could rewrite it using a reference:
void C::func()
{
...
A &cur = list[i]->arr[j];
if (cur.x == 4 && cur.y == 5 &&
(cur.z < 10 || cur.z > 90))
{
... do stuff ...
}
}
The above code assumes do stuff is actually mofidying the cur element in some way, if not, you should probably use const A &cur =... instead.
I use this technique quite a bit to make it clearer and less repetitive.
In this particular case of assigning a reference to a local variable of primitive type in the same scope, the assignment is very much useless: there is nothing you can do using j that you could not do using i. There are several mildly negative consequences to it, too, because the readability would suffer, and the optimizer may get confused.
Here is one legitimate use of assigning a reference:
class demo {
private:
map<int,string> cache;
string read_resource(int id) {
string resource_string;
... // Lengthy process for getting a non-empty resource string
return resource_string;
}
public:
string& get_by_id(int id) {
// Here is a nice trick
string &res = cache[id];
if (res.size() == 0) {
// Assigning res modifies the string in the map
res = read_resource(id);
}
return res;
}
};
Above, variable res of reference type refers to an element of the map that is either retrieved, or created new. If the string is created new, the code calls the "real" getter, and assigns its result to res. This automatically updates the cache, too, saving us another lookup in the cache map.
I am having problems translating C++ data structures to Scala. Scala is really different from C++, but I like a lot of it.
I have the following Code fragment in C++:
struct Output
{
double point;
double solution[6];
};
struct Coeff
{
double rcont1[6];
double rcont2[6];
double rcont3[6];
double rcont4[6];
double rcont5[6];
double rcont6[6];
};
std::list<Output> output;
std::list<Coeff> coeff;
I now fill the list in a while loop with data
while(n<nmax) {
if step successfull
Output out;
out.point = some values;
out.solution[0] = some value;
output.push_back(out);
}
I tried creating a simple class in Scala to hold the data.
class Output
{
var point: Double
var solution: Array[Double] = new Array(6)
}
But this doens't work since point is not initialized. Is there a way around this? I just want to define the variable but not initialize it.
Another quick thing. I am looking for an equivalent to stl::lower_bound.
Is finds the right position to insert an element in an sorted container to maintain the order.
Thanks for helping a Scala beginner
Why don't you want to initialize it? For efficiency? I'm afraid that the JVM doesn't let you get away with having random junk in your variables based on whatever was there originally. So since you have to initialize it anyway, why not specify what your "uninitialized" value is?
class Output {
var point = 0.0
var solution = new Array[Double](6)
}
(You could use Double.NaN and check for point.isNaN if you later need to see whether the value has been initialized or not.)
You could use _ as the default initialization, but unless you use it in generic code:
class Holder[T] {
var held: T = _
}
then you're just obscuring what the value really will be set to. (Or you are announcing "I really don't care what goes here, it could be anything"--which could be useful.)
I just found the answer to the intialistion:
class Output
{
var point: Double = _
var solution: Array[Double] = Array(6)
}
Puh Scala has a lot of syntx to get used to :-)
Anyone have a solution for the lower_bound equivalent ?
It's hard to translate effectively, as you've left a lot of unknowns hidden behind pseudo code, but I'd advocate something along these lines:
// type alias
type Coeff = Seq[Seq[Double]]
// parameters passed to a case class become member fields
case class Output (point: Double, solution: Seq[Double])
val outputs = (0 to nmax) map { n =>
Output(generatePoint(n), generateSolution(n))
}
If you can flesh out your sample code a bit more fully, I'll be able to give a better translation.