There are many ways functions can be defined in Scala, which leads to confusion about when exactly function parameter types are required. I usually start with the simplest possible definition and work my way down until compiler errors go away. I'd rather actually understand how this works.
For example:
_ + _
(x, y) => x + y
(x: Int, y: Int) => x + y
def sum(x: Int, y: Int) = x + y // as pointed out, this is a method,
// which not a function
Bonus points for a link to the documentation.
Parameters are essential to functions, because otherwise you can't give the function-machine an input.
Parameter RulesJavaScript function definitions do not specify data types for parameters. JavaScript functions do not perform type checking on the passed arguments.
The parameters are the variables in a function, whereas the arguments are the values passed to the parameters when calling the function. The parameters can be mandatory or optional.
Non-value types capture properties of identifiers that are not values. For example, a type constructor does not directly specify a type of values. However, when a type constructor is applied to the correct type arguments, it yields a first-order type, which may be a value type.
Well there are some corner cases like: a recursive method must be explicitly typed, but normally the rule of thumb is as follows: types have to come from somewhere.
Either they come from the reference part:
val function: (Int, Int) => Int = _ + _
or from the object part:
val function = (x: Int, y: Int) => x + y
does not really matter. (in Scala!)
I know you question is about functions, but here is a similar example to illustrate Scala's type inference:
// no inference
val x: HashMap[String, Int] = new HashMap[String, Int]()
val x: HashMap[String, Int] = new HashMap[String, Int]
// object inference
val x: HashMap[String, Int] = new HashMap()
val x: HashMap[String, Int] = new HashMap
val x: HashMap[String, Int] = HashMap() // factory invocation
// reference inference
val x = new HashMap[String, Int]()
val x = new HashMap[String, Int]
val x = HashMap[String, Int]() // factory invocation
// full inference
val x = HashMap("dog" -> 3)
EDIT As requested I add the higher-order function case.
def higherOrderFunction(firstClassFunction: (Int, Int) => Int) = ...
can be called like this:
higherOrderFunction(_ + _) // the type of the firstClassFunction is omitted
But, this is not a special case. The type of the reference is explicitly mentioned. The following code illustrates a similar example.
var function: (Int, Int) => Int = null
function = _ + _
This is roughly equivalent to the higher-order function case.
Your fourth example is a method, not a function (see this question). You must specify the types of arguments to a methods. The return type of a method can be inferred, unless the method is recursive, in which case it must be specified explicitly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With