Does anyone know if something like this is possible in Scala:
case class Thing(property:String)
def f(thing:Thing, prop:String = thing.property) = println(prop)
The above code doesn't compile; giving the error error: not found: value thing
at thing.property
The following shows the expected behaviour:
f(Thing("abc"), "123") // prints "123"
f(Thing("abc")) // prints "abc"
I realise I could make the prop
argument an Option[String]
and do the check in the function definition, but I was wondering if there was a way around it with the new named/default argument support in 2.8.0.
The thing with optional parameters is, they are BAD because they are unintuitive - meaning they do NOT behave the way you would expect it. Here's why: They break ABI compatibility ! so you can change the default-arguments at one place.
The definition of a method, constructor, indexer, or delegate can specify its parameters are required or optional. Any call must provide arguments for all required parameters, but can omit arguments for optional parameters. Each optional parameter has a default value as part of its definition.
So, it is optional during a call. If a value is provided, it will overwrite the default value. Any number of arguments in a function can have a default value. But once we have a default argument, all the arguments to its right must also have default values.
Functions with optional arguments offer more flexibility in how you can use them. You can call the function with or without the argument, and if there is no argument in the function call, then a default value is used.
Yes, it's possible in Scala 2.8. Here's a quote from the "Named and Default Arguments in Scala 2.8" design document:
Since the scope of a parameter extends over all subsequent parameter lists (and the method body), default expressions can depend on parameters of preceding parameter lists (but not on other parameters in the same parameter list). Note that when using a default value which depends on earlier parameters, the actual arguments are used, not the default arguments.
def f(a: Int = 0)(b: Int = a + 1) = b // OK
And another example:
def f[T](a: Int = 1)(b: T = a + 1)(c: T = b)
// generates:
// def f$default$1[T]: Int = 1
// def f$default$2[T](a: Int): Int = a + 1
// def f$default$3[T](a: Int)(b: T): T = b
According to this, your code may look as follows:
scala> case class Thing(property:String)
defined class Thing
scala> def f(thing:Thing)(prop:String = thing.property) = println(prop)
f: (thing: Thing)(prop: String)Unit
scala> f(Thing("abc"))("123")
123
scala> f(Thing("abc"))()
abc
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