I'm trying to pass a default args in a function like we can do in method ..But im getting an error. Is it possible to pass a default args / named args to a function like method?
Is it possible to pass named arguments in function while calling it ?
This only works for methods (which are defined with def).
def func(i: Int = 2) = i
However, here is somewhat of a "hack" to do it regardless.
You can use a curried function here
def sum1(a:Int=2)(b:Int) = a+b
sum1(33)
Hope this answers your question.
var f(i:Int=2,j:Int) => i + j
This does not work. If you want to define a lambda, try this
val f = (i:Int,j:Int) => i + j
This is the correct approach. Also you cannot assign default values in lambda. You need to define methods with def keyword. Try this:
def f(i:Int, j:Int=2) = i + j
Parameter with default value should be the last parameter because scala compiler will scan values from left-right. It'll only use default values if there are missing ones. In above code f(1) will produce 3 because j will use 2 as default value. So use the compulsory arguments in the left side and the ones with default values on right. Hope this helps
Explained here: In Scala, can you make an anonymous function have a default argument?
Named arguments work with function definitions. Parameters with defaults don't need to be given:
class my
{
def f(i:Int = 2, j: Int) = i + j
}
var my = new my()
my.f(j = 1) // i = 2, j = 1
my.f(i = 3, j = 1) // i = 3, j = 1
my.f(3, 1) // i = 3, j = 1
Related
I think this question is somewhat related to Kotlin function declaration: equals sign before curly braces
In Scala, every statement is an expression (possibly with Unit type). If we surround multiple expressions with braces, then the final expression is the actual value of the curly braced part. Therefore,
// Scala
val a = {
val b = 1
val c = b + b
c + c
}
println(a)
The type of a is Int and the code prints the value 4.
However, in Kotlin, this is somewhat different.
If we do the same thing in the Kotlin,
// Kotlin
val a = {
val b = 1
val c = b + b
c + c
}
println(a)
The type of a is () -> Int and the code prints the Function0<java.lang.Integer>, which means a 0-ary function object with result type Int.
So if we want to print the value 4, we need to do println(a()).
In fact, the expression {} in Kotlin is a function () -> ().
I cannot find an explanation about this in Kotlin official reference pages. Without a parameter list or ->, curly braces make a function?
When I use Scala, I write many codes like the first code. However, in Kotlin, it creates a function object and we have to call the function, which may be an overhead in a loop or recursion.
Is there any document about this thing: just curly braces make a function object?
Any way to workaround the overhead in the second code if it is used many times?
EDIT
Here is the actual code that iterates many times:
in Java
while ((count = input.read(data, 0, BYTE_BLOCK_SIZE)) != -1) {
....
}
in Scala
while {
count = input.read(data, 0, BYTE_BLOCK_SIZE)
count != -1
} {
....
}
in Kotlin
while ({
count = input.read(data, 0, BYTE_BLOCK_SIZE)
count != -1
}()) {
...
}
You can see, only Kotlin makes a lot of function objects and calls them.
In Kotlin {} are always a lambda expression or a part of a syntax construct like while(true) {}. Probably different from Scala, but easy to grasp, nonetheless.
What you probably want is:
val a = run {
val b = 1
val c = b + b
c + c
}
println(a)
Kotlin has no build-in concept of "code blocks anywhere". Instead we use standard functions-helpers like run in the example above.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/run.html
If {} defines a function, you can just call the function upon declaring it, which will immediately evaluate it:
val a = {
val b = 1
val c = b + b
c + c
}()
println(a)
prints 4. (Note the () at the end of the block)
In Scala, every statement is an expression (possibly with Unit type)
That's not exactly true. Check: Is everything a function or expression or object in scala?
As Zoltan said {} defines functions so instead of:
// Kotlin
val a = {
val b = 1
val c = b + b
c + c
}
println(a)
it should be:
// Kotlin
val a = {
val b = 1
val c = b + b
c + c
}
println(a()) //you defined a function, which returns `4`, not expression
or
// Kotlin
val a = {
val b = 1
val c = b + b
c + c
}() //note these braces
println(a)
If you would like to print a value, not function, you can try to declare the variable and then use one of Kotlin functions to change a value like in example below:
var sum = 0
ints.filter { it > 0 }.forEach {
sum += it
}
print(sum)
Read: Higher-Order Functions and
Lambdas
Hope it will help
Suppose I have this code:
def a(x:Int,y:Int):Int = x+y
def b:(Int,Int) = (1,2)
and I would like to accomplish:
a(b)
What is the proper way of doing this? Also are there more efficient ways of calling a predefined multi-parameter function - in my case 8 - with the results of another function?
how about:
scala> (a _).tupled(b)
res0: Int = 3
a is a method. a _ gives you a partially applied function.
Function2.tupled creates a tupled version from your function.
Take this code:
var x = 10
val y = () => x + 1
I then want to treat y as if its a variable that holds an Int and changes anytime x changes. Essentially I want to bind y to x.
Problem is, if I just type y then I get the result res0: () => Int = <function0>
I was under the impression that you could invoke 0-arity functions without any parens, but I am required to use y() to get the behavior I am trying to achieve.
Is there a better way to define the anonymous function or do I need to use a different approach?
Why do you need to do it like that? Just do def y = x + 1
scala> var x = 1
x: Int = 1
scala> def y = x + 1
y: Int
scala> y
res0: Int = 2
scala> x = 3
x: Int = 3
scala> y
res1: Int = 4
EDIT to address some comments:
If you define val y = () => x + 1, you are defining y as a value that holds a function that takes no argument and returns an Int. To call the function that is held by this variable, you will need to call it with (), to tell the compiler that you don't want to pass the value, but to execute (evaluate) the function that is within it.
If you define val y = x + 1, you are defining a value (constant), that is assigned in the moment it is executed, you could postpone evaluation using lazy, but once it is assigned, it will not be evaluated again.
If you define def y = x + 1, you are defining a function that returns x+1, which is what you want.
You have not defined a 0-arity function. You have actually defined a Unit => Int function. That is why you can not invoke it like you would like to invoke it. I've rarely seen 0-arity functions outside the context of come contained function scope:
def something[V](value: Int)(f: => V) =
if(value %2 == 0) f
else throw new Exception("not even (and also not evaluated f)")
where it is used as a lazily deferred execution body.
Edit: I would use the other person's answer.
I'm basically new to functional programming and scala, and the following question might possibly look stupid.
val f = (a:Int) => a+1
In the above snippet, should I consider f to be a function or a variable? Coming from a C/C++ background, the first thought that occurs is that f is a variable that stores the return value of the anonymous function, but I think that's not the correct way to interpret it Any explanation would be really helpful.
(Some of the terminologies I used above might be wrong with respect to scala/functional programming, kindly bear with it)
Here, f is a variable that stores a function. It's really no different from saying any of the following:
val a = 4 // `a` is a variable storing an Int
val b = "hi" // `b` is a variable storing a String
val f = (a:Int) => a+1 // `f` is a variable storing a function
You can also confirm this with the REPL:
scala> val f = (a:Int) => a+1
f: Int => Int = <function1>
So this is telling you that f has the type Int => Int. Or in other words, f is a function that takes one argument, an Int, and returns an Int.
Since f is a variable, you can call methods on it or pass it as an argument to functions that expect its type:
a + 3 // here I'm calling the `+` method on `a`, which is an Int
f(3) // here I'm calling the `apply` method on `f`, which is a function `Int => Int`
f(a) // the function `f` expects an `Int`, which `a` is
(1 to 3).map(f) // the `map` method expects a function from Int to Int, like `f`
Yes, like dhg said, f is a variable (that can't be changed) that stores a function.
However, there's a subtlety here:
... the first thought that occurs is that f is a variable that stores the
return value of the anonymous function
f actually stores the function, not the result. So you can give it different inputs, and get different outputs. So, you can use it like f(7) and then f(5). Functions in Scala are objects, so can be assigned to variables, passed as parameters, etc.
I recently posted about function literals, which may be helpful to you.
f is a value denoting a function literal.
In the statement, the right-hand-side is a function literal. The left-hand-side binds it to a name which is then called value (the val keyword is similar to let in LISP). Now the function is associated with the symbol f, so you can refer to that function by using this symbol f.
I disagree with the other answers which suggest that f should be called a variable. f is a value, because it is fixed to the right-hand-side term which is determined only once and cannot change. On the contrary a variable, introduced with var, allows you to re-assign values to a symbol:
var f = (i: Int) => i + 1
Where var begins a variable definition, f is the name or symbol of the variable, there could be an optional : ... defining type of the variable (if you leave that out, the type is automatically inferred from the assignment), and = ... defines the value initially assigned to the variable.
So when one says value, don't confuse this with a numeric constant, it is simply an entity that doesn't change. A function can be a value too, because f then always denotes this same identical function, even if you can feed that function with different arguments which yield different results.
Now with the var you can re-assign its right-hand-side:
f(2) // --> 3
f = (i: Int) => i * 2 // assign a new function to the variable f.
f(2) // --> 4
Functional programming is all about avoiding variables (re-assignments).
It is also possible to define a function without assigning it at all (to a value or a variable). The following defines such a function and immediately calls it with argument 4:
{ i: Int => i + 1 } apply 4 // --> 5
although that is seldom useful as a statement per se, but you will see 'plain' functions often when calling a method that expects a function argument. For instance
val s = List(1, 2, 3)
s.map { (i: Int) => i + 1 } // --> List(2, 3, 4)
s.map { _ + 1 } // equivalent
s.map( _ + 1 ) // equivalent
With named parameters like
def f(x : Int = 1, y : Int = 2) = x * y
your parameter names become part of the interface
f(x=3)
Now if you want to change the parameter names locally, you are forced to perserve the public name of the parameter:
def f(x : Int = 1, y : Int = 2) = {
val (a,b) = (x,y)
a * b
}
If this a real problem? Is there a syntax to support this directly? Who do other languages handle this?
A small illustration of the problems you can run into if you switch parameter names, as suggested by Jon.
trait X{ def f(x : Int, y : Int) }
class A extends X{
override def f(y : Int, x : Int) = println("" + y + x)
}
val a = new A
scala> a.f(x = 1, y = 2)
21
scala> (a : X).f(x = 1, y = 2)
12
Yes, the parameter name is effectively part of the public interface. This is a "problem" for any language which has named arguments - or indeed produces code which is consumed by languages supporting named arguments. Sometimes this isn't well understood.
For example, C# 3 doesn't support named arguments - but VB does. So if you create a library in C# 3, someone builds against it in VB, then changing parameter names counts as a breaking change.
Ultimately some of this will be handled by refactoring tools, but it boils down to the same sort of caution as with any other aspect of a public API... you need to be very cautious.
You should also be very cautious when overriding a method with parameters - use the same parameter names as the original method, or you could cause some very subtle issues. (In particular, switching round the names of parameters would be very evil...)
I don't know about the "inferior readability" part of your title. The few times I used named parameters, it was to provide default values like increment:Int = 100000, maxCount:Int = 1000000. I think it helps readability when you have to changed on value where you call the function.