Statically decide if a Scala class is immutable - scala

I just attended a Scala-lecture at a summer school. The lecturer got the following question:
- "Is there any way for the compiler to tell if a class is immutable?"
The lecturer responded
- "No, there isn't. It would be very nice if it could."
I was surprised. Isnt't it just to check if the class contains any var-members?

What is immutable?
Checking to see if the object only contains val fields is an overapproximation of immutability - the object may very well contain vars, but never assign different values in them. Or the segments of the program assigning values to vars may be unreachable.
According to the terminology of Chris Okasaki, there are immutable data structures and functional data structures.
An immutable data structure (or a class) is a data structure which, once constructed in memory, never changes its components and values - an example of this is a Scala tuple.
However, if you define the immutability of an object as the immutability of itself and all the objects reachable through references from the object, then a tuple may not be immutable - it depends on what you later instantiate it with. Sometimes there is not enough information about the program available at compile time to decide if a given data structure is immutable in the sense of containing only vals. And the information is missing due to polymorphism, whether parametric, subtyping or ad-hoc (type classes).
This is the first problem with deciding immutability - lack of static information.
A functional data structure is a data structure on which you can do operations whose outputs depend solely on the inputs for a given state. An example of such a data structure is a search tree which caches the last item looked up by storing it in a mutable field. Even though every lookup will write the last item searched into the mutable field, so that if the item is looked up again the search doesn't have to be repeated, the outputs of the lookup operation for such a data structure always remain the same given that nobody inserts new items into it. Another example of a functional data structure are splay trees.
In a general imperative programming model, to check if an operation is pure, that is - do the outputs depend solely on inputs, is undecidable. Again, one could use a technique such as abstract interpretation to provide a conservative answer, but this is not an exact answer to the question of purity.
This is the second problem with deciding if something having vars is immutable or functional (observably immutable) - undecidability.

I think the problem is that you need to ensure that all your vals don’t have any var members either. And this you cannot. Consider
class Base
case class Immutable extends Base { val immutable: Int = 0 }
case class Mutable extends Base { var mutable: Int = _ }
case class Immutable_?(b: Base)
Even though Immutable_?(Immutable) is indeed immutable, Immutable_?(Mutable) is not.

If you save a mutable object in a val the object itself is still mutable. So you would have to check if each class you use in a val is immutable.
case class Mut(var mut:Int)
val m = Mut(1)
println(m.toString)
m.mut = 3
println(m.toString)

In addition to what others have said, take a look at effect systems and discussion about supporting one in Scala.

It is not quite as easy since you could have vals that are linked to other mutable classes or, even harder to detect, that calls methods in other classes or objects that are mutable.
Also, you could very well have a immutable class that in fact has vars (to be more efficient for example...).
I guess you could have something that checks if a class looks like it is immutable or not though, but it sounds like it could be pretty confusing.

You can have a class, which can be instantiated to an object, and this object can be mutable or immutable.
Example: A class may contain a List[_], which, at runtime, can be a List[Int] or a List[StringBuffer]. So two different objects of a class could be either mutable, or immutable.

Related

What is the type of scala.concurrent.Future?

I try to understand what's the data type of scala.concurrent.Future?
I found the following types from the scala lang documentation, but still unsure the differences between them, and when to use which one?
trait Future[+T] extends Awaitable[T] //for concurrent programming
object Future extends AnyRef //not sure?
http://www.scala-lang.org/api/2.9.3/scala/concurrent/Future.html
http://www.scala-lang.org/api/2.9.3/scala/concurrent/Future$.html
Sorry, but I got an impression that you need first to get some scala basis, what is trait, what is companion object, and other stuff.
Back to your question.
When you want to execute something concurrently, you can wrap it in Future. Your code has some output type (SomeType, could be Unit - equivalent of void), after wrapping into Future you will get Future[SomeType] - it is extension of trait Future[+T]. Than you need some execution context (thread pool) to execute your Future.
Try to find and read "Programming in Scala" written by Martin Odersky, Lex Spoon and Bill Venners, very good for beginners.
Like a collection (List, Array, etc.), a Future is a type that works on/with another type. A useful comparison is the Option type.
Just as an Option[Int] might be an Int value (and it might not), a Future[Int] might not be an Int value yet. It could be that the Int value is still being calculated, or being extracted from a database table, or being retrieved from a distant network location. Whatever the cause, if it's a slow process there's no reason to wait for it. Turn it into a Future[Int] so that your program can go on with other important tasks.
As for the object Future, that is a singleton object that has a handful of methods for handling/manipulating existing Future elements. Future.sequence() is a useful example.
It is unclear whether you are talking about the trait Future or the singleton object Future. I will answer both.
The trait doesn't have a type. It is a type.
All singleton objects foo have the singleton type foo.type, so the singleton object Future has the singleton type Future.type.
In Scala, object is a singleton class, which means, that there only exists a single instance during the runtime of the application. There are several ways to implement singletons in most languages, but most often, you risk some issues such as thread safety. Scala's object takes care of the implementation of this pattern for you.
A common pattern in Scala is creating an object that has the same name as a class, like the one in your example. This is called a companion object. A common use for these is for essentially defining the equivalents of static methods from Java. You can declare methods that are common for all instances, or methods that handle and manipulate instances of the class. In Java, for example, you would declare them as static in the body of the class itself. The companion object helps you with separation of concern in this case.

Why not make every Scala class a case class?

case classes have some nice percs, like copy, hashCode, toString, Pattern Matching. Why not make every Scala class a case class?
A case class is extremely good to hold complex values, like entity objects. They are thought precisely for that case, so they provide you methods that make sense precisely for this use case by synthesizing the methods you mentioned and furthermore making your class Serializable and creating a companion object with a "factory" method (other than the extractor for pattern matching).
The drawbacks are the following:
some of the properties that a case class has may not be interesting for the class you're creating: would you want an equals method on an object holding a database connection? Would it make sense for it to be Serializable? And if it did, would it be secure?
all these features are not free: they require the compiler to do some extra work and add to your final artifact size; why having these if you don't need the extra features a case class provides?
you cannot inherit from case class to another case class, which may go against how you are modeling your domain. Why? Short answer: equality. You can find a longer answer here.
Case classes have clear semantics -- data container (much better POJOs or ADT blocks, depends on your background).
Sometimes methods like copy or unapply can have confusing meaning -- e.g. if fields are mutable. Case classes are designed to be used in "idiomatic scala style", that might not be applicable everywhere.
Last but not the least -- technical disadvantages (more code in .class, more code to serialize, issues with inheritance).

Scala: Serializing/deserializing a few elements of a class

Consider the following toy class:
class myGiantClass(){
val serializableElement = ...
// lots of other variables and methods here
}
// main program
val listOfGiantObjects: List[myGiantClass] = ....
What I need is to serialize/deserialize listOfGiantObjects. The issue is that myGiantClass contains lots of junk objects and variables which I don't/can't serialize/deserialize. Instead the only element of the myGiantClass that I want to serialize is serializableElement inside each object of listOfGiantObjects.
So after deserialize, listOfGiantObjects is expected to contain a bunch of myGiantClass objects which contain only serializableElement (the rest set to default).
Any ideas?
Of course there are two approaches (or defaults): all elements should be serialized by default, or none.
Within the "all" scenario, you could take a look at the #transient annotation, for marking fields that should not be serialized.
It may seem an unoptimal approach in case of a large number of elements that should not be serialized. However, it does communicate what you are trying to achieve. Moreover, you could arrange your code using composition or inner classes to better define the scope of serialization.
At last resort, ad-hoc serializaion with custom attributes is a way (e.g., to implement the none-by-default scenario).

Scala type alias with companion object

I'm a relatively new Scala user and I wanted to get an opinion on the current design of my code.
I have a few classes that are all represented as fixed length Vector[Byte] (ultimately they are used in a learning algorithm that requires a byte string), say A, B and C.
I would like these classes to be referred to as A, B and C elsewhere in the package for readability sake and I don't need to add any extra class methods to Vector for these methods. Hence, I don't think the extend-my-library pattern is useful here.
However, I would like to include all the useful functional methods that come with Vector without having to 'drill' into a wrapper object each time. As efficiency is important here, I also didn't want the added weight of a wrapper.
Therefore I decided to define type aliases in the package object:
package object abc {
type A: Vector[Byte]
type B: Vector[Byte]
type C: Vector[Byte]
}
However, each has it's own fixed length and I would like to include factory methods for their creation. It seems like this is what companion objects are for. This is how my final design looks:
package object abc {
type A: Vector[Byte]
object A {
val LENGTH: Int = ...
def apply(...): A = {
Vector.tabulate...
}
}
...
}
Everything compiles and it allows me to do stuff like this:
val a: A = A(...)
a map {...} mkString(...)
I can't find anything specifically warning against writing companion objects for type aliases, but it seems it goes against how type aliases should be used. It also means that all three of these classes are defined in the same file, when ideally they should be separated.
Are there any hidden problems with this approach?
Is there a better design for this problem?
Thanks.
I guess it is totally ok, because you are not really implementing a companion object.
If you were, you would have access to private fields of immutable.Vector from inside object A (like e.g. private var dirty), which you do not have.
Thus, although it somewhat feels like A is a companion object, it really isn't.
If it were possible to create a companion object for any type by using type alias would make member visibility constraints moot (except maybe for private|protected[this]).
Furthermore, naming the object like the type alias clarifies context and purpose of the object, which is a plus in my book.
Having them all in one file is something that is pretty common in scala as I know it (e.g. when using the type class pattern).
Thus:
No pitfalls, I know of.
And, imho, no need for a different approach.

What are the benefits of an immutable struct over a mutable one?

I already know the benefit of immutability over mutability in being able to reason about code and introducing less bugs, especially in multithreaded code. In creating structs, though, I cannot see any benefit over creating a completely immutable struct over a mutable one.
Let's have as an example of a struct that keeps some score:
struct ScoreKeeper {
var score: Int
}
In this structure I can change the value of score on an existing struct variable
var scoreKeeper = ScoreKeeper(score: 0)
scoreKeeper.score += 5
println(scoreKeeper.score)
// prints 5
The immutable version would look like this:
struct ScoreKeeper {
let score: Int
func incrementScoreBy(points: Int) -> ScoreKeeper {
return ScoreKeeper(score: self.score + points)
}
}
And its usage:
let scoreKeeper = ScoreKeeper(score: 0)
let newScoreKeeper = scoreKeeper.incrementScoreBy(5)
println(newScoreKeeper.score)
// prints 5
What I don't see is the benefit of the second approach over the first, since structs are value types. If I pass a struct around, it always gets copied. So it does not seem to matter to me if the structure has a mutable property, since other parts of the code would be working on a separate copy anyway, thus removing the problems of mutability.
I have seen some people using the second example, though, which requires more code for no apparent benefit. Is there some benefit I'm not seeing?
Different approaches will facilitate different kinds of changes to the code. An immutable structure is very similar to an immutable class object, but a mutable structure and a mutable class object are very different. Thus, code which uses an immutable structure can often be readily adapted if for some reason it becomes necessary to use a class object instead.
On the flip side, use of an immutable object will often make the code to replace a variable with a modified version more brittle in case additional properties are added to the type in question. For example, if a PhoneNumber type includes methods for AreaCode, LocalExchange, and LocalNumber and a constructor that takes those parameters, and then adds an "optional" fourth property for Extension, then code which is supposed to change the area codes of certain phone numbers by passing the new area code, LocalExchange, and LocalNumber, to the three-argument constructor will erase the Extension property of every phone number, while code which could write to AreaCode directly wouldn't have had that problem.
Your remark about copying value types is very good. Maybe this doesn't make much sense in particular language (swift) and particular compiler implementation (current version) but in general if the compiler knows for sure that the data structure is immutable, it could e.g. use reference instead of a copy behind the scenes to gain some performance improvement. This could not be done with mutable type for obvious reasons.
Even more generally speaking, limitation means information. If you limit your data structure somehow, you gain some extra knowledge about it. And extra knowledge means extra possibilities ;) Maybe the current compiler does not take advantage of them but this does not mean they are not here :)
Good analysis, especially pointing out that structs are passed by value and therefore will not be altered by other processes.
The only benefit I can see is a stylistic one by making the immutability of the element explicit.
It is more of a style to make value based types be treated on par with object based types in object oriented styles. It is more of a personal choice, and I don't see any big benefits in either of them.
In general terms, immutable objects are less costly to the system than mutable ones. Mutable objects need to have infrastructure for taking on new values, and the system has to allow for the fact that their values can change at any time.
Mutable objects are also a challenge in concurrent code because you have to guard against the value changing out from under you from another thread.
However, if you are constantly creating and destroying unique immutable objects, the overhead of creating new ones becomes costly quite quickly.
In the foundation classes, NSNumber is an immutable object. The system maintains a pool of NSNumber objects that you've used before, and under the covers, gives you back an existing number if you ask for one with the same value as one you created before.
That's about the only situation in which I could see value in using static structs - where they don't change very much and you have a fairly small pool of possible values. In that case you'd probably want to se up your class with a "factory method" that kept recently used structs around and reused them if you asked for a struct with the same value again.
Such a scheme could simplify concurrent code, as mentioned above. In that case you wouldn't have to guard against the values of your structs changing in another thread. If you were using such a struct, you could know that it would never change.