I'm having trouble understand the signature of partially applied function for function literal. For example, consider the following function and method definitions that work the same way:
def meth(x: Int): Unit = ()
val func = (x: Int) => ()
Now create a partially applied function out of each of the method/function above. Notice the signatures of the resulting function:
val f = meth _ // Int => Unit
val g = func _ // () => Int => Unit
I don't understand why the signature of func _ includes a () => part, which makes g must be called like g()(1) rather than g(1).
For example, consider the following function and method definitions that work the same way:
Methods and functions are not the same in Scala. They're in fact very different. Methods are not first-class objects, whereas functions are. That is, you'll never have a variable whose type is a method type.
As a consequence of this, let's look at the types without the underscores.
val f = meth
val g = func
Since meth is a method, it's going to be called. So the first line will try to call meth() with no arguments, an error. func, however, is an ordinary value, so there's no trouble. We'll just have another alias to func called g.
val f = meth _
val g = func _
In order to allow us to treat methods as objects, Scala introduces the _ syntax. When used with a method, it converts that method into a function object. So meth _ is a special method syntax which turns it into a function. On the other hand, func _ is taking a value (remember, functions are objects, just like strings or anything else) and lifting it to be a function object. The "easiest" way to do that is to add an empty argument list, so that's exactly what Scala does.
tl;dr Putting _ after a name turns the thing into a function object. If the thing is a method, it doesn't apply it. If the thing is a value (including but not limited to a function), it produces a new function object.
Related
Getting to know scala better, I came across a behaviour I cannot explain.
The below code works fine:
def triple(x: Double) = 3 * x
Array(3.14,1.42,3.9).map(triple)
However, If I call the scala ceil function in math library then I will need to pass an _ for it to work
def valueAtOneQuarter(f: (Double)=> Double) = f(0.25)
valueAtOneQuarter(sqrt _)
What is special about the _ in this context from the function call in the earlier piece of code.
The underscore is actually expanded to a function.
So sqrt _ gets turned into the function a => sqrt(a).
You will notice that this expanded function matches the parameter type f of the valueatonequarter method.
In more general terms, the underscore is sometimes needed to flag to the compiler to turn the method (a method is declared using def) into a function (methods and functions are similar but not the same thing). The compiler will attempt to automatically convert the method to a function for you but in some cases it needs additional pointers (like an explicit type declaration or _). See here for a full explanation of eta expansion and partial functions: https://medium.com/#sinisalouc/on-method-invocations-or-what-exactly-is-eta-expansion-1019b37e010c
A method and a function are not the same in Scala.
You define a method this way:
def method(x:Double):Double = ...
But you define a function using this way:
val func = (x: Double):Double => {...}
when you pass a function as a parameter to a method it must be a function, but not a method.
So you must use underscore to make a function from a method.
Sometimes Scala uses “Eta Expansion” capability to automatically convert the method into a function. But in some cases you must do it manually
Answering since the existing answers don't really explain when _ is needed, just "sometimes" or "in some cases".
A very important concept to understand in Scala is expected type. In your first example the expected type for argument of map is Double => B with some unknown B; in the second it's Double => Double. When the expected type is a function type and a method name is passed, it'll be automatically converted to a function. So, as comments say, the second example works without _. It's only necessary where there is no expected type, say
val f = sqrt _
There can also be issues when the method is overloaded, but there just adding _ generally won't work either; instead, you'll specify the argument type to show which method is used, e.g. max(_: Int, _: Int) or max(_: Double, _: Double).
Thanks seems _ has different meaning in different context in scala
Yes, quite a few: What are all the uses of an underscore in Scala?
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.
Looking at Programming in Scala (control abstraction) I saw these two examples that have the same effect:
1. Higher-Order Function
def withPrintWriter(file: File, op: PrintWriter => Unit) {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}
2. Currying function
def withPrintWriter(file: File)(op: PrintWriter => Unit) {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}
What is the difference between them? Can we always achieve the same result in both ways?
The concepts of higher-order functions and curried functions are generally used in an orthogonal way. A higher-order function is simply a function that takes a function as an argument or returns a function as a result, and it may or may not be curried. In general usage, someone referring to a higher-order function is usually talking about a function that takes another function as an argument.
A curried function, on the other hand, is one that returns a function as its result. A fully curried function is a one-argument function that either returns an ordinary result or returns a fully curried function. Note that a curried function is necessarily a higher-order function, since it returns a function as its result.
Thus, your second example is an example of a curried function that returns a higher-order function. Here's another example of curried function that does not take a function as an argument, expressed in various (nearly equivalent) ways:
def plus(a: Int)(b:Int) = a + b
def plus(a: Int) = (b: Int) => a + b
val plus = (a: Int) => (b: Int) => a + b
Higher order functions are functions that either take functions as parameter or return functions or both.
def f(g: Int => Int) = g(_: Int) + 23
scala> f(_ + 45)
res1: Int => Int = <function1>
scala> res1(4)
res2: Int = 72
This is a higher order function, it takes a function as parameter and returns another function. As you can see, higher order functions are a pre-requisite for currying. The curry function looks like this:
def curry[A,B,C](f: (A,B) => C) = (a: A) => (b: B) => f(a,b)
scala> curry((a: Int, b: Int) => a+b)
res3: Int => (Int => Int) = <function1>
scala> res3(3)
res4: Int => Int = <function1>
scala> res4(3)
res5: Int = 6
So to answer your question: They are two different concepts, where the one (higher order functions) is the pre-requisit for the other (currying).
Semantically, there is one difference I can think of between a curried and a not curried function. With the non-curried version, when you call withPrintWriter, that's a single method call. With the curried version, it's actually going to be two method calls. Think of it like this:
withPrintWriter.apply(file).apply(op)
Other than that, I think a lot of people use currying in this kind of situation for style. Using currying here makes this look more like a language feature then just a custom function call because you can use it like this:
withPrintWriter(file){ op =>
...
}
Using it in that way is trying to emulate some sore of control structure from the language itself, but again, this is only really a style thing and it does come with the overhead of an additional method call.
You can use the non-curried version in almost the same way, but it's not as clean looking:
withPrintWriter(file, { op =>
...
})
EDIT
#drexin makes a good point in his answer that it's worth mentioning here for me. When you think of the signature of the curried version of the method, it's really:
Function1[File, Function1[PrintWriter, Unit]]
They are mostly the same, but there is a difference with regard to type inference. Scala is not able to infer types between arguments of a single method invocation, but it is able to infer types for multiple argument lists.
Consider:
def foo1[T](x : T, y : T => T) = y(x)
def foo2[T](x : T)(y : T => T) = y(x)
foo1(1, t => t + 1) //does not compile with 'missing parameter type'
foo2(1)(t => t + 1) //compiles
You can see some additional information in this answer : Multiple parameter closure argument type not inferred
Strictly speaking, the example you gave is not really curried, it just has multiple argument lists. It just happens that multiple argument list Scala functions look a lot like curried functions in many situations. However, when you call a multiple argument list function but don't fill in one or more argument lists, it's really an example of partial application, not currying. Calling a multiple argument list with all its arguments is just one function call, not one per argument list.
There are two use cases where multiple argument list functions are helpful. The first is the case of implicit parameters, since all implicit parameters have to be in their own argument list separate from any explicit parameters. The second use case is functions that accept other functions as parameters, since if a parameter that is a function is in its own argument list, you can leave off the parentheses and just use braces, making the function call look like some sort of control structure.
Other than that, the difference is purely cosmetic.
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.
def func(arg: String => Int): Unit = {
// body of function
}
I mean this fragment:
String => Int
Short answer
Its a function that receives a String and returns a Int
Long answer
In Scala, functions are first class citizens. That means you can store them in variables or (like in this case) pass them around as arguments.
This is how a function literal looks like
() => Unit
This is a function that receives no arguments and returns Unit (java's equivalent to void).
This would be a function that receives a String as a parameter and returns an Int:
(String) => Int
Also, scala let's you drop the parenthesis as a form of syntactic sugar, like in your example. The preceding arg: is just the name of the argument.
Inside func you would call the function received (arg) like this:
val result = arg("Some String") // this returns a Int
As mentioned in Advantages of Scala’s Type System, it is a Functional type.
The article Scala for Java Refugees Part 6: Getting Over Java describes this syntax in its section "Higher-Order Functions".
def itrate(array:Array[String], fun:(String)=>Unit) = {
for (i <- 0 to (array.length - 1)) { // anti-idiom array iteration
fun(array(i))
}
}
val a = Array("Daniel", "Chris", "Joseph", "Renee")
iterate(a, (s:String) => println(s))
See? The syntax is so natural you almost miss it.
Starting at the top, we look at the type of the fun parameter and we see the (type1, …)=>returnType syntax which indicates a functional type.
In this case, fun will be a functional which takes a single parameter of type String and returns Unit (effectively void, so anything at all).
Two lines down in the function, we see the syntax for actually invoking the functional. fun is treated just as if it were a method available within the scope, the call syntax is identical.
Veterans of the C/C++ dark-ages will recognize this syntax as being reminiscent of how function pointers were handled back-in-the-day.
The difference is, no memory leaks to worry about, and no over-verbosity introduced by too many star symbols.
In your case: def func(arg: String => Int): Unit, arg would be a function taking a String and returning an Int.
You might also see it written (perhaps by a decompiler) as
def func(arg: Function1[String, Int]): Unit = {
// body of function
}
They are precisely equivalent.