I've seen a few examples of how to write :: equvalant in Scala, for eg passing System.out::println to a function, but I'm unable to figure out how to write this Vaadin Grid component in Scala:
Grid<Person> grid = new Grid<>(Person.class, false);
grid.addColumn(Person::getFirstName).setHeader("First name");
grid.addColumn(Person::getLastName).setHeader("Last name");
Here the get methods are regular getters, and not a static methods.
Any idea how can this code be written in Scala 2(.12)?
Edit:
The java code above (grid.addColumn(..)) calls this specific method:
public Column<T> addColumn(ValueProvider<T, ?> valueProvider) {
BiFunction<Renderer<T>, String, Column<T>> defaultFactory = getDefaultColumnFactory();
return addColumn(valueProvider, defaultFactory);
}
ref: https://github.com/vaadin/flow-components/blob/2f6bce42b67651fd47d202fa83d8359c619fe099/vaadin-grid-flow-parent/vaadin-grid-flow/src/main/java/com/vaadin/flow/component/grid/Grid.java#L1625
It depends on the shape of the method and, in some cases, the version of Scala you're using. Scala 3 made some pretty significant changes to the way methods work, so some of the syntax works differently.
Let's assume we've got these signatures.
def foo(n: Int): Int
def bar(a: Int, b: String): Int
def baz(): Int
def frobnicate: Int
First, if you're in Scala 3 and the method takes mandatory arguments, then you can simply use a . and get the method as a first-class object. So for each of the following methods, you can use this trick.
In that case, myInstance.foo is a function of one argument and myInstance.bar is a function of two. You cannot use this trick with a function of zero arguments, even in Scala 3.
On the other hand, if the method has no arguments, or if you're working in Scala 2 (which came out before this syntax was finalized), then you can convert a method to an object by placing an underscore (not in parentheses) after it. For example, foo _ is a function of one argument in both Scala 2 and 3. bar _ is a function of two arguments, and baz _ is a function of zero arguments. frobnicate _ is a syntax that used to work in Scala 2, but it won't work anymore for functions of zero arguments declared without parentheses in Scala 3. In Scala 3 for such functions, you'll have to wrap them in an explicit lambda.
You can also (for functions that take one or more arguments) explicitly place underscores in the argument positions. Sometimes this is more readable, and it's required if there are multiple overloads of different arities. So, in both Scala 2 and 3, foo(_) is a function of one argument, while bar(_, _) is a function of two, and we could even partially apply bar as bar(0, _) or bar(_, "")
In summary, assuming the signatures listed at the top of this answer:
Code
Scala 2 behavior
Scala 3 behavior
obj.foo
Error
(Int) -> Int
obj.bar
Error
(Int, String) -> Int
obj.baz
Calls baz()
Error
obj.frobnicate
Calls frobnicate
Calls frobnicate
obj.foo _
(Int) -> Int
(Int) -> Int
obj.bar _
(Int, String) -> Int
(Int, String) -> Int
obj.baz _
() -> Int
() -> Int
obj.frobnicate _
() -> Int
Error
obj.foo(_)
(Int) -> Int
(Int) -> Int
obj.bar(_, _)
(Int, String) -> Int
(Int, String) -> Int
() => obj.baz()
() -> Int
() -> Int
() => obj.frobnicate
() -> Int
() -> Int
So if you want to be maximally backwards compatible, then the safest thing to do is to put an _ after the function name, as in obj.foo _. This will work in every case except Scala 3 functions of zero arguments which are declared with no parentheses (i.e. frobnicate in our example). For those, you'll need an explicit lambda, as () => obj.frobnicate
Related
I don't know why pattern d is bad in this list below.
Why need expicit type declaration?
def adder1(m:Int,n:Int) = m + n
val a = adder1(2,_) //OK
val b = adder1(_,2) //OK
def adder2(m:Int)(n:Int) = m + n
val c = adder2(2)(_) //OK
val d = adder2(_)(2) //NG:missing parameter type
val e = adder2(_:Int)(2) //OK
I just want to know the reason pattern d needs parameter type.
Very welcome just showing citation language spec.
So I believe this comes from the concept of Partial Application.
Intuitively, partial function application says "if you fix the first arguments of the function, you get a function of the remaining arguments"
...
Scala implements optional partial application with placeholder, e.g. def add(x: Int, y: Int) = {x+y}; add(1, _: Int) returns an incrementing function. Scala also support multiple parameter lists as currying, e.g. def add(x: Int)(y: Int) = {x+y}; add(1) _.
Lets take a look at adder2
From the REPL:
scala> def adder2(m:Int)(n:Int) = m + n
def adder2(m: Int)(n: Int): Int
Lets get a value to represent this:
scala> val adder2Value = adder2
^
error: missing argument list for method adder2
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `adder2 _` or `adder2(_)(_)` instead of `adder2`.
Ok, let's try:
val adder2Value = adder2 _
val adder2Value: Int => (Int => Int) = $Lambda$1382/0x0000000840703840#4b66a923
Ahha!
In English: "A function that takes an Int and returns a function that takes an Int and returns an Int"
How can we bind the second argument using this signature? How can we access the inner function unless we first have gone through the outer one?
As far as I know, this is not possible to do using this signature, unless you explicitly define the type of your first argument.
(But what about adder2(_)(_)?)
scala> adder2(_)(_)
^
error: missing parameter type for expanded function ((<x$1: error>, x$2) => adder2(x$1)(x$2))
^
error: missing parameter type for expanded function ((<x$1: error>, <x$2: error>) => adder2(x$1)(x$2))
(Maybe this hints at our solution?)
Notice what happens if we explicitly define both arguments:
val adder2Value2= adder2Value (_:Int) (_:Int)
val adder2Value2: (Int, Int) => Int = $Lambda$1394/0x000000084070d840#32f7d983
This is much more manageable, we can now fix either argument, and get a simplified partial function:
scala> val adder2FirstArg = adder2Value (_:Int) (10)
val adder2FirstArg: Int => Int = $Lambda$1395/0x000000084070d040#47f5ddf4
scala> val adder2SecondArg = adder2Value (5) (_:Int)
val adder2SecondArg: Int => Int = $Lambda$1396/0x000000084070c840#21ed7ce
So what's really going on here?
When you bind an argument to a value, you have explicitly expressed the type (maybe it's inferred, but it's definitely that type, in this case, Ints). It's sugar so we don't need to write it. But under the hood, these are composed functions, and how they are composed is very important. To be able to match and simplify the function signature, the compiler requires us to provide this information in an outside-in manner. Otherwise, we need to give it some help to get there.
EDIT:
I think that this question serves as more of a Scala language spec. puzzle exercise, however. I can't think of any good reason, from a design perspective, for which you would need to implement a curried function in such a way that you cannot order the parameters such that the last parameters are the ones being inferred.
Having a function f defined as:
def f(i1: Int, i2: Int)(i3: Int) = i1 + i2 + i3
It is possible to define a partially applied function as follows using _:
val f12 = f(1, 2) _ // f12: Int => Int = <function>
f12(3) // res0: Int = 6
Now when I return a partially applied function from a function, I do not need to use _:
def f23(f: (Int, Int) => Int => Int) = f(2, 3) // f23: (f: (Int, Int) => Int => Int)Int => Int
val f23f = f23(f) // f23f: Int => Int = <function>
f23f(4) // res1: Int = 9
If I place _ at the f23 definition I will get an Error:
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
Error:(6, 49) _ must follow method; cannot follow Int => Int
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
What is the reason for this inconsistency?
f is a method, not a function. You can read about some of the differences here.
f12 is a function derived from f via eta-expansion. It is not a partial function. A PartialFunction is a function defined over a limited domain of input values. If, say, f12 was defined only for Int values less than 500, for example, and undefined for input values greater than 500, then it would be a partial function.
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
This fails because f, as defined here, is a function that takes 2 Int values and returns a function that takes an Int and returns an Int. In this situation what is the underscore supposed to be standing in for? f(2,3) is a complete invocation that returns an Int=>Int function. It's a bit like writing 5 + 7 _. It's not clear what the _ is substituting for.
You can, on the other hand, do this: ... = f(2,3)(_). Then it's clear that the returned function is being invoked with a missing, i.e. _, parameter. Which is the same thing as: ... = f(2,3).
This is by design in Scala to prevent developer confusion.
If you tell the compiler the type of f12 explicitly it will work as you expect:
`val f12:Int=>Int = f(1, 2)`
This is explained by the language originator (Martin Odersky):
Why the trailing underscore?
Scala's syntax for partially applied functions highlights a difference in the design trade-offs of Scala and classical functional languages such as Haskell or ML. In these languages, partially applied functions are considered the normal case. Furthermore, these languages have a fairly strict static type system that will usually highlight every error with partial applications that you can make. Scala bears a much closer relation to imperative languages such as Java, where a method that's not applied to all its arguments is considered an error. Furthermore, the object-oriented tradition of subtyping and a universal root type accepts some programs that would be considered erroneous in classical functional languages.
For instance, say you mistook the drop(n: Int) method of List for tail(), and you therefore forgot you need to pass a number to drop. You might write, "println(drop)". Had Scala adopted the classical functional tradition that partially applied functions are OK everywhere, this code would type check. However, you might be surprised to find out that the output printed by this println statement would always be ! What would have happened is that the expression drop would have been treated as a function object. Because println takes objects of any type, this would have compiled OK, but it would have given an unexpected result.
To avoid situations like this, Scala normally requires you to specify function arguments that are left out explicitly, even if the indication is as simple as a `_'. Scala allows you to leave off even the _ only when a function type is expected.
I'm learning specs2 testing framework by following some of its examples.
I've noticed the following anonymous function syntax is recurring:
val upper = (_: String).toUpperCase
which is equivalent to more conventional / usual
val upper = (s: String) => s.toUpperCase
Although the syntax is simple and elegant, yet it's not very familiar (easy).
Can someone step me through how the first syntax works / derives? I'm pretty sure that it has to do with some sort of partial application but cannot reason fully.
Also is the syntax used frequently in Scala? (I'm still learning the ropes here :] )
Edit::
I've found the recurring pattern to use such syntax is with ad-hoc polymorphism (simply, overloaded methods / functions) where argument type of the passed function determines what function is dispatched.
For example,
def f(g: Int => String): String = g(10)
def f(g: String => String): String = g("hello")
f((_: Int).toString + " beers") // 10 beers
f((_: String) + " world") // hello world
This kind of pattern is recurring in libraries like ScalaCheck.
The syntax indicates the compiler you're creating a function with a parameter of type String, which is inserted where the _ is used, according to parameter order. If you had:
val f = (_:String).length + (_:Int)
it would create a function (String, Int) => Int, where each _ marks where the parameter is being used. The order is important! They must be used in the same order you want the function's parameters to be
If the types are already defined when declaring the val, you can omit them in the function body:
val f: (String, Int) => Int = _.length + _
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.
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.