I execute the following assignment:-
val x = { println("hello") }
This prints hello and also prints the type of x as:-
x: Unit = ()
My understanding was that an inline function has been created and assigned to val x. So with that assumption I tried executing x as:-
x
It doesn't error out. But also prints nothing. Isn't that a function which x is holding?
What this line does:
val x = { println("hello") }
is this: it executes println("hello") and then assigns what println returns to the value x. Since println returns Unit, x will be assigned Unit.
The correct syntax for what you want to do (assign a function to x) is this:
val x = () => { println("hello") }
You can then call the function with:
x()
(which is short-hand syntax for x.apply()).
You are not assigning a function to x, you are assigning the result of a block to x. The block is executed immediately and the result (Unit) is assigned to x.
The result of a block is the result of the last statement in the block, and the result of println() is Unit.
val x = () => { println("hello") }
will assign a function to x, which can be called like this:
x()
Alternatively you can use def instead of val. val introduces constant values defined as the result of the block defining them. In your example, println("hello") is executed, then its returning value is named x. On the contrary, def introduces a method whose body is executed every time you call it.
def x = println("hello")
will then be executed every time x is called. But even with def, it's still not a function. To make it a function you have two options:
you can define directly a function (x1 : T1, ..., xn : Tn) => expr where x1 to xn are the arguments of the function, Ti is the type of xi and expr is the code you want to execute (which depends on parameters x1 to xn and anything in scope).
scala> val x = () => println("hello")
x: () => Unit = <function0>
or you can define a method as before and use the syntax methodName _ to transform your method into a function :
scala> def x = println("hello")
x: Unit
scala> x _
res0: () => Unit = <function0>
Related
I have two functions
val mul3 = 3*(_: Double)
val pow2 = (x: Double) => x*x
What I don't understand how it works at all is this:
println((pow2.andThen[Double] _ )(mul3)(5))
1) I thought andThen operates with results of the function to the left, but here it is [Double] _ - what is this? (I was expecting something like pow2 andThen mul3)
2) Why is mul3 passed to pow2 if pow2 expects Double? (mul3(pow2) gives an error)
3) What is being passed to pow2? Is it mul3 or 15?
4) What does . mean?
scala fiddle
Lets go step by step.
val mul3 = 3*(_: Double)
Is a Function from a Double to another Double. Thus, is type is Function1[Double, Double].
The same applies to:
val pow2 = (x: Double) => x*x
Now, remember that in Scala, everything is an object. And that there are not operators, only methods. So:
pow2.andThen[Double]
Is calling the andThen on method on the Function1 class.
As you can see on the scaldoc, that method receives another function. Also, it is parametric in the return type of the second function, which determines the return type of the composed function that is returned.
So the [Double] part is just specifying that type.
pow2.andThen[Double] _
Is using the underscore syntax to create another function.
The above line is equivalent to:
f => pow2.andThen[Double](f)
So, it is creating a function that takes another function as input, and returns another function. The resulting function will call pow2 first and then call the function passed as the argument.
Thus, it is of type Function1[Function1[Double, Double], Function[Double, Double]].
Then
(pow2.andThen[Double] _ )(mul3)
Is passing mul3 as the argument of that function, returning a final function (Function1[Double, Doule]) that calls pow2 first and pass the result to mul3.
Finally
(pow2.andThen[Double] _ )(mul3)(5)
Is calling the resulting function with 5 as is input.
After substitution, the code is equivalent to:
x => mul3(pow2(x))
x => 3 * (x * x)
5 => 3 * (x * x)
3 * (5 * 5)
75.0
Side note, IMHO, that code is very cryptic and far for what I would call idiomatic in Scala.
My question is about Scala function:
var x = 1
val f = {() => x += 1}
It's clear if the function literal looks like:
val f = (x:Int)=>x+1
But what does () stand for in:
val f = {() => x += 1}
I am pretty new in Scala.
I've read out the function chapter in a Scala book already, but still cannot understand what () means here.
tl;dr It's just an empty argument list of a function.
It's an empty argument list. It means you're not passing any arguments to the function. So normally that kind of function would not consume any value, but would supply value when it's called.
Your case is special. Variable x comes from the outer scope and is bound to your function so it becomes closure. Every time you invoke f it will change the value of x.
The () in the val f = {() => x += 1} represents the function takes no argument and increase value of x by 1
it is similar to
var x = 1
def foo(): Unit = {
x += 1
}
val f: () => Unit = () => x += 1
This is not a pure function
f is of type () => Unit. A function that takes no arguments and returs nothing (Unit)
val f: () => Unit = {() => x += 1}
The java equivalent of this would be the Supplier interface.
Hi I'm newbie in scala.
when I write the below code, Even I didn't declared variable y, but it is allowed.
object exercise {
def fixedPoint(f: Double => Double)(firstGuess: Double) = {
//some code
}
def sqrt(x: Double) = fixedPoint(y => x / y)(1) //No error. weird...
}
I don't understand how does it works?
I didn't declared variable y
Actually, you did.
This ...
y => ...
... translates into, "Here's a function that takes a single argument. I'm going to call that argument y."
When you declare f: Double => Double, it means that function f will take Double as input parameter and will return Double as output. So, when you pass y => x / y function, y here is of type Double and x/y(output) is of type double.
It is not giving any compiler error because compiler can infer the type based on type of function fixedPoint expects.
Suggest you have a look for How to use function literals (anonymous functions) in Scala.
In the post, it use a simple example (i: Int) => i % 2 == 0 to act as a function literals, and pass it to the function filter. And see follows:
Because the Scala compiler can infer from the expression that i is an Int, the Int declaration can be dropped off: val evens = x.filter(i => i % 2 == 0)
Then, this is exactly the situation in your post for y => x / y, the Double was dropped off in your code as scala compiler can infer from the expression.
Before I answer this question let me modify your code as:
object exercise {
def fixedPoint(f: Double => Double)(firstGuess: Double) = {
f(firstGuess) //call the function in f with the curried parameter
}
def sqrt(x: Double) = fixedPoint(y => x / y)(1) //No error. weird...
}
I have added a line to call function f (which takes Double and returns Double) with firstGuess parameter.
f(firstGuess) //call the function in f with the curried parameter
Let's see what what sqrt function is all about
def sqrt(x: Double) = fixedPoint(y => x / y)(1)
It takes a x and invokes fixedPoint with y => x/y and 1
now your y is firstGuess parameter (as per modified code) and x is the sqrt parameter.
Suppose I have a function that looks like this:
def foo(x: Int*)(y: Int*): Int = ???
How can I pass Arrays of x and y to foo?
val x = Array(4,6,3,7)
val y = Array(3,4,6,3)
foo(x, y) // Error:Type mismatch
Use :_* to tell the compiler to unpack the sequence to match the expected varargs input. Also, since foo is declared using two parameter lists, calling the function has to match:
foo(x: _*)(y: _*)
Take this code:
var x = 10
val y = () => x + 1
I then want to treat y as if its a variable that holds an Int and changes anytime x changes. Essentially I want to bind y to x.
Problem is, if I just type y then I get the result res0: () => Int = <function0>
I was under the impression that you could invoke 0-arity functions without any parens, but I am required to use y() to get the behavior I am trying to achieve.
Is there a better way to define the anonymous function or do I need to use a different approach?
Why do you need to do it like that? Just do def y = x + 1
scala> var x = 1
x: Int = 1
scala> def y = x + 1
y: Int
scala> y
res0: Int = 2
scala> x = 3
x: Int = 3
scala> y
res1: Int = 4
EDIT to address some comments:
If you define val y = () => x + 1, you are defining y as a value that holds a function that takes no argument and returns an Int. To call the function that is held by this variable, you will need to call it with (), to tell the compiler that you don't want to pass the value, but to execute (evaluate) the function that is within it.
If you define val y = x + 1, you are defining a value (constant), that is assigned in the moment it is executed, you could postpone evaluation using lazy, but once it is assigned, it will not be evaluated again.
If you define def y = x + 1, you are defining a function that returns x+1, which is what you want.
You have not defined a 0-arity function. You have actually defined a Unit => Int function. That is why you can not invoke it like you would like to invoke it. I've rarely seen 0-arity functions outside the context of come contained function scope:
def something[V](value: Int)(f: => V) =
if(value %2 == 0) f
else throw new Exception("not even (and also not evaluated f)")
where it is used as a lazily deferred execution body.
Edit: I would use the other person's answer.