Why can't a class val parameter be call-by-name?
scala
Solution
A class can very well have call-by-name parameters, as long as they are not `val` or `var`:
> scala
Welcome to Scala version 2.11.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_55).
Type in expressions to have them evaluated.
Type :help for more information.
scala> class Foo(f: => Unit) {
| def run(): Unit = f
| }
defined class Foo
scala> new Foo(println("hello"))
res0: Foo = Foo@5da6b8c6
scala> res0.run()
hello
The reason a `val` or `var` parameter cannot be by-name is simply that a class field cannot be by-name, no more than local variable, for that matter. So the following is invalid:
scala> class FooInvalid(val v: => Unit) {
<console>:1: error: `val' parameters may not be call-by-name
class FooInvalid(val v: => Unit) {
^
However, it is possible to have a by-name parameter that is assigned, as a function to a `val` field, like this (but then you have to use `()` as call site):
scala> class FooVal(v0: => Unit) {
| val v: () => Unit = () => v0
| }
defined class FooVal
scala> new FooVal(println("hello"))
res2: FooVal = FooVal@75c145bc
scala> res2.v
res3: () => Unit = <function0>
scala> res2.v()
hello
Finally, instead of defining `v` as a `val` of type `() => Unit`, you can define it as `def` of type `Unit`. And then you get the behavior you probably wanted in the first place:
scala> class FooDef(v0: => Unit) {
| def v: Unit = v0
| }
defined class FooDef
scala> new FooDef(println("hello"))
res5: FooDef = FooDef@2e04a041
scala> res5.v
hello
One could argue that the compiler should do this transformation itself, but that would not be consistent with the semantics that a `val` must be stable (e.g., with a stable value you can `import x._` its members, which you cannot do with an unstable value) since a `def` (even without `()`) is a not a stable value. Best to leave this small rewriting to the user rather than introduce a very weird unsoundness.
Problem
I'm trying to use a class to aggregate as a single interface a bunch of proxies for API functions. A couple of these are nullary functions, but I don't want the act of including them in the class constructor to trigger the API calls. My solution right now is to wrap the call in a literal nullary function `new myClass(() => apiCall)` and then calling the member function explicitly. This isn't all that bad, but I'm wondering if there's a technical reason I can't just use a call-by-name parameter to pass lazy reference to the method? Example: ``` scala> class MyClass(val apiCall: => String) <console>:1: error: `val' parameters may not be call-by-name class MyClass(val apiCall: => String) ``` Edit I should have specified that my question is why a class can't have a `val` parameter. Added an example.