Unexpected result when invoke functions within method in scala - scala

I start to learn scala by writing simple code.
I'm a little confused about the behavior of below code.
class BasicUsage {
private val incr = (x: Int) =>
{
println("incr invoked")
x + 1
}
private val add = (x: Int, y: Int) =>
{
println("add invoked")
if (x == 0 || y == 0) {
0
} else {
x + y
}
}
def testFuns(): Unit =
println(add(1,2))
println(incr(5))
}
When invoking testFuns(), the output is as below,
incr invoked
6
add invoked
3
Per my understanding, functions add() should be called firstly, then incr() should be invoked.
What's the mistake in above code?
Do I misunderstand the usage of function and method?
Thanks very much,

You're missing curly braces in your testFuns method:
def testFuns(): Unit =
println(add(1,2))
println(incr(5))
This means that testFuns() contains only one first statement: println(add(1,2)). The second statement belongs to class and gets executed once BasicUsage instantiated. To fix it do:
def testFuns(): Unit = {
println(add(1,2))
println(incr(5))
}

Related

Declare variable in Scala

I just new in Scala, I know Scala have three keywords to declare variables is:
def defines a method
val defines a fixed value (which cannot be modified)
var defines a variable (which can be modified)
I am going to write some code to test with an anonymous method.
object Anonymous {
def main(args: Array[String]): Unit = {
def double_1 = (i: Int) => { i * 2 }
val double_2 = (i: Int) => { i * 2 }
var double_3 = (i: Int) => { i * 2 }
println(double_1(2))
println(double_2(2))
println(double_3(2))
}
}
What is the difference about three ways above, when I use double_1, double_2, double_3?
What is the memory segment have to store the variables?
Thanks!
First off, they are not anonymous methods. They are functions and they each have a name so they are not anonymous.
The main difference between them is that double_3 can be reassigned to some different function value.
var double_3 = (i: Int) => { i * 2 }
double_3 = (i: Int) => i + 3 // the compiler allows this
The others cannot.
It would be rather unusual to defined a function as a def. def is mostly used to declare methods because a def is re-evaluated every time it is referenced.
def x = 3 + 4
val y = 3 + 4
Both x and y evaluate to 7, but the addition is redone every time x is referenced. For y the addition is done once, at the definition, and never again.

IndexedSeq-based equivalent of Stream?

I have a lazily-calculated sequence of objects, where the lazy calculation depends only on the index (not the previous items) and some constant parameters (p:Bar below). I'm currently using a Stream, however computing the stream.init is typically wasteful.
However, I really like that using Stream[Foo] = ... gets me out of implementing a cache, and has very light declaration syntax while still providing all the sugar (like stream(n) gets element n). Then again, I could just be using the wrong declaration:
class FooSrcCache(p:Bar) {
val src : Stream[FooSrc] = {
def error() : FooSrc = FooSrc(0,p)
def loop(i: Int): Stream[FooSrc] = {
FooSrc(i,p) #:: loop(i + 1)
}
error() #:: loop(1)
}
def apply(max: Int) = src(max)
}
Is there a Stream-comparable base Scala class, that is indexed instead of linear?
PagedSeq should do the job for you:
class FooSrcCache(p:Bar) {
private def fill(buf: Array[FooSrc], start: Int, end: Int) = {
for (i <- start until end) {
buf(i) = FooSrc(i,p)
}
end - start
}
val src = new PagedSeq[FooSrc](fill _)
def apply(max: Int) = src(max)
}
Note that this might calculate FooSrc with higher indices than you requested.

How to tell the Scala compiler that a while loop will return a value?

Some algorithms execute a while loop with condition true and will (for sure) end at some point with a return statement inside the body of the while loop. E.g.:
def foo: Int = {
while(true) {
// At some time, the while loop will do a return statement inside its body
if( ... )
return 0
}
}
Simple example (without semantic sense):
def foo: Int = {
var i = 0
while(true) {
i += 1
if(i == 10)
return 0
}
}
The Scala compiler complains about a type mismatch, because the while loop has type Unit and the compiler does not know, that the while loop will at some point return a value. We could fix this with a workaround like:
def foo: Int = {
var i = 0
while(true) {
i += 1
if(i == 10)
return 0
}
0 // !
}
But this looks ugly. Is there a better workaround ? Or even a better solution for this kind of problem ?
You could throw an exception:
def foo: Int = {
var i = 0
while(true) {
i += 1
if(i == 10)
return 0
}
throw new IllegalStateException("This should never happen")
}
The compiler will stop complaining about the type mismatch, and since the while loop always returns something, the exception will never be thrown. And if it is, you will quickly find out where you did something wrong :).
There are other ways to write this loop which are more idomatic and Scala-esque, but given the code you provided, this will get the job done in a clear and simple way.
Maybe you should just use tail recursion instead. It should end up compiling down to very similar bytecode:
import scala.annotation.tailrec
def foo: Int = {
#tailrec def bar(i: Int): Int = {
val j = i + 1
if (j == 10) return 0
else bar(j)
}
bar(0)
}
You might even want to make use of the default parameter value support:
#tailrec def foo(i: Int = 0): Int = {
val j = i + 1
if (j == 10) return 0
else foo(j)
}
Note that this way requires you to call the function as foo() not foo since it has an argument.
A more idiomatic way would be to use recursion. Something like this:
def foo: Int = {
import scala.annotation.tailrec
#tailrec def whileUnderTen(i: Int):Int = if ( i < 10) whileUnderTen(i+1) else 0
whileUnderTen(0)
}
For just these occasions, I have a "forever" construct defined in my personal standard library.
forever{
}
is in all ways equivalent to
while(true){
}
except that forever has type Nothing while the equivalent while construct has type Unit. Just one of those small extension capabilities that makes Scala such a joy.

Storing an anonymous function passed as a parameter in a Map

I'm trying to implement a simple web application server as a personal project to improve my Scala, but I've hit upon a problem.
I'd like to be able to set up routes using code like the following:
def routes()
{
get("/wobble")
{
...many lines of code here...
}
get("/wibble")
{
...many lines of code here...
}
post("/wibble")
{
...many lines of code here...
}
post("/wobble")
{
...many lines of code here...
}
}
routes is called by the server when it starts and get and post are functions defined by me like this:
get(url:String)(func:()=>String)=addroute("GET",url,func)
post(url:String(func:()=>String)=addroute("POST",url,func)
addroute(method:String,url:String,f:()=>String)
{
routesmap+=(method->Map[String,()=>String](url,func))
}
Unfortunately, I've had nothing but problems with this. Could anyone tell me the correct way in Scala to add an anonymous function (as passed in as a parameter in the defined routes function above) to a Map (or any other Scala collection for that matter)?
Here is a working example:
scala> var funcs = Map[String,(Int)=>Int]()
funcs: scala.collection.immutable.Map[String,Int => Int] = Map()
scala> funcs += ("time10", i => i * 10 )
scala> funcs += ("add2", i => i + 2 )
scala> funcs("add2")(3)
res3: Int = 5
scala> funcs("time10")(10)
res4: Int = 100
You can also add a declared function:
val minus5 = (i:Int) => i - 5
funcs += ( "minus5", minus5)
Or a method:
def square(i: Int) = i*i
funcs += ("square", square)
In your case, you can have two maps, one for GET and one for POST. It should simplify the design (and at most, you will end with four maps if you include DEL and PUT).
May be, this one ? :
type Fonc = ( (=> String) => Unit)
var routesmap = Map[String,Map[String,()=>String]]()
def addRoute(method:String,url:String,f:()=>String) = {
routesmap+=(method-> (routesmap.getOrElse(method,Map[String,()=>String]()) + (url->f)))
}
def get(url:String):Fonc = (x => addRoute("GET",url,() => x))
def post(url:String):Fonc = (x => addRoute("POST",url,() => x))
def routes()
{
post("/wobble")
{
"toto"
}
get("/wibble")
{
"titi"
}
}
you can try this code :
def addRoute(method:String,url:String,f:()=>String) = {
routesmap+=(method-> (routesmap.getOrElse(method,Map[String,()=>String]()) + (url->f)))
}
def get(url:String,func:()=>String)= addRoute("GET",url,func)
def post(url:String,func:()=>String)= addRoute("POST",url,func)
def routes()
{
get("/wobble",()=>{"toto"})
get("/wibble",()=>{println("test")
"titi"})
}
and execute these commands
scala> routes
scala> routesmap.get("GET").get("/wibble")()

method with angle brackets (<>)

Is it possible to have angle brackets in method names , e.g. :
class Foo(ind1:Int,ind2:Int){...}
var v = new Foo(1,2)
v(1) = 3 //updates ind1
v<1> = 4 //updates ind2
The real situation is obviously more complicated than this!!I am trying to provide a convenient user interface.
This response is not meant to be taken too seriously - just a proof that this can almost be achieved using some hacks.
class Vector(values: Int*) {
val data = values.toArray
def < (i:Int) = new {
def `>_=`(x: Int) {
data(i) = x
}
def > {
println("value at "+ i +" is "+ data(i))
}
}
override def toString = data.mkString("<", ", ", ">")
}
val v = new Vector(1, 2, 3)
println(v) // prints <1, 2, 3>
v<1> = 10
println(v) // prints <1, 10, 3>
v<1> // prints: value at 1 is 10
Using this class we can have a vector that uses <> instead of () for "read" and write access.
The compiler (2.9.0.1) crashes if > returns a value. It might be a bug or a result of misusing >.
Edit: I was wrong; kassens's answer shows how to do it as you want.
It is not possible to implement a method that would be called when you write v<1> = 4 (except, maybe, if you write a compiler plugin?). However, something like this would be possible:
class Foo {
def at(i: Int) = new Assigner(i)
class Assigner(i: Int) {
def :=(v: Int) = println("assigning " + v + " at index " + i)
}
}
Then:
val f = new Foo
f at 4 := 6
With a little trickery you can actually get quite close to what you want.
object Foo {
val a:Array[Int] = new Array(100)
def <(i:Int) = new Updater(a, i)
}
class Updater(a:Array[Int], i:Int) {
def update(x:Int) {
a(i) = x
}
def >() = this
}
Foo<1>() = 123
I am not sure why Scala requires the () though. And yes, this is a bit of a hack...