call a def within a block - scala

If there is any way to call a def from a block
def factor (n: Int) : Int = if (n == 0 ) 1 else n * factor(n-1)
val i = 1000
i.toString.foreach ( x => sum += factor(x.toInt) )
at the end I want to get the sum of factorial of every digit
But it seems like def doesn't return a value, everytime is 0
How to fix it?
Thanks!

The problem actually has nothing to do with Scala per se; your code and your def are fine. The issue is with toInt:
scala> '3'.toInt
res7: Int = 51
toInt doesn't actually convert it as a decimal digit, but as a unicode (ish?) character value. These are producing very large numbers which go beyond what factor can handle:
scala> factor(6)
res8: Int = 720
scala> factor(20)
res9: Int = -2102132736
scala> factor(100)
res10: Int = 0
So instead use (thanks to Luigi)
x.asDigit

Related

How to declare in scala a default param in a method of an implicit class

In order to use infix notation, I have the following example of scala code.
implicit class myclass(n:Int ){
private def mapCombineReduce(map : Int => Double, combine: (Double,Double) => Double, zero: Double )(a:Int, b:Double): Double =
if( a > b) zero else combine ( map(a), mapCombineReduce(map,combine,zero)(a+1,b) )
var default_value_of_z : Int = 0
def sum( z : Int = default_value_of_z) = mapReduce( x=>x , (x,y) => x+y+z, 0)(1,n)
def ! = mapCombineReduce( x=> x, (x,y) => x*y, 1)(1,n)
}
4 !
4 sum 1 //sum the elements from 1 to 7 and each time combine the result, add 1 to the result.
4 sum
Is there any way in scala 2.12 to run 4 sum without have a double declaration of the sum method inside myclass ?
No, because default arguments are only used if argument list is provided
def f(x: Int = 1) = x
f // interpreted as trying to do eta-expansion
In fact starting Scala 3 it will indeed eta-expand
scala> def f(x: Int = 1) = x
def f(x: Int): Int
scala> f
val res1: Int => Int = Lambda$7473/1229666909#61a1990e
so in your case you will have to write 4.sum() with argument list present.

custom absolute function is not working for large long values in Scala

I have written custom function to get absolute value for long number. Below is the
def absolute(x:Long):Long= x match {
case y:Long if(y<0) => -1 * y
case y if(y>=0) => y
}
println(absolute(-9223372036854775808L))
println(absolute(-2300L))
Below is the output of above program
-9223372036854775808
2300
I am not sure why it is working for very big long values. Ang suggestions on the same.
This is just a case of integer overflow:
scala> Long.MaxValue
res0: Long = 9223372036854775807
scala> Long.MinValue
res1: Long = -9223372036854775808
Thus when you negate -9223372036854775808 you are overflowing the Long by 1 unit, causing it to wrap around (to itself!).
Also there is no need for a match here:
scala> def abs(x: Long): Long = if (x < 0) -x else x
abs: (x: Long)Long
Why not use scala.math.abs?
See scala.math

Scala lazy val explanation

I am taking the Functional Programming in Scala course on Coursera and I am having a hard time understanding this code snippet -
def sqrtStream(x: Double): Stream[Double] = {
def improve(guess: Double): Double = (guess+ x/ guess) / 2
lazy val guesses: Stream[Double] = 1 #:: (guesses map improve)
guesses
}
This method would find 10 approximate square root of 4 in increasing order of accuracy when I would do sqrtSteam(4).take(10).toList.
Can someone explain the evaluation strategy of guesses here? My doubt is what value of guesses in substituted when the second value of guesses is picked up?
Let's start from simplified example:
scala> lazy val a: Int = a + 5
a: Int = <lazy>
scala> a
stack overflow here, because of infinite recursion
So a is recalculating til it gets some stable value, like here:
scala> def f(f:() => Any) = 0 //takes function with captured a - returns constant 0
f: (f: () => Any)Int
scala> lazy val a: Int = f(() => a) + 5
a: Int = <lazy>
scala> a
res4: Int = 5 // 0 + 5
You may replace def f(f:() => Any) = 0 with def f(f: => Any) = 0, so a definition will look like it's really passed to the f: lazy val a: Int = f(a) + 5.
Streams use same mechanism - guesses map improve will be passed as parameter called by name (and lambda linked to the lazy a will be saved inside Stream, but not calculated until tail is requested), so it's like lazy val guesses = #::(1, () => guesses map improve). When you call guessess.head - tail will not be evaluated; guesses.tail will lazily return Stream (improve(1), ?), guesses.tail.tail will be Stream(improve(improve(1)), ?) and so on.
The value of guesses is not substituted. A stream is like a list, but its elements are evaluated only when they are needed and then they stored, so next time you access them the evaluation will not be necessary. The reference to the stream itself does not change.
On top of the example Αλεχει wrote, there is a nice explanation in Scala API:
http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Stream
You can easily find out what's going on by modifying the map function, as described in the scaladoc example:
scala> def sqrtStream(x: Double): Stream[Double] = {
| def improve(guess: Double): Double = (guess + x / guess) / 2
| lazy val guesses: Stream[Double] = 1 #:: (guesses map {n =>
| println(n, improve(n))
| improve(n)
| })
| guesses
| }
sqrtStream: (x: Double)Stream[Double]
The output is:
scala> sqrtStream(4).take(10).toList
(1.0,2.5)
(2.5,2.05)
(2.05,2.000609756097561)
(2.000609756097561,2.0000000929222947)
(2.0000000929222947,2.000000000000002)
(2.000000000000002,2.0)
(2.0,2.0)
(2.0,2.0)
(2.0,2.0)
res0: List[Double] = List(1.0, 2.5, 2.05, 2.000609756097561, 2.0000000929222947, 2.000000000000002, 2.0, 2.0, 2.0, 2.0)

Why is this function called multiple times?

In this function "f" :
def f(x: => Int) : Int = x * x * x //> f: (x: => Int)Int
var y = 0 //> y : Int = 0
f {
y += 1
println("invoked")
y
} //> invoked
//| invoked
//| invoked
//| res0: Int = 6
"f" is invoked same amount of times as "x" parameter is multiplied.
But why is function invoked multiple times ?
Should "f" not expand to 1 * 1 * 1 not 1 * 2 * 3 ?
Your x is not a function, it is a by-name parameter, and its type is a parameterless method type.
Parameterless method type means the same as def x, something that is evaluated every time you reference it. By reference, we mean x and not x.apply() or x().
The expression you're passing to your function f is evaluated every time x is referenced in f. That expression is the whole thing in braces, a block expression. A block is a sequence of statements followed by the result expression at the end.
Here's another explanation: https://stackoverflow.com/a/13337382/1296806
But let's not call it a function, even if it behaves like one under the covers.
Here is the language used in the spec:
http://www.scala-lang.org/files/archive/spec/2.11/04-basic-declarations-and-definitions.html#by-name-parameters
It's not a value type because you can't write val i: => Int.
It was a big deal when they changed the implementation so you could pass a by-name arg to another method without evaluating it first. There was never a question that you can pass function values around like that. For example:
scala> def k(y: => Int) = 8
k: (y: => Int)Int
scala> def f(x: => Int) = k(x) // this used to evaluate x
f: (x: => Int)Int
scala> f { println("hi") ; 42 }
res8: Int = 8
An exception was made to "preserve the by-name behavior" of the incoming x.
This mattered to people because of eta expansion:
scala> def k(y: => Int)(z: Int) = y + y + z
k: (y: => Int)(z: Int)Int
scala> def f(x: => Int) = k(x)(_) // normally, evaluate what you can now
f: (x: => Int)Int => Int
scala> val g = f { println("hi") ; 42 }
g: Int => Int = <function1>
scala> g(6)
hi
hi
res11: Int = 90
The question is how many greetings do you expect?
More quirks:
scala> def f(x: => Int) = (1 to 5) foreach (_ => x)
f: (x: => Int)Unit
scala> def g(x: () => Int) = (1 to 5) foreach (_ => x())
g: (x: () => Int)Unit
scala> var y = 0
y: Int = 0
scala> y = 0 ; f { y += 1 ; println("hi") ; y }
hi
hi
hi
hi
hi
y: Int = 5
scala> y = 0 ; g { y += 1 ; println("hi") ; () => y }
hi
y: Int = 1
scala> y = 0 ; g { () => y += 1 ; println("hi") ; y }
hi
hi
hi
hi
hi
y: Int = 5
Functions don't cause this problem:
scala> object X { def f(i: Int) = i ; def f(i: => Int) = i+1 }
defined object X
scala> X.f(0)
res12: Int = 0
scala> trait Y { def f(i: Int) = i }
defined trait Y
scala> object X extends Y { def f(i: => Int) = i+1 }
defined object X
scala> X.f(0)
<console>:11: error: ambiguous reference to overloaded definition,
both method f in object X of type (i: => Int)Int
and method f in trait Y of type (i: Int)Int
match argument types (Int)
X.f(0)
^
Compare method types:
http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#method-types
This is not a pedantic distinction; irrespective of the current implementation, it can be confusing to think of a by-name parameter as "really" a function.
Another way of saying what has already been said is that inside f you invoke the function x three times. The first time it increments the y var and returns 1. The second time it again increments y returning 2 and the third time it again increments y and returns 3.
If you want it invoked only once then you may want to do something like this:
def f(x: => Int) : Int = x * x * x
var y = 0
lazy val xx = {
y += 1
println("invoked")
y
}
f {xx}
This will print 'invoked' only once and result in a returned value of 1.
x: T means need a T value.
x: => T means need a T value, but it is call by name.
x: () => T This means need a function given nothing to T
However, this question is not related to the difference between function and method.
The reason is call by name is invoked every time you try to use it.
change to call by value def f(x: Int) : Int, it will only invoke once.
Because you increment y by 1 every time the argument is used inside f
The result which your function f() returns is changing, because there is a global variable that is incremented with every subsequent call to that function.
the x in f(x: => Int) is interpreted as "some function that returns Int". So it has to be called 3 times to evaluate the x*x*x expression. With every call, you increment the global variable and return the result, which is how you arrive at three subsequent natural numbers (because the global variable is initialized to 0). Hence 1*2*3.

Incrementing and getting value

Simple scala question. Consider the below.
scala> var mycounter: Int = 0;
mycounter: Int = 0
scala> mycounter += 1
scala> mycounter
res1: Int = 1
In the second statement I increment my counter. But nothing is returned. How do I increment and return something in one statement.
Using '+=' return Unit, so you should do:
{ mycounter += 1; mycounter }
You can too do the trick using a closure (as function parameters are val):
scala> var x = 1
x: Int = 1
scala> def f(y: Int) = { x += y; x}
f: (y: Int)Int
scala> f(1)
res5: Int = 2
scala> f(5)
res6: Int = 7
scala> x
res7: Int = 7
BTW, you might consider using an immutable value instead, and embrace this programming style, then all your statements will return something ;)
Sometimes I do this:
val nextId = { var i = 0; () => { i += 1; i} }
println(nextId()) //> 1
println(nextId()) //> 2
Might not work for you if you need sometime to access the value without incrementing.
Assignment is an expression that is evaluated to Unit. Reasoning behind it can be found here: What is the motivation for Scala assignment evaluating to Unit rather than the value assigned?
In Scala this is usually not a problem because there probably is a different construct for the problem you are solving.
I don't know your exact use case, but if you want to use the incrementation it might be in the following form:
(1 to 10).foreach { i =>
// do something with i
}