Scala var best practice - Encapsulation - scala

I'm trying to understand what's the best practice for using vars in scala, for example
class Rectangle() {
var x:Int = 0
}
Or something like:
class Rectangle() {
private var _x:Int = 0
def x:Int = _x
def x_(newX:Int):Unit = _x=newX
}
Which one can be considered as better? and why?
Thank you!

As Luis already explained in the comment, vars are something that should be avoided whenever you are able to avoid it, and such a simple case like you gave is one of those that can be better designed using something like this:
// Companion object is not necessary in your case
object Rectangle {
def fromInt(x: Int): Option[Rectangle] = {
if(x > 0) {
Some(Rectangle(x))
} else None
}
final case class Rectangle(x: Int)
It would be very rare situations when you can't avoid using vars in scala. Scala general idiom is: "Make your variables immutable, unless there is a good reason not to"

I'm trying to understand what's the best practice for using vars in scala, […]
Best practice is to not use vars at all.
Which one can be considered as better? and why?
The second one is basically equivalent to what the compiler would generate for the first one anyway, so it doesn't really make sense to use the second one.
It would make sense if you wanted to give different accessibility to the setter and the getter, something like this:
class Rectangle {
private[this] var _x = 0
def x = _x
private def x_=(x: Int) = _x = x
}
As you can see, I am using different accessibility for the setter and the getter, so it makes sense to write them out explicitly. Otherwise, just let the compiler generate them.
Note: I made a few other changes to the code:
I changed the visibility of the _x backing field to private[this].
I changed the name of the setter to x_=. This is the standard naming for setters, and it has the added advantage that it allows you to use someRectangle.x = 42 syntactic sugar to call it, making it indistinguishable from a field.
I added some whitespace to give the code room to breathe.
I removed some return type annotations. (This one is controversial.) The community standard is to always annotate your return types in public interfaces, but in my opinion, you can leave them out if they are trivial. It doesn't really take much mental effort to figure out that 0 has type Int.
Note that your first version can also be simplified:
class Rectangle(var x: Int = 0)
However, as mentioned in other answers, you really should make your objects immutable. It is easy to create a simple immutable data object with all the convenience functions generated automatically for you by using a case class:
final case class Rectangle(x: Int = 0)
If you now want to "change" your rectangle, you instead create a new one which has all the properties the same except x (in this case, x is the only property, but there could be more). To do this, Scala generates a nifty copy method for you:
val smallRectangle = Rectangle(3)
val enlargedRectangle = smallRectangle.copy(x = 10)

Related

How to design abstract classes if methods don't have the exact same signature?

This is a "real life" OO design question. I am working with Scala, and interested in specific Scala solutions, but I'm definitely open to hear generic thoughts.
I am implementing a branch-and-bound combinatorial optimization program. The algorithm itself is pretty easy to implement. For each different problem we just need to implement a class that contains information about what are the allowed neighbor states for the search, how to calculate the cost, and then potentially what is the lower bound, etc...
I also want to be able to experiment with different data structures. For instance, one way to store a logic formula is using a simple list of lists of integers. This represents a set of clauses, each integer a literal. We can have a much better performance though if we do something like a "two-literal watch list", and store some extra information about the formula in general.
That all would mean something like this
object BnBSolver[S<:BnBState]{
def solve(states: Seq[S], best_state:Option[S]): Option[S] = if (states.isEmpty) best_state else
val next_state = states.head
/* compare to best state, etc... */
val new_states = new_branches ++ states.tail
solve(new_states, new_best_state)
}
class BnBState[F<:Formula](clauses:F, assigned_variables) {
def cost: Int
def branches: Seq[BnBState] = {
val ll = clauses.pick_variable
List(
BnBState(clauses.assign(ll), ll :: assigned_variables),
BnBState(clauses.assign(-ll), -ll :: assigned_variables)
)
}
}
case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
def assign(ll: Int) :F =
Formula(clauses.filterNot(_ contains ll)
.map(_.filterNot(_==-ll))))
}
Hopefully this is not too crazy, wrong or confusing. The whole issue here is that this assign method from a formula would usually take just the current literal that is going to be assigned. In the case of two-literal watch lists, though, you are doing some lazy thing that requires you to know later what literals have been previously assigned.
One way to fix this is you just keep this list of previously assigned literals in the data structure, maybe as a private thing. Make it a self-standing lazy data structure. But this list of the previous assignments is actually something that may be naturally available by whoever is using the Formula class. So it makes sense to allow whoever is using it to just provide the list every time you assign, if necessary.
The problem here is that we cannot now have an abstract Formula class that just declares a assign(ll:Int):Formula. In the normal case this is OK, but if this is a two-literal watch list Formula, it is actually an assign(literal: Int, previous_assignments: Seq[Int]).
From the point of view of the classes using it, it is kind of OK. But then how do we write generic code that can take all these different versions of Formula? Because of the drastic signature change, it cannot simply be an abstract method. We could maybe force the user to always provide the full assigned variables, but then this is a kind of a lie too. What to do?
The idea is the watch list class just becomes a kind of regular assign(Int) class if I write down some kind of adapter method that knows where to take the previous assignments from... I am thinking maybe with implicit we can cook something up.
I'll try to make my answer a bit general, since I'm not convinced I'm completely following what you are trying to do. Anyway...
Generally, the first thought should be to accept a common super-class as a parameter. Obviously that won't work with Int and Seq[Int].
You could just have two methods; have one call the other. For instance just wrap an Int into a Seq[Int] with one element and pass that to the other method.
You can also wrap the parameter in some custom class, e.g.
class Assignment {
...
}
def int2Assignment(n: Int): Assignment = ...
def seq2Assignment(s: Seq[Int]): Assignment = ...
case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
def assign(ll: Assignment) :F = ...
}
And of course you would have the option to make those conversion methods implicit so that callers just have to import them, not call them explicitly.
Lastly, you could do this with a typeclass:
trait Assigner[A] {
...
}
implicit val intAssigner = new Assigner[Int] {
...
}
implicit val seqAssigner = new Assigner[Seq[Int]] {
...
}
case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
def assign[A : Assigner](ll: A) :F = ...
}
You could also make that type parameter at the class level:
case class Formula[A:Assigner,F<:Formula[A,F]](clauses:List[List[Int]]) {
def assign(ll: A) :F = ...
}
Which one of these paths is best is up to preference and how it might fit in with the rest of the code.

Using a Lens on a non-case class extending something with a constructor in Scala

I am probably thinking about this the wrong way, but I am having trouble in Scala to use lenses on classes extending something with a constructor.
class A(c: Config) extends B(c) {
val x: String = doSomeProcessing(c, y) // y comes from B
}
I am trying to create a Lens to mutate this class, but am having trouble doing so. Here is what I would like to be able to do:
val l = Lens(
get = (_: A).x,
set = (c: A, xx: String) => c.copy(x = xx) // doesn't work because not a case class
)
I think it all boils down to finding a good way to mutate this class.
What are my options to achieve something like that? I was thinking about this in 2 ways:
Move the initialization logic into a companion A object into a def apply(c: Config), and change the A class to be a case class that gets created from the companion object. Unfortunately I can't extend from B(c) in my object because I only have access to c in its apply method.
Make x a var. Then in the Lens.set just A.clone then set the value of x then return the cloned instance. This would probably work but seems pretty ugly, not to mention changing this to a var might raise a few eyebrows.
Use some reflection magic to do the copy. Not really a fan of this approach if I can avoid it.
What do you think? Am I thinking about this really the wrong way, or is there an easy solution to this problem?
This depends on what you expect your Lens to do. A Lens laws specify that the setter should replace the value that the getter would get, while keeping everything else unchanged. It is unclear what is meant by everything else here.
Do you wish to have the constructor for B called when setting? Do you which the doSomeProcessing method called?
If all your methods are purely functional, then you may consider that the class A has two "fields", c: Config and x: String, so you might as well replace it with a case class with those fields. However, this will cause a problem while trying to implement the constructor with only c as parameter.
What I would consider is doing the following:
class A(val c: Config) extends B(c) {
val x = doSomeProcessing(c, y)
def copy(newX: String) = new A(c) { override val x = newX }
}
The Lens you wrote is now perfectly valid (except for the named parameter in the copy method).
Be careful if you have other properties in A which depend on x, this might create an instance with unexpected values for these.
If you do not wish c to be a property of class A, then you won't be able to clone it, or to rebuild an instance without giving a Config to your builder, which Lenses builder cannot have, so it seems your goal would be unachievable.

Can I dynamically construct a trait in Scala that is computed based on the class it extends?

I want to accomplish something a little different from standard mixins. I want to construct a trait whose new fields are computed based on the fields of the class (or trait) it extends.
For instance, if I had a class like this:
class Point {
var x: Int = 0
var y: Int = 0
}
and I wanted to produce a class like this:
class Point' {
var x: Int = 0
var y: Int = 0
var myx: Int = 0
var myy: Int = 0
}
I'd like to be able to write a function that computes the field names myx and myy and then mixes them into the class using a trait. Here's some made up psuedo-Scala for what I want to do:
def addMy(cls: Class) {
newFields = cls.fields.map( f => createField("my" + f.name, f.type) )
myTrait = createTrait(newFields)
extendClass(cls, myTrait)
}
The easiest way I can think of to achieve such a behavior would be to use Scala 2.10's Dynamic feature. Thus, Point must extend Dynamic and you can "mix in" arbitrary fields by adding the calculation logic to the member functions selectDynamic and updateDynamic. This is not quite what "mix in" actually refers to, but it nevertheless allows you to add functionality dynamically.
To ensure that it is possible to check whether a specific functionality has been mixed in, you can for instance use the following convention. In order to check whether a field is mixed in, a user can call hasMyx or has... in general. By default your implementation returns false. Each time you mix in a new field the corresponding has... function would return true.
Please note that the return type of all your mixed in fields will be Any (unless all your fields are of the same type, see for instance this question). I currently see no way to avoid a lot of casting with this design.

Consistent way of declaring class fields in Scala

This constantly bugs me:
class Test(i: Int) {
val this.i = i;
val this.ii = i; // :(
}
I would like to declare all my vals/vars the same way, and I really don't understand why that this upsets the Scala compiler. Everywhere else this performs as expected except here.
Is there a good reason why it won't let me punch in that this?
Is there a better way/ a way around it/ a Scala way?
Every variable you declare in that scope is going to be a field. So it warrants no special syntax.
class Test(_i: Int) {
val i = _i
val ii = i
}
Or even better:
class Test(val i: Int) {
val ii = i
}
You can write it either way, depending on whether you are going for clearer and smaller code OR "consistent" code.
The scala way is not to use this. Why do you use this in Java? To make it obvious that you are accessing a member of an instance and not a static member. This isn't necessary in Scala, since there are no static members and members of the companion object need to be prefixed with the companion object's name anyway.

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