Basic Scala: Methods holding parameters? - scala

I am reading the book Programming in Scala and in chapter 10 I had to write:
abstract class Element {
def contents: Array[String]
def height: Int = contents.length
def width: Int = if (height == 0) 0 else contents(0).length
}
class ArrayElement(conts: Array[String]) extends Element {
def contents: Array[String] = conts
}
but the concept I don't catch here is how can I define a method that is holding a variable? As far as I know, methods return a value, it can be a computed value or an instance variable directly, but they can't hold a value. Am I forgetting a basic concept about the programming language that applies here too?

Try this out:
abstract class Foo { def bar: Int }
class Baz(val bar: Int) extends Foo
In Scala, you can implement methods by creating member variables with same name and same type. The compiler then adds a corresponding getter-method automatically.
The member variable and the getter-method are still two different things, but you don't see much difference syntactically: when you try to access it, its both just foo.bar, regardless of whether bar is a method or a member variable.
In your case
def contents: Array[String] = conts
is just an ordinary method that returns an array, an equivalent way to write the same thing would be
def contents: Array[String] = {
return conts
}
Since the array is mutable, you can in principle use this method to modify entries of your array, but the method itself is really just a normal method, it doesn't "hold" anything, it just returns reference to your array.
Edit: I've just noticed that conts is actually not a member variable. However, its still captured in the definition of the contents method by the closure-mechanism.

Related

How to program an iterator in scala without using a mutable variable?

I want to implement the iterator trait but in the functional way, ie, without using a var. How to do that?
Suppose I have an external library where I get some elements by calling a function getNextElements(numOfElements: Int):Array[String] and I want to implement an Iterator using that function but without using a variable indicating the "current" array (in my case, the var buffer). How can I implement that in the functional way?
class MyIterator[T](fillBuffer: Int => Array[T]) extends Iterator[T] {
var buffer: List[T] = fillBuffer(10).toList
override def hasNext(): Boolean = {
if (buffer.isEmpty) buffer = fillBuffer(10).toList
buffer.nonEmpty
}
override def next(): T = {
if (!hasNext()) throw new NoSuchElementException()
val elem: T = buffer.head
buffer = buffer.tail
elem
}
}
class Main extends App {
def getNextElements(num: Int): Array[String] = ???
val iterator = new MyIterator[String](getNextElements)
iterator.foreach(println)
}
Iterators are mutable, at least without an interface that also returns a state variable, so you can't in general implement the interface directly without some sort of mutation.
That being said, there are some very useful functions in the Iterator companion object that let you hide the mutation, and make the implementation cleaner. I would implement yours something like:
Iterator.continually(getNextElements(10)).flatten
This calls getNextElements(10) whenever it needs to fill the buffer. The flatten changes it from an Iterator[Array[A]] to an Iterator[A].
Note this returns an infinite iterator. Your question didn't say anything about detecting the end of your source elements, but I would usually implement that using takeWhile. For example, if getNextElements returns an empty array when there are no more elements, you can do:
Iterator.continually(getNextElements(10)).takeWhile(!_.isEmpty).flatten

Scala secondary constructor "Application does not take parameters" error [duplicate]

I think I see the merit in defining auxiliary constructors in such a way that the primary constructor is the solitary point of entry to the class. But why can't I do something like this?
class Wibble(foo: Int, bar: String) {
def this(baz: List[Any]) = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
this(bazLength, someText)
}
}
Is it maybe a way of guaranteeing that the auxiliary constructor doesn't have side effects and/or can't return early?
Auxiliary constructors can contain more than a single invocation of another constructor, but their first statement must be said invocation.
As explained in Programming in Scala, ch. 6.7:
In Scala, every auxiliary constructor must invoke another constructor of
the same class as its first action. In other words, the first statement in every
auxiliary constructor in every Scala class will have the form this(. . . ).
The invoked constructor is either the primary constructor (as in the Rational
example), or another auxiliary constructor that comes textually before the
calling constructor. The net effect of this rule is that every constructor invocation
in Scala will end up eventually calling the primary constructor of the
class. The primary constructor is thus the single point of entry of a class.
If you’re familiar with Java, you may wonder why Scala’s rules for
constructors are a bit more restrictive than Java’s. In Java, a constructor
must either invoke another constructor of the same class, or directly invoke
a constructor of the superclass, as its first action. In a Scala class, only the
primary constructor can invoke a superclass constructor. The increased
restriction in Scala is really a design trade-off that needed to be paid in
exchange for the greater conciseness and simplicity of Scala’s constructors
compared to Java’s.
Just as in Java, one can get round this limitation by extracting the code to be executed before the primary constructor call into a separate method. In Scala it is a bit more tricky than in Java, as apparently you need to move this helper method into the companion object in order to be allowed to call it from the constructor.
Moreover, your specific case is awkward as you have two constructor parameters and - although one can return tuples from a function - this returned tuple is then not accepted as the argument list to the primary constructor. For ordinary functions, you can use tupled, but alas, this doesn't seem to work for constructors. A workaround would be to add yet another auxiliary constructor:
object Wibble {
private def init(baz: List[Any]): (Int, String) = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
println("init")
(bazLength, someText)
}
}
class Wibble(foo: Int, bar: String) {
println("Wibble wobble")
def this(t: (Int, String)) = {
this(t._1, t._2)
println("You can execute more code here")
}
def this(baz: List[Any]) = {
this(Wibble.init(baz))
println("You can also execute some code here")
}
}
This at least works, even if it is slightly complicated.
scala> val w = new Wibble(List(1, 2, 3))
init
Wibble wobble
You can execute more code here
You can also execute some code here
w: Wibble = Wibble#b6e385
Update
As #sschaef's pointed out in his comment, this can be simplified using a factory method in the companion object:
object Wobble {
def apply(baz: List[Any]): Wobble = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
println("init")
new Wobble(bazLength, someText)
}
}
class Wobble(foo: Int, bar: String) {
println("Wobble wibble")
}
Thus we need no new to create an object anymore:
scala> val w = Wobble(List(1, 2, 3))
init
Wobble wibble
w: Wobble = Wobble#47c130

Why is it allowed to put methods inside blocks, and statements inside objects in Scala?

I'm learning Scala and I don't really understand the following example :
object Test extends App {
def method1 = println("method 1")
val x = {
def method2 = "method 2" // method inside a block
"this is " + method2
}
method1 // statement inside an object
println(x) // same
}
I mean, it feels inconsistent to me because here I see two different concepts :
Objects/Classes/Traits, which contains members.
Blocks, which contains statements, the last statement being the value of the block.
But here we have a method part of a block, and statements part of an object. So, does it mean that blocks are objects too ? And how are handled the statements part of an object, are they members too ?
Thanks.
Does it mean that blocks are objects too?
No, blocks are not objects. Blocks are used for scoping the binding of variables. Scala enables not only defining expressions inside blocks but also to define methods. If we take your example and compile it, we can see what the compiler does:
object Test extends Object {
def method1(): Unit = scala.Predef.println("method 1");
private[this] val x: String = _;
<stable> <accessor> def x(): String = Test.this.x;
final <static> private[this] def method2$1(): String = "method 2";
def <init>(): tests.Test.type = {
Test.super.<init>();
Test.this.x = {
"this is ".+(Test.this.method2$1())
};
Test.this.method1();
scala.Predef.println(Test.this.x());
()
}
}
What the compiler did is extract method2 to an "unnamed" method on method2$1 and scoped it to private[this] which is scoped to the current instance of the type.
And how are handled the statements part of an object, are they members
too?
The compiler took method1 and println and calls them inside the constructor when the type is initialized. So you can see val x and the rest of the method calls are invoked at construction time.
method2 is actually not a method. It is a local function. Scala allows you to create named functions inside local scopes for organizing your code into functions without polluting the namespace.
It is most often used to define local tail-recursive helper functions. Often, when making a function tail-recursive, you need to add an additional parameter to carry the "state" on the call stack, but this additional parameter is a private internal implementation detail and shouldn't be exposed to clients. In languages without local functions, you would make this a private helper alongside the primary method, but then it would still be within the namespace of the class and callable by all other methods of the class, when it is really only useful for that particular method. So, in Scala, you can instead define it locally inside the method:
// non tail-recursive
def length[A](ls: List[A]) = ls match {
case Nil => 0
case x :: xs => length(xs) + 1
}
//transformation to tail-recursive, Java-style:
def length[A](ls: List[A]) = lengthRec(ls, 0)
private def lengthRec[A](ls: List[A], len: Int) = ls match {
case Nil => len
case x :: xs => lengthRec(xs, len + 1)
}
//tail-recursive, Scala-style:
def length[A](ls: List[A]) = {
//note: lengthRec is nested and thus can access `ls`, there is no need to pass it
def lengthRec(len: Int) = ls match {
case Nil => len
case x :: xs => lengthRec(xs, len + 1)
}
lengthRec(ls, 0)
}
Now you might say, well I see the value in defining local functions inside methods, but what's the value in being able to define local functions in blocks? Scala tries to as simple as possible and have as few corner cases as possible. If you can define local functions inside methods, and local functions inside local functions … then why not simplify that rule and just say that local functions behave just like local fields, you can simply define them in any block scope. Then you don't need different scope rules for local fields and local functions, and you have simplified the language.
The other thing you mentioned, being able to execute code in the bode of a template, that's actually the primary constructor (so to speak … it's technically more like an initializer). Remember: the primary constructor's signature is defined with parentheses after the class name … but where would you put the code for the constructor then? Well, you put it in the body of the class!

Why can auxiliary constructors in Scala only consist of a single call to another constructor?

I think I see the merit in defining auxiliary constructors in such a way that the primary constructor is the solitary point of entry to the class. But why can't I do something like this?
class Wibble(foo: Int, bar: String) {
def this(baz: List[Any]) = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
this(bazLength, someText)
}
}
Is it maybe a way of guaranteeing that the auxiliary constructor doesn't have side effects and/or can't return early?
Auxiliary constructors can contain more than a single invocation of another constructor, but their first statement must be said invocation.
As explained in Programming in Scala, ch. 6.7:
In Scala, every auxiliary constructor must invoke another constructor of
the same class as its first action. In other words, the first statement in every
auxiliary constructor in every Scala class will have the form this(. . . ).
The invoked constructor is either the primary constructor (as in the Rational
example), or another auxiliary constructor that comes textually before the
calling constructor. The net effect of this rule is that every constructor invocation
in Scala will end up eventually calling the primary constructor of the
class. The primary constructor is thus the single point of entry of a class.
If you’re familiar with Java, you may wonder why Scala’s rules for
constructors are a bit more restrictive than Java’s. In Java, a constructor
must either invoke another constructor of the same class, or directly invoke
a constructor of the superclass, as its first action. In a Scala class, only the
primary constructor can invoke a superclass constructor. The increased
restriction in Scala is really a design trade-off that needed to be paid in
exchange for the greater conciseness and simplicity of Scala’s constructors
compared to Java’s.
Just as in Java, one can get round this limitation by extracting the code to be executed before the primary constructor call into a separate method. In Scala it is a bit more tricky than in Java, as apparently you need to move this helper method into the companion object in order to be allowed to call it from the constructor.
Moreover, your specific case is awkward as you have two constructor parameters and - although one can return tuples from a function - this returned tuple is then not accepted as the argument list to the primary constructor. For ordinary functions, you can use tupled, but alas, this doesn't seem to work for constructors. A workaround would be to add yet another auxiliary constructor:
object Wibble {
private def init(baz: List[Any]): (Int, String) = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
println("init")
(bazLength, someText)
}
}
class Wibble(foo: Int, bar: String) {
println("Wibble wobble")
def this(t: (Int, String)) = {
this(t._1, t._2)
println("You can execute more code here")
}
def this(baz: List[Any]) = {
this(Wibble.init(baz))
println("You can also execute some code here")
}
}
This at least works, even if it is slightly complicated.
scala> val w = new Wibble(List(1, 2, 3))
init
Wibble wobble
You can execute more code here
You can also execute some code here
w: Wibble = Wibble#b6e385
Update
As #sschaef's pointed out in his comment, this can be simplified using a factory method in the companion object:
object Wobble {
def apply(baz: List[Any]): Wobble = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
println("init")
new Wobble(bazLength, someText)
}
}
class Wobble(foo: Int, bar: String) {
println("Wobble wibble")
}
Thus we need no new to create an object anymore:
scala> val w = Wobble(List(1, 2, 3))
init
Wobble wibble
w: Wobble = Wobble#47c130

Scala singleton factories and class constants

OK, in the question about 'Class Variables as constants', I get the fact that the constants are not available until after the 'official' constructor has been run (i.e. until you have an instance). BUT, what if I need the companion singleton to make calls on the class:
object thing {
val someConst = 42
def apply(x: Int) = new thing(x)
}
class thing(x: Int) {
import thing.someConst
val field = x * someConst
override def toString = "val: " + field
}
If I create companion object first, the 'new thing(x)' (in the companion) causes an error. However, if I define the class first, the 'x * someConst' (in the class definition) causes an error.
I also tried placing the class definition inside the singleton.
object thing {
var someConst = 42
def apply(x: Int) = new thing(x)
class thing(x: Int) {
val field = x * someConst
override def toString = "val: " + field
}
}
However, doing this gives me a 'thing.thing' type object
val t = thing(2)
results in
t: thing.thing = val: 84
The only useful solution I've come up with is to create an abstract class, a companion and an inner class (which extends the abstract class):
abstract class thing
object thing {
val someConst = 42
def apply(x: Int) = new privThing(x)
class privThing(x: Int) extends thing {
val field = x * someConst
override def toString = "val: " + field
}
}
val t1 = thing(2)
val tArr: Array[thing] = Array(t1)
OK, 't1' still has type of 'thing.privThing', but it can now be treated as a 'thing'.
However, it's still not an elegant solution, can anyone tell me a better way to do this?
PS. I should mention, I'm using Scala 2.8.1 on Windows 7
First, the error you're seeing (you didn't tell me what it is) isn't a runtime error. The thing constructor isn't called when the thing singleton is initialized -- it's called later when you call thing.apply, so there's no circular reference at runtime.
Second, you do have a circular reference at compile time, but that doesn't cause a problem when you're compiling a scala file that you've saved on disk -- the compiler can even resolve circular references between different files. (I tested. I put your original code in a file and compiled it, and it worked fine.)
Your real problem comes from trying to run this code in the Scala REPL. Here's what the REPL does and why this is a problem in the REPL. You're entering object thing and as soon as you finish, the REPL tries to compile it, because it's reached the end of a coherent chunk of code. (Semicolon inference was able to infer a semicolon at the end of the object, and that meant the compiler could get to work on that chunk of code.) But since you haven't defined class thing it can't compile it. You have the same problem when you reverse the definitions of class thing and object thing.
The solution is to nest both class thing and object thing inside some outer object. This will defer compilation until that outer object is complete, at which point the compiler will see the definitions of class thing and object thing at the same time. You can run import thingwrapper._ right after that to make class thing and object thing available in global scope for the REPL. When you're ready to integrate your code into a file somewhere, just ditch the outer class thingwrapper.
object thingwrapper{
//you only need a wrapper object in the REPL
object thing {
val someConst = 42
def apply(x: Int) = new thing(x)
}
class thing(x: Int) {
import thing.someConst
val field = x * someConst
override def toString = "val: " + field
}
}
Scala 2.12 or more could benefit for sip 23 which just (August 2016) pass to the next iteration (considered a “good idea”, but is a work-in-process)
Literal-based singleton types
Singleton types bridge the gap between the value level and the type level and hence allow the exploration in Scala of techniques which would typically only be available in languages with support for full-spectrum dependent types.
Scala’s type system can model constants (e.g. 42, "foo", classOf[String]).
These are inferred in cases like object O { final val x = 42 }. They are used to denote and propagate compile time constants (See 6.24 Constant Expressions and discussion of “constant value definition” in 4.1 Value Declarations and Definitions).
However, there is no surface syntax to express such types. This makes people who need them, create macros that would provide workarounds to do just that (e.g. shapeless).
This can be changed in a relatively simple way, as the whole machinery to enable this is already present in the scala compiler.
type _42 = 42.type
type Unt = ().type
type _1 = 1 // .type is optional for literals
final val x = 1
type one = x.type // … but mandatory for identifiers