Scala - are classes sufficient? - scala

Coming from Java I am confused by the class/object distinction of scala.
Note that I do not ask for the formal difference; there are enough
references on the web which explain this, and there are related questions on
SO.
My questions are:
Why did the designers of scala
choosed to make things more
complicated (compared to Java or
C#)? What disadvantages do I have to
expect if I ignore this distinction
and declare only classes?
Thanks.

Java classes contain two completely different types of members -- instance members (such as BigDecimal.plus) and static members (such as BigDecimal.valueOf). In Scala, there are only instance members. This is actually a simplification! But it leaves a problem: where do we put methods like valueOf? That's where objects are useful.
class BigDecimal(value: String) {
def plus(that: BigDecimal): BigDecimal = // ...
}
object BigDecimal {
def valueOf(i: Int): BigDecimal = // ...
}
You can view this as the declaration of anonymous class and a single instantiation thereof:
class BigDecimal$object {
def valueOf(i: Int): BigDecimal = // ...
}
lazy val BigDecimal = new BigDecimal$object
When reading Scala code, it is crucial to distinguish types from values. I've configured IntelliJ to hightlight types blue.
val ls = List.empty[Int] // List is a value, a reference the the object List
ls: List[Int] // List is a type, a reference to class List
Java also has another degree of complexity that was removed in Scala -- the distinction between fields and methods. Fields aren't allowed on interfaces, except if they are static and final; methods can be overriden, fields instead are hidden if redefined in a subclass. Scala does away with this complexity, and only exposes methods to the programmer.
Finally, a glib answer to your second question: If you don't declare any objects, you're program may never run, as you to define the equivalent of public static void main(String... args) {} in Scala, you need at least one object!

Scala doesn't have any notion of static methods with standard classes, so in those scenarios you'll have to use objects. Interesting article here which provides a good intro:
http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-3
(scroll down to Scala’s Sort-of Statics)

One way to look at it is this. An executing program consists of a community of objects and threads. Threads execute code within the context of objects -- i.e. there is always a "this" object that a thread is executing within. This is a simplification from Java in the sense that in Java, there is not always a "this". But now there is a chicken/egg problem. If objects are created by threads and threads are executed within objects, what object is the first thread initially executing within. There has to be a nonempty set of objects that exist at the start of program execution. These are the objects declared with the object keyword.

Related

why I can update state of an Object extend immutable trait in scala

I created a class extend scala.Immutable
class SomeThing(var string: String) extends Immutable {
override def toString: String = string
}
As I expected, scala compiler should help me prevent change state of class SomeThing. But when I run this test
"Test change state of immutable interface" should "not allow" in {
val someThing = new SomeThing("hello")
someThing.string = "hello 1"
println(someThing)
}
The result is hello 1 and scala compiler don't throw any warning or error.
Why they have to add Immutable trait without help us prevent object mutable?
There are several aspects to this question.
1. A simple one is that Scala compiler can't really ensure immutability for many various reasons. For example, the main target platform JVM allows modifying even final fields using reflection. Another reason this is not enforceable is code like this
/////////////////////////////////////////
//// library v1
package library
class LibraryData(val value:Int)
/////////////////////////////////////////
//// code that uses the library
package app
class UserData(val data:LibraryData) extends Immutable
/////////////////////////////////////////
//// library v2
package library
class LibraryData(var value:Int) //now change it to var!
Since the "library" is compiled independently of the "app" and doesn't even know about existence of the "app" there is no point in time where compiler can catch the broken contract.
2. More fundamental misunderstanding you seem to have is what trait does. In this context trait (or "interface" in some other languages) represents a contract between the implementation and the user-code about how the implementation can and should behave. However not every kind of a contract can be represented as a trait (at least without making the code super-complicated). For example, for a mutable collection there is a contract that size should return the number of times add (or +=) has been called but there is no way to represent such a contract as a trait besides declaring that there are methods size and += with corresponding signatures. On the other hand, for most of the contracts there is no way to enforce implementation to follow the contract . For example, an implementation of size that always returns 0 technically matches all the types but is clearly breaking the contract.
Similarly Immutable doc says:
A marker trait for all immutable data structures such as immutable collections.
So it is just a marker trait which is one of the ways to work around contracts that can't be really represented as types. And it says that whoever implements that trait claims to be an immutable object. Your code claims that but clearly breaks the contract. So technically it is your fault for not respecting the contract.

Quick Documentation For Scala Apply Constructor Pattern in IntelliJ IDE

I am wondering if there is a way to get the quick documentation in IntelliJ to work for the class construction pattern many scala developers use below.
SomeClass(Param1,Parma2)
instead of
new SomeClass(param1,Param2)
The direct constructor call made with new obviously works but many scala devs use apply to construct objects. When that pattern is used the Intelij documentation look up fails to find any information on the class.
I don't know if there are documents in IntelliJ per se. However, the pattern is fairly easy to explain.
There's a pattern in Java code for having static factory methods (this is a specialization of the Gang of Four Factory Method Pattern), often along the lines of (translated to Scala-ish):
object Foo {
def barInstance(args...): Bar = ???
}
The main benefit of doing this is that the factory controls object instantiation, in particular:
the particular runtime class to instantiate, possibly based on the arguments to the factory. For example, the generic immutable collections in Scala have factory methods which may create optimized small collections if they're created with a sufficiently small amount of contents. An example of this is a sequence of length 1 can be implemented with basically no overhead with a single field referring to the object and a lookup that checks if the offset is 0 and either throws or returns its sole field.
whether an instance is created. One can cache arguments to the factory and memoize or "hashcons" the created objects, or precreate the most common instances and hand them out repeatedly.
A further benefit is that the factory is a function, while new is an operator, which allows the factory to be passed around:
class Foo(x: Int)
object Foo {
def instance(x: Int) = new Foo(x)
}
Seq(1, 2, 3).map(x => Foo(x)) // results in Seq(Foo(1), Foo(2), Foo(3))
In Scala, this is combined with the fact that the language allows any object which defines an apply method to be used syntactically as a function (even if it doesn't extend Function, which would allow the object to be passed around as if it's a function) and with the "companion object" to a class (which incorporates the things that in Java would be static in the class) to get something like:
class Foo(constructor_args...)
object Foo {
def apply(args...): Foo = ???
}
Which can be used like:
Foo(...)
For a case class, the Scala compiler automatically generates a companion object with certain behaviors, one of which is an apply with the same arguments as the constructor (other behaviors include contract-obeying hashCode and equals as well as an unapply method to allow for pattern matching).

Scala: Do classes that extend a trait always take the traits properties?

Given the following:
class TestClass extends TestTrait {
def doesSomething() = methodValue + intValue
}
trait TestTrait {
val intValue = 4
val unusedValue = 5
def methodValue = "method"
def unusedMethod = "unused method"
}
When the above code runs, will TestClass actually have memory allocated to unusedValue or unusedMethod? I've used javap and I know that there exists an unusedValue and an unusedMethod, but I cannot determine if they are actually populated with any sort of state or memory allocation.
Basically, I'm trying to understand if a class ALWAYS gets all that a trait provides, or if the compiler is smart enough to only provide what the class actually uses from the trait?
If a trait always imposes itself on a class, it seems like it could be inefficient, since I expect many programmers will use traits as mixins and therefore wasting memory everywhere.
Thanks to all who read and help me get to the bottom of this!
Generally speaking, in languages like Scala and Java and C++, each class has a table of pointers to its instance methods. If your question is whether the Scala compiler will allocate slots in the method table for unusedMethod then I would say yes it should.
I think your question is whether the Scala compiler will look at the body of TestClass and say "whoa, I only see uses of methodValue and intValue, so being a good compiler I'm going to refrain from allocating space in TestClass's method table for unusedMethod. But it can't really do this in general. The reason is, TestClass will be compiled into a class file TestClass.class and this class may be used in a library by programmers that you don't even know.
And what will they want to do with your class? This:
var x = new TestClass();
print(x.unusedMethod)
See, the thing is the compiler can't predict who is going to use this class in the future, so it puts all methods into its method table, even the ones not called by other methods in the class. This applies to methods declared in the class or picked up via an implemented trait.
If you expect the compiler to do global system-wide static analysis and optimization over a fixed, closed system then I suppose in theory it could whittle away such things, but I suspect that would be a very expensive optimization and not really worth it. If you need this kind of memory savings you would be better off writing smaller traits on your own. :)
It may be easiest to think about how Scala implements traits at the JVM level:
An interface is generated with the same name as the trait, containing all the trait's method signatures
If the trait contains only abstract methods, then nothing more is needed
If the trait contains any concrete methods, then the definition of these will be copied into any class that mixes in the trait
Any vals/vars will also get copied verbatim
It's also worth noting how a hypothetical var bippy: Int is implemented in equivalent java:
private int bippy; //backing field
public int bippy() { return this.bippy; } //getter
public void bippy_$eq(int x) { this.bippy = x; } //setter
For a val, the backing field is final and no setter is generated
When mixing-in a trait, the compiler doesn't analyse usage. For one thing, this would break the contract made by the interface. It would also take an unacceptably long time to perform such an analysis. This means that you will always inherit the cost of the backing fields from any vals/vars that get mixed in.
As you already hinted, if this is a problem then the solution is just use defs in your traits.
There are several other benefits to such an approach and, thanks to the uniform access principle, you can always override such a method with a val further down in the inheritance hierarchy if you need to.

Why people define class, trait, object inside another object in Scala?

Ok, I'll explain why I ask this question. I begin to read Lift 2.2 source code these days.
It's good if you happened to read lift source code before.
In Lift, I found that, define inner class and inner trait are very heavily used.
object Menu has 2 inner traits and 4 inner classes. object Loc has 18 inner classes, 5 inner traits, 7 inner objects.
There're tons of codes write like this. I wanna to know why the author write like this.
Is it because it's the author's
personal taste or a powerful use of
language feature?
Is there any trade-off for this kind
of usage?
Before 2.8, you had to choose between packages and objects. The problem with packages is that they cannot contain methods or vals on their own. So you have to put all those inside another object, which can get awkward. Observe:
object Encrypt {
private val magicConstant = 0x12345678
def encryptInt(i: Int) = i ^ magicConstant
class EncryptIterator(ii: Iterator[Int]) extends Iterator[Int] {
def hasNext = ii.hasNext
def next = encryptInt(ii.next)
}
}
Now you can import Encrypt._ and gain access to the method encryptInt as well as the class EncryptIterator. Handy!
In contrast,
package encrypt {
object Encrypt {
private[encrypt] val magicConstant = 0x12345678
def encryptInt(i: Int) = i ^ magicConstant
}
class EncryptIterator(ii: Iterator[Int]) extends Iterator[Int] {
def hasNext = ii.hasNext
def next = Encrypt.encryptInt(ii.next)
}
}
It's not a huge difference, but it makes the user import both encrypt._ and encrypt.Encrypt._ or have to keep writing Encrypt.encryptInt over and over. Why not just use an object instead, as in the first pattern? (There's really no performance penalty, since nested classes aren't actually Java inner classes under the hood; they're just regular classes as far as the JVM knows, but with fancy names that tell you that they're nested.)
In 2.8, you can have your cake and eat it too: call the thing a package object, and the compiler will rewrite the code for you so it actually looks like the second example under the hood (except the object Encrypt is actually called package internally), but behaves like the first example in terms of namespace--the vals and defs are right there without needing an extra import.
Thus, projects that were started pre-2.8 often use objects to enclose lots of stuff as if they were a package. Post-2.8, one of the main motivations has been removed. (But just to be clear, using an object still doesn't hurt; it's more that it's conceptually misleading than that it has a negative impact on performance or whatnot.)
(P.S. Please, please don't try to actually encrypt anything that way except as an example or a joke!)
Putting classes, traits and objects in an object is sometimes required when you want to use abstract type variables, see e.g. http://programming-scala.labs.oreilly.com/ch12.html#_parameterized_types_vs_abstract_types
It can be both. Among other things, an instance of an inner class/trait has access to the variables of its parent. Inner classes have to be created with a parent instance, which is an instance of the outer type.
In other cases, it's probably just a way of grouping closely related things, as in your object example. Note that the trait LocParam is sealed, which means that all subclasses have to be in the same compile unit/file.
sblundy has a decent answer. One thing to add is that only with Scala 2.8 do you have package objects which let you group similar things in a package namespace without making a completely separate object. For that reason I will be updating my Lift Modules proposal to use a package object instead of a simple object.

Why are singleton objects more object-oriented?

In Programming in Scala: A Comprehensive Step-by-Step Guide, the author said:
One way in which Scala is more
object-oriented than Java is that
classes in Scala cannot have static
members. Instead, Scala has singleton
objects.
Why is a singleton object more object-oriented? What's the good of not using static members, but singleton objects?
Trying for the "big picture"; most of this has been covered in other answers, but there doesn't seem to be a single comprehensive reply that puts it all together and joins the dots. So here goes...
Static methods on a class are not methods on an object, this means that:
Static members can't be inherited from a parent class/trait
Static members can't be used to implement an interface
The static members of a class can't be passed as an argument to some function
(and because of the above points...)
Static members can't be overridden
Static members can't be polymorphic
The whole point of objects is that they can inherit from parent objects, implement interfaces, and be passed as arguments - static members have none of these properties, so they aren't truly object-oriented, they're little more than a namespace.
Singleton objects, on the other hand, are fully-fledged members of the object community.
Another very useful property of singletons is that they can easily be changed at some later point in time to not be singletons, this is a particularly painful refactoring if you start from static methods.
Imagine you designed a program for printing addresses and represented interactions with the printer via static methods on some class, then later you want to be able to add a second printer and allow the user to chose which one they'll use... It wouldn't be a fun experience!
Singleton objects behave like classes in that they can extend/implement other types.
Can't do that in Java with just static classes -- it's pretty sugar over the Java singleton pattern with a getInstance that allows (at least) nicer namespaces/stable identifiers and hides the distinction.
Hint: it's called object-oriented programming.
Seriously.
Maybe I am missing something fundamentally important, but I don't see what the fuss is all about: objects are more object-oriented than non-objects because they are objects. Does that really need an explanation?
Note: Although it sure sounds that way, I am really not trying to sound smug here. I have looked at all the other answers and I found them terribly confusing. To me, it's kind of obvious that objects and methods are more object-oriented than namespaces and procedures (which is what static "methods" really are) by the very definition of "object-oriented".
An alternative to having singleton objects would be to make classes themselves objects, as e.g. Ruby, Python, Smalltalk, Newspeak do.
For static members, there is no object. The class really just is a namespace.
In a singleton, there is always at least one object.
In all honesty, it's splitting hairs.
It's more object oriented in the sense that given a Scala class, every method call is a method call on that object. In Java, the static methods don't interact with the object state.
In fact, given an object a of a class A with the static method m(), it's considered bad practice to call a.m(). Instead it's recommended to call A.m() (I believe Eclipse will give you a warning). Java static methods can't be overridden, they can just be hidden by another method:
class A {
public static void m() {
System.out.println("m from A");
}
}
public class B extends A {
public static void m() {
System.out.println("m from B");
}
public static void main(String[] args) {
A a = new B();
a.m();
}
}
What will a.m() print?
In Scala, you would stick the static methods in companion objects A and B and the intent would be clearer as you would refer explicitly to the companion A or B.
Adding the same example in Scala:
class A
object A {
def m() = println("m from A")
}
class B extends A
object B {
def m() = println("m from B")
def main(args: Array[String]) {
val a = new B
A.m() // cannot call a.m()
}
}
There is some difference that may be important in some scenarios. In Java you
can't override static method so if you had class with static methods you would not be able to customize and override part of its behavior. If you used singleton object, you could just plug singleton created from subclass.
It's a marketing thing, really. Consider two examples:
class foo
static const int bar = 42;
end class
class superfoo
Integer bar = ConstInteger.new(42);
end class
Now, what are the observable differences here?
in a well-behaved language, the additional storage created is the same.
Foo.bar and Superfoo.bar have exactly the same signatures, access, and so on.
Superfoo.bar may be allocated differently but that's an implementation detail
It reminds me of the religious wars 20 years ago over whether C++ or Java were "really" Object Oriented, since after all both exposed primitive types that aren't "really" objects -- so, for example you can't inherit from int but can from Integer.