Scala Currying syntax explanation - scala

I am new to scala .
I want to understand the syntax of this below code
object PlainSimple {
def main(args:Array[String])
{
val m = add(5)
println(m(3))
}
def add(x:Int):Int=>Int =
{
y=>y+x
}
}
My question is where are we saying that the add function is returning another function?
What does Int=>Int mean?
Inside the add function what is called y? Why are we using it without declaring it anywhere?
What do need to do if want multiples line inside add method?

My question is Where are we saying that the add function is returning another function?
Right here
def add(x: Int): Int => Int = y => y + x
Int => Int is a function type. That's just syntactic sugar, but you can also write it as
def add(x:Int): Function1[Int, Int] = y => y + x
Now, what is y? y => y + x is a lambda, i.e. an anonymous function. This lambda takes one parameter that we're now referring to as y.
Here's a good reference on anonymous functions in scala and their syntax: http://docs.scala-lang.org/tutorials/tour/anonymous-function-syntax.html
In order to have multiple lines inside the method just use braces
def add(x:Int): Function1[Int, Int] = { y =>
println("whaveter")
y + x
}

My question is Where are we saying that the add function is returning another function?
What is Int=>Int means?
T => U as a type means "a function that takes a T and returns an U". So when we write : Int => Int at the end of the function signature, we say "this function returns a function from Int to Int".
Inside the add function what is called y ? Why are we using it without declaring it anywhere?
As an expression x => body (or (x,y,z) => body for multiple parameters) is a function literal, that is it defines an anonymous function whose parameter is named x and whose body is body. So we are declaring the parameter x by writing its name of the left side of the =>.
What do need to do if want multiples line inside add method?
You can put anything to the right of => that you could also put to the right of = when defining a method using def. So if you want your function's body to consist of multiple statements, you can use braces just like with a regular method definition:
y => {
val z = y+x
z*2
}

Related

Scala: how to access variables in a method defined in some other block of code

I have following code:
.hof((key, value) => {
Some(..some processing result on key,value)
.filterNot(_.isEmpty)
.map(x: X => {....my code processing x using key,value with output y})
}
)
I want to abstract out the function I passed to map into a method defined in class.
def myMethod(x: X) = {
y = ....some computation....
return y
}
But I need to have access to key,value in myMethod.
Is there a way to have that?
You can define myMethod in curried form:
def myMethod(key: Key, value: Value)(x: X) = {
... uses key and value ...
}
Then you can partially apply it in the map, passing it the key/value pair that you have at that point:
.map(myMethod(key, value))
Note that adding key/value pair to myMethod signature isn't some kind of "cheating"; if the method needs to use key and value, then it should have them passed as parameters.
This is the great thing about FP; once every function declares all the parameters it operates on, you can compose them easily.
Of course, you could simply place myMethod somewhere within the scope where key and value are going to be accessible (=closure), but by declaring them as parameters you are more flexible and you can place the method anywhere you want.
You can define the method locally like this:
.hof((key, value) => {
def myMethod(x: X) = {
???
}
Some(..some processing result on key,value)
.filterNot(_.isEmpty)
.map(myMethod)
}
)
Otherwise you are going to have to pass (key, value) to the function as arguments.
(See answer from #slouc for tips on how to use currying to make this cleaner)

scala: Specifying method type for currying

The following method type describes a function that passes configuration info and data to a method. Each method of this type can perform a different function.
type FTDataReductionProcess =(PipelineConfiguration,RDDLabeledPoint) => RDDLabeledPoint
The above works fin.
But what I would like to do is different. I want to add the configuration to the method first, and then later add the data. So I need currying.
I thought this would work:
type FTDataReductionProcess =(PipelineConfiguration)(RDDLabeledPoint) => RDDLabeledPoint
but this causes a compilation error
Cannot resolve symbol RDDLabeledPoint
Any suggestions would be appreciated
You want a function that takes a PipelineConfiguration and returns another function that takes an RDDLabeledPoint and returns an RDDLabeledPoint.
What is the domain? PipelineConfiguration.
What is the return type? A "function that takes RDDLP and returns RDDLP", that is: (RDDLabeledPoint => RDDLabeledPoint).
All together:
type FTDataReductionProcess =
(PipelineConfiguration => (RDDLabeledPoint => RDDLabeledPoint))
Since => is right-associative, you can also write:
type FTDataReductionProcess =
PipelineConfiguration => RDDLabeledPoint => RDDLabeledPoint
By the way: the same works for function literals too, which gives a nice concise syntax. Here is a shorter example to demonstrate the point:
scala> type Foo = Int => Int => Double // curried function type
defined type alias Foo
scala> val f: Foo = x => y => x.toDouble / y // function literal
f: Foo = $$Lambda$1065/1442768482#54089484
scala> f(5)(7) // applying curried function to two parameters
res0: Double = 0.7142857142857143

In Scala invoking no-parameter function with and without brackets is executed in different way

I have following Currying function declaration:
def logString(count: Int)(fun:() => Unit) {
for (n <- 1 to count) { fun }
}
I call this function in this way:
logString(3) { () => print("I") }
The result is nothing - just no output.
Then I just add brackets after "fun" function invocation, inside the body of Currying function declaration:
def logString(count: Int)(fun:() => Unit) {
for (n <- 1 to count) { fun() }
}
The result becomes what is expected:
III
Is this some Scala bug, or there is some rule that I missed when learning Scala?
I know that there is rule that when you declare function like this:
def myFun = 1
we can not invoke it with brackets - the compilation fails.
But having different results when invoking a function with and without brackets seems more like a bug.
Am I right or I miss something about Scala?
Look at the type of fun, it's fun: () => Unit. You can think of that as meaning that when you call it with (), you get Unit in return. Without explicitly calling it, fun refers to the function as a value, not the result of calling it. This is the essence of the concept of higher-order functions.
If it had type fun: => Unit, simply mentioning fun would cause it to be executed, in which case there would be no way to refer the function as a value.
When you have such a declaration
val x = 10
this is a value definition. The value x can be an integer like in this case,
but it can also be a function.
val y = () => println("i'm a function")
However either way, if you call it without parenthesis nothing will happen.
scala> val x = 10
x: Int = 10
scala> val y = () => println("i'm a function")
y: () => Unit = <function0>
scala> x
res0: Int = 10
scala> y
res1: () => Unit = <function0>
When you have a function definition like this:
def z() = println("i'm a function def")
Then you can omit parenthisis and call it without it.
scala> def z() = println("i'm a function def")
z: ()Unit
scala> z
i'm a function def
In your case fun is like a value definition (it's a value parameter).
What happens is that, when Scala evaluates your for expression it will just do nothing with fun.
Just the same as if you did y vs y() from the example above.
I just wanted to share the information summarized by me based on the very helpful answers answers above and some additional research. Might be would be helpful for someone else also.
Functions can be declared in two ways in Scala:
- "call-by-name" - they are represented in the byte code as normal Java functions in a straightforward way.
- "call-by-value" - from Scala's abstract point of view they are stored in variables. Actually in the Byte code they are stored in classes implementing Single Abstract Method interfaces (SAM) and passed around as method parameters or as normal variables.
When we invoke a "call-by-name" function that does not take parameters it is always executed no matter how we call it with or without brackets.
So now myFunction and myFunction() is just the same.
When we invoke a "call-by-value" function that does not take parameters we have two cases:
- when we do not have brackets after it - myFunction - we just refer to the variable pointing to the function without executing function itself.
- when we have brackets - myFunction() - we actually call (execute) the function.
Different ways to declare function:
def myFunction = 5 * 5
This is call-by-name function. Declared this way no brackets allowed when calling it. So calling myFunction() will not compile. Call it this way: myFunction
def myFunction() = 5 * 5
This is call-by-name function. Can call the function with and without brackets - the effect is the same. So myFunction and myFunction() is just the same.
def myFunction = () => 5 * 5
This is call-by-value function (even when declared as def not val) . When calling it with brackets - myFunction() - function is executed, when calling it without brackets - myFunction - function is NOT executed - just val holding it is being mentioned.
Similarly if we declare function as other function's parameter:
def enclosingFunc(myFunction: => Void)
This is call-by-name function. Inside enclosing function it will be executed only if called without brackets - myFunction. With brackets - myFunction() - will not compile.
In this case enclosingFunc could be called this way:
enclosingFunc(n = 1; n +=1)
def enclosingFunc(myFunction: () => Int)
This is call-by-value function. It matters how we invoke it in the body of enclosing function. If invoke it without brackets - myFunction - it will NOT be executed, but we just refer to the object holing it. If invoke it with brackets - myFunction() - it will be called and executed.
In this case enclosingFunc could be called only in this way:
enclosingFunc( () => n = 1; n +=1)
In the first example the function fun doesn't isn't invoked, it juts sort of sits there. Adding the parenthesis cause the passed-in function to be evaluated.

How to access to the parameter of the higher order function in scala

I am really new to Scala and trying to study it.
I don't know how to access or using the parameter of higher order function. For example:
def higherOrderFunc(f: Int => Boolean): String = {
/* Logic to print parameter is here */
"Hello"
}
val func = higherOrderFunc(x => x > 1)
How can I print the value of x before I return value "Hello"
You can't. The argument does not exist in this context; it'd need to be passed into the higher-order function along with the anonymous function.

scala loan pattern, optional function param

I have a loan pattern that applies a function n times where 'i' is the incrementing variable. "Occasionally", I want the function passed in to have access to 'i'....but I don't want to require all functions passed in to require defining a param to accept 'i'. Example below...
def withLoaner = (n:Int) => (op:(Int) => String) => {
val result = for(i <- 1 to n) yield op(i)
result.mkString("\n")
}
def bob = (x:Int) => "bob" // don't need access to i. is there a way use () => "bob" instead?
def nums = (x:Int) => x.toString // needs access to i, define i as an input param
println(withLoaner(3)(bob))
println(withLoaner(3)(nums))
def withLoaner(n: Int) = new {
def apply(op: Int => String) : String = (1 to n).map(op).mkString("\n")
def apply(op: () => String) : String = apply{i: Int => op()}
}
(not sure how it is related to the loan pattern)
Edit Little explanation as requested in comment.
Not sure what you know and don't know of scala and what you don't undestand in that code. so sorry if what I just belabor the obvious.
First, a scala program consist of traits/classes (also singleton object) and methods. Everything that is done is done by methods (leaving constructor aside). Functions (as opposed to methods) are instances of (subtypes of) the various FunctionN traits (N the number of arguments). Each of them has as apply method that is the actual implemention.
If you write
val inc = {i: Int => i + 1}
it is desugared to
val inc = new Function1[Int, Int] {def apply(i: Int) = i + 1}
(defines an anonymous class extending Function1, with given apply method and creating an instance)
So writing a function has rather more weight than a simple method. Also you cannot have overloading (several methods with the same name, differing by the signature, just what I did above), nor use named arguments, or default value for arguments.
On the other hand, functions are first classes values (they can be passed as arguments, returned as result) while methods are not. They are automatically converted to functions when needed, however there may be some edges cases when doing that. If a method is intended solely to be used as a function value, rather than called as a method, it might be better to write a function.
A function f, with its apply method, is called with f(x) rather than f.apply(x) (which works too), because scala desugars function call notation on a value (value followed by parentheses and 0 or more args) to a call to method apply. f(x) is syntactic sugar for f.apply(x). This works whatever the type of f, it does not need to be one of the FunctionN.
What is done in withLoaner is returning an object (of an anonymous type, but one could have defined a class separately and returned an instance of it). The object has two apply methods, one accepting an Int => String, the other one an () => String. When you do withLoaner(n)(f) it means withLoaner(n).apply(f). The appropriate apply method is selected, if f has the proper type for one of them, otherwise, compile error.
Just in case you wonder withLoaner(n) does not mean withLoaner.apply(n) (or it would never stop, that could just as well mean withLoaner.apply.apply(n)), as withLoaner is a method, not a value.