How to invoke no-arg anonymous function with no parentheses - scala

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.

Related

Function currying in scala

I’m learning scala and read this concept called ‘currying’. I know it is used to divide the parameters in a function and pass them one by one. So from what I understood I tried creating a simple basic currying function below:
def add_num(a:Int,b:Int)(c:Int):Int={a+b+c}
add_num(10,20)
add_num(10)
But it gives me an error when I call the function with values 10 and 20. What i understood is it will remember the values and then I can pass the third value as 10 separately. I’m unable to understand this concept. Can someone help me in understanding this concept in most basic terms.
Error is missing argument list for method add_num. Unsupplied methods are only converted to functions when a function type is executed.
A curried function is applied to multiple argument lists, instead of just
one. An example of a non-curried function, which adds two Int parameters, x and y:
scala> def plainOldSum(x: Int, y: Int) = x + y
plainOldSum: (x: Int, y: Int)Int
scala> plainOldSum(1, 2)
res4: Int = 3
A similar function that’s curried:
scala> def curriedSum(x: Int)(y: Int) = x + y
curriedSum: (x: Int)(y: Int)Int
scala> curriedSum(1)(2)
res5: Int = 3
What's happening here is that when you invoke curriedSum, you actually
get two traditional function invocations back-to-back. The first function
invocation takes a single Int parameter named x, and returns a function
value for the second function. This second function takes the Int parameter
y.
Here's a function named first that does in spirit what the first traditional
function invocation of curriedSum would do:
scala> def first(x: Int) = (y: Int) => x + y
first: (x: Int)Int => Int
Applying the first function to 1—in other words, invoking the first function
and passing in 1—yields the second function:
scala> val second = first(1)
second: Int => Int = <function1>
Applying the second function to 2 yields the result:
scala> second(2)
res6: Int = 3
These first and second functions are just an illustration of the currying
process. They are not directly connected to the curriedSum function. Nevertheless,
there is a way to get an actual reference to curriedSum's "second"
function. You can use the placeholder notation to use curriedSum in a partially
applied function expression, like this:
scala> val onePlus = curriedSum(1)_
onePlus: Int => Int = <function1>
The underscore in curriedSum(1)_ is a placeholder for the second parameter
list.2 The result is a reference to a function which, when invoked, adds one
to its sole Int argument and returns the result:
scala> onePlus(2)
res7: Int = 3
And here's how you'd get a function that adds two to its sole Int argument:
scala> val twoPlus = curriedSum(2)_
twoPlus: Int => Int = <function1>
scala> twoPlus(2)
res8: Int = 4

In scala not declared value has no error. How does it works?

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.

What is the "real" difference between val b and var b?

What is the "real" difference between the following ?
val b = ( x:Double) => x * 3
var b = ( x:Double) => x * 3
Technically speaking, once a value is assigned to val , it should not be changed. However, as part of the first statement, the value of b could be changed to different values by passing different values of x.
scala> val b = ( x:Double) => x * 3
b: Double => Double = $$Lambda$1109/411756754#7a522157
scala> b(3)
res1: Double = 9.0
scala> b(4)
res2: Double = 12.0
What is actually happening here? Is it not that value of b is changing here?
b is a function that takes a Double and returns a one.
The function itself can't be changed, not the value it returns (functions are first class values).
If you try to do:
b = (x : Double) => x * 6
you'll get:
error: reassignment to val
But it's possible to change the var one:
scala> b = (x : Double) => x * 7
b: Double => Double = $$Lambda$1308/1272194712#9e46050
But note that when you change the var one, you should keep its type: A function that takes a Double and returns a Double, the same if you were to change any other type like Integer or Boolean.
In the example posted by you b is a function. You are passing different values to the function subsequently. Value of b is not changed by that.
Syntax is as follows:

Function parameters evaluation in Scala (functional programming)

please find below a piece of code from Coursera online course (lecture 2.3) on functional programming in Scala.
package week2
import math.abs
object lecture2_3_next {
def fixedPoint(f: Double => Double)(firstGuess: Double): Double = {
val tolerance = 0.0001
def isCloseEnough(x: Double, y: Double): Boolean = abs((x - y) / x) / x < tolerance
def iterate(guess: Double): Double = {
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
}
def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => x / y))(1)
sqrt(2)
}
A few points blocked me while I'm trying to understand this piece of code.
I'd like your help to understanding this code.
The 2 points that annoying me are :
- when you call averageDamp, there are 2 parameters 'x' and 'y' in the function passed (eg. averageDamp(y => x / y)) but you never specify the 'y' parameter in the definition of the averageDamp function (eg. def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2). Where and how do the scala compiler evaluate the 'y' parameter.
- second point may be related to the first, I don't know in fact. When I call the averageDamp function, I pass only the function 'f' parameter (eg. y => x / y) but I don't pass the second parameter of the function which is 'x' (eg. (x: Double) second parameter). How the scala compiler is evaluating the 'x' parameter in this case to render the result of the averageDamp call.
I think I missed something about the evaluation or substitution model of scala and functional programming.
Thank's for your help and happy new year !
Hervé
1) You don't pass an x and an y parameter as f, you pass a function. The function is defined as y => x / y, where y is just a placeholder for the argument of this function, while x is a fixed value in this context, as it is given as argument for the sqrt method (in the example x is 2). Instead of the fancy lambda-syntax, you could write as well
def sqrt(x: Double): Double = fixedPoint(averageDamp(
new Function1[Double,Double] {
def apply(y:Double):Double = x / y
}
))(1)
Nothing magic about this, just an abbreviation.
2) When you have a second parameter list, and don't use it when calling the method, you do something called "currying", and you get back a partial function. Consider
def add(x:Int)(y:Int) = x + y
If you call it as add(2)(3), everything is "normal", and you get back 5. But if you call add(2), the second argument is still "missing", and you get back a function expecting this missing second argument, so you have something like y => 2 + y
The x is not a parameter of the (anonymous) function, it is a parameter of the function sqrt. For the anonymous function it is a bound closure.
To make it more obvious, let's rewrite it and use a named instead of an anonymous function:
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => x / y))(1)
will can be rewritten as this:
def sqrt(x: Double): Double = {
def funcForSqrt(y: Double) : Double = x / y // Note that x is not a parameter of funcForSqrt
// Use the function fundForSqrt as a parameter of averageDamp
fixedPoint(averageDamp(funcForSqrt))(1)
}

Unit as parameter

What is the following methods' difference?
def sum1() = 1+2
def sum2(a:Unit) = 1+2
I think they are semantically identical, is it right?
With sum1, you can call it with or without parentheses:
val x = sum1 // x: Int = 3
val y = sum1() // y: Int = 3
But with sum2 you are forced to provide parentheses.. I think that if you call sum2(), you are actually calling sum2 with () as the argument a.
val x2 = sum2 // error
val y2 = sum2() // y2: Int = 3
Note that passing unit as an argument to an expression lets you simulate lazy evaluation in a strict language. By "moving evaluation under a lambda" you ensure that the expression isn't eval'd until the () gets passed in. This can be useful for e.g. auto-memoizing data structures, which collapse from a function to a value the first time they're inspected.
These methods are not identical. Once receives a parameter, the other does not. See here:
scala> sum1(println("Hi, there!"))
<console>:9: error: too many arguments for method sum1: ()Int
sum1(println("Hi, there!"))
^
scala> sum2(println("Hi, there!"))
Hi, there!
res1: Int = 3