Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala Named Arguments

Tags:

scala

I'm looking at this Named Arguments example in Scala in Depth:

scala> class Parent {
     | def foo(bar: Int = 1, baz: Int = 2): Int = bar + baz
     | }
defined class Parent

scala> class Child extends Parent {
     |    override def foo(baz: Int = 3, bar: Int = 4): Int = super.foo(baz, bar)
     | }
defined class Child

scala> val p = new Parent
p: Parent = Parent@6100756c

scala> p.foo()
res1: Int = 3

scala> val x = new Child
x: Child = Child@70605759

Calling x.foo() evaluates to 7 since Child#foo has default arguments of 3 and 4.

scala> x.foo()
res3: Int = 7

Instantiate a new Child at run-time, but Parent at compile-time. This may or may not be correct

scala> val y: Parent = new Child
y: Parent = Child@540b6fd1

Calling x.foo() evaluates to 7 since Child#foo has default arguments of 3 and 4.

scala> y.foo()
res5: Int = 7

Calling x.foo() evaluates to 4 since Child#foo has a default baz argument of 3.

scala> x.foo(bar = 1)
res6: Int = 4

However, I don't understand why y.foo(bar = 1) returns 5. I would've expected Child#foo to be evaluated since y is a Child type. Passing in a bar of 1 to foo means that baz's default is 3. And so it should produce 4. But my understanding is of course incorrect.

scala> y.foo(bar = 1)
res7: Int = 5
like image 559
Kevin Meredith Avatar asked Dec 18 '13 03:12

Kevin Meredith


People also ask

What is named arguments in Scala?

Named Arguments allow you to call a function without passing the arguments in the order as they are defined in the function. In a normal function call, we need to pass the arguments with reference to the function's parameters.

What is call by name in Scala?

In Scala when arguments pass through call-by-value function it compute the passed-in expression's or arguments value once before calling the function . But a call-by-Name function in Scala calls the expression and recompute the passed-in expression's value every time it get accessed inside the function.

How do you pass parameters to a function in Scala?

One function can be passed to another function as a function argument (i.e., a function input parameter). The definition of the function that can be passed in as defined with syntax that looks like this: "f: Int > Int" , or this: "callback: () > Unit" .

How do you pass a named argument in Python?

Keyword arguments (or named arguments) are values that, when passed into a function, are identifiable by specific parameter names. A keyword argument is preceded by a parameter and the assignment operator, = . Keyword arguments can be likened to dictionaries in that they map a value to a keyword.


1 Answers

There are 2 reasons:

Default parameters implementation

scala compiler creates helper methods for default parameters:

val p = new Parent()
val c = new Child()

p.`foo$default$1`
// Int = 1
p.`foo$default$2`
// Int = 2

c.`foo$default$1`
// Int = 3
c.`foo$default$2`
// Int = 4

This is why you could use not only constants, but also fields and methods for default parameters:

def test(i: Int = util.Random.nextInt) = i

test()
// Int = -1102682999

test()
// Int = -1994652923

Named parameters implementation

There are no named parameters after compilation - all parameters are positional.

So since bar is second parameter of Child#foo this code:

c.foo(bar = 1)
// Int = 4

is translated by compiler to this:

c.foo(c.`foo$default$1`, /*bar = */1)
// Int = 4

But since bar is first parameter of Parent#foo this code:

val tmp: Parent = c
tmp.foo(bar = 1)
// Int = 5

is translated to this:

tmp.foo(/*bar = */1, tmp.`foo$default$2`)
// Int = 5

As we already know c.foo$default$2 returns 4, so c.foo(1, 4) returns 5.

like image 86
senia Avatar answered Sep 21 '22 20:09

senia