Can wildcard anonymous functions be used when parameters are repeating in the result expression? - scala

Find Square of an integer 'x'.
Without Placeholder
var square = (x:Int) => x*x
square(3) gives desired output 9.
With Placeholder var square = (_:Int)*(_:Int)
square(3) gives Error
Not enough arguments for method apply: (v1: Int, v2: Int)Int in trait Function2.
Unspecified value parameter v2.
Internally what is happening?

No, each occurrence of _ represents the next argument in the argument list for the function.
(_:Int)*(_:Int) is a function that takes two Int arguments and multiplies them.

Related

andThen with square brackets and underscore in Scala function

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.

Getting an error while passing an expression as a fucntion parameter

scala> def sum(a:Int)={a} //I have defined the function with a single parameter
sum: (a: Int)Int
sum{val b=10+20} //passing the parameter as expression block
Getting error
scala> sum{val b=10+20}
<console>:9: error: type mismatch;
found : Unit
required: Int
sum{val b=10+20}
Why is it expecting Unit here?
The error is that {val b = 10 + 20} is of type Unit while sum is expecting an Int.
You can either call sum directly without assigning the variable:
sum(10 + 20)
> 30
Or make the block return an Int, like:
sum{
val b = 10 + 20
b // return b, which is an Int
}
> 30
You do not pass an expression but a block with one declaration. Try:
sum(10+20)
You are experiencing a weird combination of syntax error and type-system convention.
The curly braces mark a block (see e.g. the body of your sum function declaration). Function arguments can be passed in juxtaposition or using parenthesis. That is your syntax error.
The type system convention allows languages with side-effects to gently insert these effects into basically any expression. This happens by treating the composition of statements (i.e. the semicolon) as "evaluate these expression but do nothing with the result, then evaluate the next expression". The nothing as result part is combined with the unit type for statements that do not compute anything.
def sum(a:Int)={a}
What this statement does is create a method that takes one Int-typed parameter and returns it.
sum{val b=10+20}
Here you pass a value to your defined method sum. What you're passing is an expression. Scala will, effectively, 'rewrite' that expression before applying it to sum. If we write the expression being passed (val b=10+20) in the REPL we will see what it gets rewritten to:
scala> val b=10+20
b: Int = 30
But this is only part of the story, because the assignment of a value to a name returns nothing. We can see this by putting brackets around the assignment:
scala> { val b=10+20 }
Note that the REPL displays nothing when this happens.
Because the re-written expression includes this evaluation, you're actually passing a scope to the function, in which b is defined. However, that scope doesn't 'return' an Int to be bound to a. To return the result of the b assignment, you have to do one of two things. Either you have to have a call to the variable be the last call in the expression, or have the last call be the calculation itself, and don't assign that to a variable:
sum{ val b=10+20; b } // Explicitly call the bound variable
sum{ 10 + 20 } // Don't assign the variable

Spark Scala Method Signature in DataFrame API

Hi I am trying to understand scala more and I think I am a little lost with this method signature.
explode[A <: Product](input: Column*)(f: (Row) ⇒ TraversableOnce[A])(implicit arg0: scala.reflect.api.JavaUniverse.TypeTag[A]): DataFrame
First off, what is the "<:" supposed to mean in the square brakcets? Are A and B supposed to be parameter types? But Column is the argument type.
Secondly, it looks like it does a lambda function from (Row) to Traversable[A] but I haven't seen a lambda yet that doesn't have the left side argument on the right side argument at least once.
Also, I 'm not 100 percent usre why it has the implicit arg0: piece
Thanks in advance!
what is the "<:" supposed to mean in the square brackets?
<: means subtype in scala, so here it means the A is a subtype of Product. It acts like a kind of upper bound which limits the type that can be passed here to be subtype of Product
Are A and B supposed to be parameter types? But Column is the argument
type
A is not the parameter type, it is a parameter by itself, which is called type parameter. It is a little bit confusing but basically it means you can pass any type that is a subtype of product to this position and use the type parameter inside the function. This makes the function more generic because it can handle different types at the same time and you don't have to write separate functions for different types;
it looks like it does a lambda function from (Row) to Traversable[A]
f: (row) => Traversable[A] is another parameter which in this case is a function type which accepts (row) and return Traversable[A]. By this definition, explode can accept a function as a parameter, in which case is a lambda expression;
To illustrate the last case:
def sum(x: Int, y: Int)(f: Int => Int) = f(x) + f(y)
sum: (x: Int, y: Int)(f: Int => Int)Int
sum(2,3)(x => 2*x)
res2: Int = 10
In conclusion, the function explode accepts three parameters in total, the first one A is a type parameter. The second and the third are real arguments of the function, with Input being of type Column as you have noticed and f being of type (row) => Traversable[A] which is a function type.

How much code does the body of an anonymous Scala function with "_" (underscore) comprise?

In Scala, if you have an expression containing an underscore, this is an anonymous function with the expression as its body and the underscore as as its parameter, e.g. 2*_ is the anonymous function that doubles its argument. But how far does the function body extend? I'm missing a clear rule here that disambiguates cases like e.g. the following (tested with the Scala 2.11.7 REPL):
scala> (_: Int)+2-1 // function body up to 1 - OK
res7: Int => Int = <function1>
scala> ((_: Int)+2)-1 // function body up to 2, - applied to function is an error
<console>:11: error: value - is not a member of Int => Int
((_: Int)+2)-1
^
The definition is given in http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#placeholder-syntax-for-anonymous-functions, and it's... not that simple.
An expression e of syntactic category Expr binds an underscore section u, if the following two conditions hold: (1) e properly contains u, and (2) there is no other expression of syntactic category Expr which is properly contained in e and which itself properly contains u.
If an expression e binds underscore sections u_1 , \ldots , u_n, in this order, it is equivalent to the anonymous function (u'_1, ... u'_n) => e' where each u_i' results from u_i by replacing the underscore with a fresh identifier and e' results from e by replacing each underscore section u_i by u_i'.
And if you look at the grammar in the beginning of the section, (_: Int)+2 in (_: Int)+2-1 is not an Expr, but in ((_: Int)+2)-1 it is.
((_: Int)+2)-1 // function body up to 2, - applied to function is an error
error: value - is not a member of Int => Int
((_: Int)+2)-1
The error message from the compiler is sensible. Your additional parens have created a function literal that adds '2' to a wildcard/placeholder parameter. The compiler reads your code to mean that you have a this function value and you are trying to subtract '1' from it.
And this doesn't make sense. You can subract '1' from other numbers, but certainly not a function value. Thus, the compiler is telling you that it doesn't make sense to subtract one from a function value. Or, in compiler terms, a function of type Int => Int doesn't have a '-' function.
value - is not a member of Int => Int
Understanding this error message requires that you know that all operators in Scala ( -, *, +, etc ) are implemented as methods of types. If you look at the Scala API docs for Int, you'll see that it defines a long list of methods with common mathematical and logical operator symbols as function names.

interpreting function within a function in scala

I'm new to scala, and I see this piece of code:
def sum(f: Int => Int)(a: Int, b: Int): Int = ...
I know that this sum function takes a function with 2 parameters(a and b) of type Ints.
Am I correct to say that:
The sum function takes a function, because i see (f: after def sum?
I'm a bit confused with the Int => Int syntax and the last :Int before =.
What does the Int on the left of the right arrow indicate?
Does the Int type on the right of the right arrow indicate:
the return value of the sum function?
or does it indicate the return value of the anonymous function
does the last :Int = indicate the return value of sum function is of type Int??
The sum method takes 3 parameters, split between two lists, and returns an Int. The first parameter list is for a function that takes an Int and returns an Int. That makes sum a higher-order function (in the loose sense of equating methods and functions). The colon means "of type".
It's significant to note that there is a different syntax for return values of functions and methods. This is because functions are values in Scala, and therefore their arguments and return types must be captured by a single type, and the => captures this. Methods are not values, and their parameter types and return types are notated separately. You may be able to gloss over this as a beginner, but I think it's worthwhile to explore the distinction.