Why is it possible to assign recursive lambdas to non-lazy vals in Scala? - scala

In the following statement the val f is defined as a lambda that references itself (it is recursive):
val f: Int => Int = (a: Int) =>
if (a > 10) 3 else f(a + 1) + 1 // just some simple function
I've tried it in the REPL, and it compiles and executes correctly.
According to the specification, this seems like an instance of illegal forward referencing:
In a statement sequence s[1]...s[n] making up a block, if a simple
name in s[i] refers to an entity defined by s[j] where j >= i,
then for all s[k] between and including s[i] and s[j],
s[k] cannot be a variable definition.
If s[k] is a value definition, it must be lazy.
The assignment is a single statement, so it satisfied the j >= i criteria, and it is included in the interval of statements the two rules apply to (between and including s[i] and s[j]).
However, it seems that it violates the second rule, because f is not lazy.
How is that a legal statement (tried it in Scala 2.9.2)?

You probably tried to use this in the REPL, which wraps all contents in an object definition. This is important because in Scala (or better: on the JVM) all instance values are initialized with a default value, which is null for all AnyRefs and 0, 0.0 or false for AnyVals. For method values this default initialization does not happen, therefore you get an error message in this case:
scala> object x { val f: Int => Int = a => if (a > 10) 3 else f(a+1)+1 }
defined object x
scala> def x { val f: Int => Int = a => if (a > 10) 3 else f(a+1)+1 }
<console>:7: error: forward reference extends over definition of value f
def x { val f: Int => Int = a => if (a > 10) 3 else f(a+1)+1 }
^
This behavior can even lead to weird situations, therefore one should be careful with recursive instance values:
scala> val m: Int = m+1
m: Int = 1
scala> val s: String = s+" x"
s: String = null x

Related

Set of WrappedArray: Type arguments [Int] do not conform to method empty's type parameter bounds [T <: AnyRef]

I'm trying to make a function that calculates how many combinations of elements with repetition there are given an array of values and a exact sum value.
But I'm getting an error:
Error:(23, 38) type arguments [Int] do not conform to method empty's type parameter bounds [T <: AnyRef]
r(maxValue,WrappedArray.empty[Int],Set[WrappedArray[Int]]()).size
It seems there is a type problem in the empty set I'm trying to pass to the function.
I choosed WrappedArrays following this [question]: Scala: lightweight way to put Arrays in a Set or Map in order to be able to have a set of arrays without duplicates.
import scala.collection.mutable.WrappedArray
def Combinations(maxValue: Int): Int = {
val values= Array(1,2,5,10)
def r (a:Int,can:WrappedArray[Int],sol:Set[WrappedArray[Int]]): Set[WrappedArray[Int]] ={
values.map(x=> if (a-x > 0) r(a-x,can:+x,sol) else if (a-x == 0) sol + (can:+x).sorted else sol).reduce((x, y)=>x union y)
}
r(maxValue,WrappedArray.empty[Int],Set[WrappedArray[Int]]()).size
}
Combinations(4)
Thanks
WrappedArray.empy is bounded by AnyRef, as Int inherits from AnyVal you cannot declare your wrappedArray this way.
However you can declare your empty array this way new WrappedArray.ofInt(Array())
Here is a little fiddle for you
https://scalafiddle.io/sf/PioRREd/0
I've never seen anyone ever importing WrappedArray for anything. It's a rather obscure implementation detail for providing collection methods on ordinary arrays, it has no place in the solution of combinatoric problems. Another general remark: methodNames are written in camel-case, starting with a lowercase letter.
Here is a more idiomatic (and also much simpler) solution:
def numCombinations(
sum: Int,
coins: List[Int] = List(1, 2, 5, 10)
): Long = {
coins match {
case Nil => if (sum == 0) 1L else 0L
case h :: t => {
(0 to sum / h)
.map { i => numCombinations(sum - i * h, t) }
.sum
}
}
}
println(numCombinations(4))
Example: for n = 4, it will find the combinations
1 + 1 + 1 + 1
1 + 1 + 2
2 + 2
and output 3.

Functional Sets / Apply method

I have just started learning scala from the Coursera course by Martin Odesky. I am really struggling at the functional sets problem. The thing I am not able to catch is the union method-
object Functionalset {
type Set = Int => Boolean
def singletonSet(element: Int): Set = i => element == i
def union(a: Set, b: Set): Set = i => a(i) || b(i)
def main(args:Array[String]): Unit = {
print(singletonSet(2)(4));
}
}
In the union method I am essentially returning a function that takes an Int i and calls a(i) || b(i) to check whether i is in the set or not. The apply method is not defined anywhere. What does the a(i) do? Does it call the singletonSet(element:Int):Set? If so how?
What does the a(i) do? Does it call the singletonSet(element: Int)
No, there is no relationship between the two methods. a(i) in this particular case is simply the invocation of the function a, which is a function from Int to Boolean.
a is a of type Set, which is a type alias for a function from Int to Boolean (Int => Boolean with Scala syntax sugar).
Think of it like this:
def union(a: Int => Boolean, b: Int => Boolean): Int => Boolean = i => a(i) || b(i)
Since a is a function of type Function1[Int, Boolean], and so is b, calling a(i) is simply invoking the function with the passed value of i. Now, what may be confusing is the notation of:
i => a(i) || b(i)
Since union itself returns a function, it needs a placeholder for any future Int which may be passed in, this happens when you call singletonSet(2)(4), if we desugarize it a little, you have:
val intermidiateFunction: Int => Boolean = singletonSet(2)
val result: Boolean = intermidiateFunction(4)
Think of it as a two step invocation of a method, when you do the first invocation, you get back another function, and only when you call it the second time, you get back the result of the generated function.
Let's invoke union and see what happens:
scala> union(i => i < 3, i => i > 1)
res6: Set = <function1>
scala> val result = union(i => i < 3, i => i > 1)
result: Set = <function1>
scala> result(1)
res7: Boolean = true
union requires us to pass in two functions, so we create these simplified functions that check whether an Int is smaller than 3 or bigger than 1. The result of the first invocation is itself a function. When we'll now pass in an Int to the result, for example: result(1), we will check 1 < 3 || 1 > 1, which is equivalent to a(i) || b(i), where a is the first function, and b is the second.
In this lab, a set is defined as its characteristic function.
This translates into:
type Set = Int => Boolean
Which means that a Set is simply a function taking an Int and returning a Boolean (this is the characteristic function of the Set, an oracle which tells whether a given integer is in the set or not).
Your variable a, being a Set, is a function Int => Boolean, so a(i) is well-defined if i is an Int.
The characteristic function of a union of two sets is a function which returns true if its argument is in one of the two sets, false otherwise.

Intellij worksheet and classes defined in it

I'm following along the Coursera course on functional programming in Scala and came along a weird behavior of the worksheet repl.
In the course a worksheet with the following code should give the following results on the right:
object rationals {
val x = new Rational(1, 2) > x : Rational = Rational#<hash_code>
x.numer > res0: Int = 1
y. denom > res1: Int = 2
}
class Rational(x: Int, y: Int) {
def numer = x
def denom = y
}
What I get is
object rationals { > defined module rationals
val x = new Rational(1, 2)
x.numer
y. denom
}
class Rational(x: Int, y: Int) { > defined class Rational
def numer = x
def denom = y
}
Only after moving the class into the object I got the same result as in the code.
Is this caused by Intellij, or have there been changes in Scala?
Are there other ways around this?
In the IntelliJ IDEA scala worksheet handles values inside the objects differently than Eclipse/Scala IDE.
Values inside objects are not evaluated in linear sequence mode, instead they are treated as normal scala object. You barely see information about it until explicit use.
To actually see your vals and expressions simply define or evaluate them outside any object\class
This behaviour could be a saviour in some cases. Suppose you have that definitions.
val primes = 2l #:: Stream.from(3, 2).map(_.toLong).filter(isPrime)
val isPrime: Long => Boolean =
n => primes.takeWhile(p => p * p <= n).forall(n % _ != 0)
Note that isPrime could be a simple def, but we choose to define it as val for some reason.
Such code is nice and working in any normal scala code, but will fail in the worksheet, because vals definitions are cross-referencing.
But it you wrap such lines inside some object like
object Primes {
val primes = 2l #:: Stream.from(3, 2).map(_.toLong).filter(isPrime)
val isPrime: Long => Boolean =
n => primes.takeWhile(p => p * p <= n).forall(n % _ != 0)
}
It will be evaluated with no problem

Why can't a variable be assigned placeholder in function literal?

I'm having trouble understanding underscores in function literals.
val l = List(1,2,3,4,5)
l.filter(_ > 0)
works fine
l.filter({_ > 0})
works fine
l.filter({val x=1; 1+_+3 > 0}) // ie you can have multiple statements in your function literal and use the underscore not just in the first statement.
works fine
And yet:
l.filter({val x=_; x > 0})
e>:1: error: unbound placeholder parameter
l.filter({val x=_; x > 0})
I can't assign the _ to a variable, even though the following is legal function literal:
l.filter(y => {val x=y; x > 0})
works fine.
What gives? Is my 'val x=_' getting interpreted as something else? Thanks!
Actually, you have to back up a step.
You are misunderstanding how the braces work.
scala> val is = (1 to 5).toList
is: List[Int] = List(1, 2, 3, 4, 5)
scala> is map ({ println("hi") ; 2 * _ })
hi
res2: List[Int] = List(2, 4, 6, 8, 10)
If the println were part of the function passed to map, you'd see more greetings.
scala> is map (i => { println("hi") ; 2 * i })
hi
hi
hi
hi
hi
res3: List[Int] = List(2, 4, 6, 8, 10)
Your extra braces are a block, which is some statements followed by a result expression. The result expr is the function.
Once you realize that only the result expr has an expected type that is the function expected by map, you wouldn't think to use underscore in the preceding statements, since a bare underscore needs the expected type to nail down what the underscore means.
That's the type system telling you that your underscore isn't in the right place.
Appendix: in comments you ask:
how can I use the underscore syntax to bind the parameter of a
function literal to a variable
Is this a "dumb" question, pardon the expression?
The underscore is so you don't have to name the parameter, then you say you want to name it.
One use case might be: there are few incoming parameters, but I'm interested in naming only one of them.
scala> (0 /: is)(_ + _)
res10: Int = 15
scala> (0 /: is) { case (acc, i) => acc + 2 * i }
res11: Int = 30
This doesn't work, but one may wonder why. That is, we know what the fold expects, we want to apply something with an arg. Which arg? Whatever is left over after the partially applied partial function.
scala> (0 /: is) (({ case (_, i) => _ + 2 * i })(_))
or
scala> (0 /: is) (({ case (_, i) => val d = 2 * i; _ + 2 * d })(_))
SLS 6.23 "placeholder syntax for anonymous functions" mentions the "expr" boundary for when you must know what the underscore represents -- it's not a scope per se. If you supply type ascriptions for the underscores, it will still complain about the expected type, presumably because type inference goes left to right.
The underscore syntax is mainly user for the following replacement:
coll.filter(x => { x % 2 == 0});
coll.filter(_ % 2 == 0);
This can only replace a single parameter. This is the placeholder syntax.
Simple syntactic sugar for a lambda.
In the breaking case you are attempting null initialization/defaulting.
For primitive types with init conventions:
var x: Int = _; // x will be 0
The general case:
var y: List[String] = _; // y is null
var z: Any = _; // z = null;
To get pedantic, it works because null is a ref to the only instance of scala.Null, a sub-type of any type, which will always satisfy the type bound because of covariance. Look HERE.
A very common usage scenario, in ScalaTest:
class myTest extends FeatureTest with GivenWhenThen with BeforeAndAfter {
var x: OAuthToken = _;
before {
x = someFunctionThatReturnsAToken;
}
}
You can also see why you shouldn't use it with val, since the whole point is to update the value after initialization.
The compiler won't even let you, failing with: error: unbound placeholder parameter.
This is your exact case, the compiler thinks you are defaulting, a behaviour undefined for vals.
Various constraints, such as timing or scope make this useful.
This is different from lazy, where you predefine the expression that will be evaluated when needed.
For more usages of _ in Scala, look HERE.
Because in this two cases underscore (_) means two different things. In case of a function it's a syntactic sugar for lambda function, your l.filter(_ > 0) later desugares into l.filter(x => x > 0). But in case of a var it has another meaning, not a lambda function, but a default value and this behavior is defined only for var's:
class Test {
var num: Int = _
}
Here num gonna be initialized to its default value determined by its type Int. You can't do this with val cause vals are final and if in case of vars you can later assign them some different values, with vals this has no point.
Update
Consider this example:
l filter {
val x = // compute something
val z = _
x == z
}
According to your idea, z should be bound to the first argument, but how scala should understand this, or you you have more code in this computation and then underscore.
Update 2
There is a grate option in scala repl: scala -Xprint:type. If you turn it on and print your code in (l.filter({val x=1; 1+_+3 > 0})), this what you'll see:
private[this] val res1: List[Int] = l.filter({
val x: Int = 1;
((x$1: Int) => 1.+(x$1).+(3).>(0))
});
1+_+3 > 0 desugares into a function: ((x$1: Int) => 1.+(x$1).+(3).>(0)), what filter actually expects from you, a function from Int to Boolean. The following also works:
l.filter({val x=1; val f = 1+(_: Int)+3 > 0; f})
cause f here is a partially applied function from Int to Boolean, but underscore isn't assigned to the first argument, it's desugares to the closes scope:
private[this] val res3: List[Int] = l.filter({
val x: Int = 1;
val f: Int => Boolean = ((x$1: Int) => 1.+((x$1: Int)).+(3).>(0));
f
});

how to simplify scala's function literal like this?

I'm new to scala and trying to write a function literal that check whether a given integer is odd or not.
my first attempt is:
val isOdd = (x:Int) => (x & 1) == 1
it works great, and, since the parameter x only appears once within this function literal, I'm tempted to use the "_" notation to simplify it further, like this:
val isOdd = ((_:Int) & 1 ) == 1
however this time the compiler complains :
warning: comparing a fresh object using `==' will always yield false
val isOdd = ((_:Int) & 1 ) == 1
what does this warning mean? why does the compiler recognize ((_ :Int) & 1) as fresh object rather than a bitwise operation that results in a value? is there any way to write this function literal using the "_" notation?
The problem is basically that Scala needs to tell the difference between
val isOdd = ((_:Int) & 1 ) == 1
where you want everything to the right of the equals sign to be a lambda, and
val result = collection.map( _ + 1 )
where you want only the stuff inside the parentheses to be a lambda
Scala has decided that when you use the underscore to create a lambda, that it's going to pick the innermost set of parentheses as the boundaries of that lambda. There's one exception: (_:Int) doesn't count as the innermost parentheses because its purpose is only to group they type declaration with the _ placeholder.
Hence:
val isOdd = ((_:Int) & 1 ) == 1
^^^^^^^^^^^^^^
this is the lambda
val result = collection.map( _ + 1 )
^^^^^^^
this is the lambda
val result = collection.map(( _ + 1) / 2)
^^^^^^^^
this is the lambda
and the compiler can't infer the type of the _
val result = somemap.map(( _ + 1) / 2 * _)
^^^^^^^^
this is an inner lambda with one parameter
and the compiler can't infer the type of the _
^^^^^^^^^^^^^^^^^
this is an outer lambda with one parameter
This last case lets you do things like
_.map(_ + 1)
and have that get translated into
x => x.map( y=> y + 1 )
Only slightly cheating:
val isOdd = (_: Int) % 2 == 1
:-)
There you go:
val isOdd = ((_: Int) & 1) andThen (1 ==)
What Scala is doing is this:
it sees ((_:Int) & 1 ) and creates an object of type (Int) => Int, that is, a function.
it then applies the comparison operator == to compare this function to the value 1
A function is not equal to the value 1. Therefore the result is false, so your code is equivalent to:
val isOdd = false
What you could do is create another anonymous function that does the == 1 part of your computation. This is ugly:
val isOdd = ((_: Int) & 1)(_: Int) == 1
This is equivalent to the more verbose (and perhaps easier to understand):
val isOdd = (x: Int) => 1 == ((_: Int) & 1)(x)
A different approach
val isOdd = (_:Int).&(1) == 1