Defining variables in scala using def - scala

In scala def is used to define a method and val, var are used for defining variables.
Consider the following code:
scala> def i = 3
i: Int
scala> i.getClass()
res0: Class[Int] = int
scala> val v = 2
v: Int = 2
scala> v.getClass()
res1: Class[Int] = int
scala> println(v)
2
scala> println(i)
3
scala> i+v
res4: Int = 5
scala> def o = () => 2+3
o: () => Int
scala> o.getClass()
res5: Class[_ <: () => Int] = class $$Lambda$1139/1753607449
Why does variable definition work using def? If it is defining a function that returns an Int then why does getClass show Int instead of a function object?

Unlike val or var declaration, def i = 3 is not variable declaration. You are defining a method/function which returns a constant 3 and i does not take any parameters.
declaration using val and var get evaluated immediately but in case of lazy val and def evaluation happens when called explicitly.
i is a not argument function. In order to get rid of confusion you could declare it using empty parenthesis as well
def i() = 3
Difference between lazy val and def is
lazy val is lazily evaluated and the result is cached. That means further
def declaration is evaluated every time you call method name.
Example using Scala REPL
scala> lazy val a = { println("a evaluated"); 1}
a: Int = <lazy>
scala> def i = { println("i function evaluated"); 2}
i: Int
scala> a
a evaluated
res0: Int = 1
scala> a
res1: Int = 1
scala> a
res2: Int = 1
scala> i
i function evaluated
res3: Int = 2
scala> i
i function evaluated
res4: Int = 2
scala> i
i function evaluated
res5: Int = 2
Notice that a is evaluated only once and further invocations of a return the cached result i.e lazy val is evaluated once when it is called and the result is stored forever. So you see println output once
Notice function is evaluated every time it is invoked. In this case you see println output every time you invoke the function
General Convention
There's a convention of using an empty parameter list when the method has side effects and leaving them off when its pure.
edited
scala> def i = 1
i: Int
scala> :type i
Int
scala> :type i _
() => Int

EDIT: My answer addresses the question of revision #3.
It is quite useful to look on the code in the middle of the compilation process where you can look on what your code is actually translated to. The following simple program:
object TestApp {
def definedVal = 3
val valVal = 3
lazy val lazyValVal = 3
def main(args: Array[String]) {
println(definedVal)
println(valVal)
println(lazyValVal)
}
}
is translated to the following (using -Xprint:mixin compiler option):
[[syntax trees at end of mixin]] // test.scala
package <empty> {
object TestApp extends Object {
#volatile private[this] var bitmap$0: Boolean = false;
private def lazyValVal$lzycompute(): Int = {
{
TestApp.this.synchronized({
if (TestApp.this.bitmap$0.unary_!())
{
TestApp.this.lazyValVal = 3;
TestApp.this.bitmap$0 = true;
()
};
scala.runtime.BoxedUnit.UNIT
});
()
};
TestApp.this.lazyValVal
};
def definedVal(): Int = 3;
private[this] val valVal: Int = _;
<stable> <accessor> def valVal(): Int = TestApp.this.valVal;
lazy private[this] var lazyValVal: Int = _;
<stable> <accessor> lazy def lazyValVal(): Int = if (TestApp.this.bitmap$0.unary_!())
TestApp.this.lazyValVal$lzycompute()
else
TestApp.this.lazyValVal;
def main(args: Array[String]): Unit = {
scala.this.Predef.println(scala.Int.box(TestApp.this.definedVal()));
scala.this.Predef.println(scala.Int.box(TestApp.this.valVal()));
scala.this.Predef.println(scala.Int.box(TestApp.this.lazyValVal()))
};
def <init>(): TestApp.type = {
TestApp.super.<init>();
TestApp.this.valVal = 3;
()
}
}
}
From the output above it is possible to conclude the following:
definedVal is actually a method.
valVal is a field which is initialized in the constructor and has an automatically generated accessor.
For the lazy field lazyValVal compiler generates compute method which is called only once when the field is accessed the first time.

There is few different concept. Call by name, call by value and call by need. All def is essentially calls by name. What do you mean variable definition using def ??
Looks like duplicate to me:
Call by name vs call by value in Scala, clarification needed
More details in wiki: https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name

Related

Underscore treats val like a def

I think I understand why this happens
def x() = 1
x _ // () => Int
x() _ // error: _ must follow method; cannot follow Int
x _ turns the method into a function, so you get a no-arg function. x() _ makes no sense because calling the method gives you an Int, which can't be turned into a function. But then why does this happen?
val x = 1
x _ // () => Int
There is little difference between a val and a parameterless method, except that the parameterless method doesn't calculate the value until it's called (and will re-calculate the value for each additional call). What really happens to a val underneath is that there is a private field declared along with a public accessor method that returns that value.
object Test {
def method = 1
val value = 1
}
Compiles to:
object Test extends Object {
def method(): Int = 1;
private[this] val value: Int = _;
<stable> <accessor> def value(): Int = Test.this.value;
def <init>(): Test.type = {
Test.super.<init>();
Test.this.value = 1;
()
}
}
Note the line:
<stable> <accessor> def value(): Int = Test.this.value;
This allows you to, for example, override a def in a super-class with a val in a sub-class, since it's actually overriding a method. Since a method is actually generated, you are allowed to eta-expand a val into a function.

Diference betwen def and val in particular case [duplicate]

What is the difference between:
def even: Int => Boolean = _ % 2 == 0
and
val even: Int => Boolean = _ % 2 == 0
Both can be called like even(10).
Method def even evaluates on call and creates new function every time (new instance of Function1).
def even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = false
val even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = true
With def you can get new function on every call:
val test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -1049057402
test()
// Int = -1049057402 - same result
def test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -240885810
test()
// Int = -1002157461 - new result
val evaluates when defined, def - when called:
scala> val even: Int => Boolean = ???
scala.NotImplementedError: an implementation is missing
scala> def even: Int => Boolean = ???
even: Int => Boolean
scala> even
scala.NotImplementedError: an implementation is missing
Note that there is a third option: lazy val.
It evaluates when called the first time:
scala> lazy val even: Int => Boolean = ???
even: Int => Boolean = <lazy>
scala> even
scala.NotImplementedError: an implementation is missing
But returns the same result (in this case same instance of FunctionN) every time:
lazy val even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = true
lazy val test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -1068569869
test()
// Int = -1068569869 - same result
Performance
val evaluates when defined.
def evaluates on every call, so performance could be worse than val for multiple calls. You'll get the same performance with a single call. And with no calls you'll get no overhead from def, so you can define it even if you will not use it in some branches.
With a lazy val you'll get a lazy evaluation: you can define it even if you will not use it in some branches, and it evaluates once or never, but you'll get a little overhead from double check locking on every access to your lazy val.
As #SargeBorsch noted you could define method, and this is the fastest option:
def even(i: Int): Boolean = i % 2 == 0
But if you need a function (not method) for function composition or for higher order functions (like filter(even)) compiler will generate a function from your method every time you are using it as function, so performance could be slightly worse than with val.
Consider this:
scala> def even: (Int => Boolean) = {
println("def");
(x => x % 2 == 0)
}
even: Int => Boolean
scala> val even2: (Int => Boolean) = {
println("val");
(x => x % 2 == 0)
}
val //gets printed while declaration. line-4
even2: Int => Boolean = <function1>
scala> even(1)
def
res9: Boolean = false
scala> even2(1)
res10: Boolean = false
Do you see the difference? In short:
def: For every call to even, it calls the body of the even method again. But with even2 i.e. val, the function is initialized only once while declaration (and hence it prints val at line 4 and never again) and the same output is used each time it accessed. For example try doing this:
scala> import scala.util.Random
import scala.util.Random
scala> val x = { Random.nextInt }
x: Int = -1307706866
scala> x
res0: Int = -1307706866
scala> x
res1: Int = -1307706866
When x is initialized, the value returned by Random.nextInt is set as the final value of x. Next time x is used again, it will always return the same value.
You can also lazily initialize x. i.e. first time it is used it is initialized and not while declaration. For example:
scala> lazy val y = { Random.nextInt }
y: Int = <lazy>
scala> y
res4: Int = 323930673
scala> y
res5: Int = 323930673
See this:
var x = 2 // using var as I need to change it to 3 later
val sq = x*x // evaluates right now
x = 3 // no effect! sq is already evaluated
println(sq)
Surprisingly, this will print 4 and not 9! val (even var) is evaluated immediately and assigned.
Now change val to def.. it will print 9! Def is a function call.. it will evaluate each time it is called.
val i.e. "sq" is by Scala definition is fixed. It is evaluated right at the time of declaration, you can't change later. In other examples, where even2 also val, but it declared with function signature i.e. "(Int => Boolean)", so it is not Int type. It is a function and it's value is set by following expression
{
println("val");
(x => x % 2 == 0)
}
As per Scala val property, you can't assign another function to even2, same rule as sq.
About why calling eval2 val function not printing "val" again and again ?
Orig code:
val even2: (Int => Boolean) = {
println("val");
(x => x % 2 == 0)
}
We know, in Scala last statement of above kind of expression (inside { .. }) is actually return to the left hand side. So you end up setting even2 to "x => x % 2 == 0" function, which matches with the type you declared for even2 val type i.e. (Int => Boolean), so compiler is happy. Now even2 only points to "(x => x % 2 == 0)" function (not any other statement before i.e. println("val") etc. Invoking event2 with different parameters will actually invoke "(x => x % 2 == 0)" code, as only that is saved with event2.
scala> even2(2)
res7: Boolean = true
scala> even2(3)
res8: Boolean = false
Just to clarify this more, following is different version of the code.
scala> val even2: (Int => Boolean) = {
| println("val");
| (x => {
| println("inside final fn")
| x % 2 == 0
| })
| }
What will happen ? here we see "inside final fn" printed again and again, when you call even2().
scala> even2(3)
inside final fn
res9: Boolean = false
scala> even2(2)
inside final fn
res10: Boolean = true
scala>
Executing a definition such as def x = e will not evaluate the expression e. In- stead e is evaluated whenever x is invoked.
Alternatively, Scala offers a value definition
val x = e,which does evaluate the right-hand-side as part of the evaluation of the definition.
If x is then used subsequently, it is immediately replaced by the pre-computed value of e, so that the expression need not be evaluated again.
also, Val is a by value evaluation. Which means the right-hand side expression is evaluated during definition. Where Def is by name evaluation. It will not evaluate until it's used.
In addition to the above helpful replies, my findings are:
def test1: Int => Int = {
x => x
}
--test1: test1[] => Int => Int
def test2(): Int => Int = {
x => x+1
}
--test2: test2[]() => Int => Int
def test3(): Int = 4
--test3: test3[]() => Int
The above shows that “def” is a method (with zero argument parameters) that returns another function "Int => Int” when invoked.
The conversion of methods to functions is well explained here: https://tpolecat.github.io/2014/06/09/methods-functions.html
In REPL,
scala> def even: Int => Boolean = { _% 2 == 0 }
even: Int => Boolean
scala> val even: Int => Boolean = { _% 2 == 0 }
even: Int => Boolean = $$Lambda$1157/1017502292#57a0aeb8
def means call-by-name, evaluated on demand
val means call-by-value, evaluated while initialization
Note: There are different types of functions in Scala: abstract, concrete, anonymous, high order, pure, impure etc...
Explaining val function:
A val function in Scala is a complete object. There are traits in Scala to represent functions with various numbers of arguments: Function0, Function1, Function2, etc. As an instance of a class that implements one of these traits, a function object has methods. One of these methods is the apply method, which contains the code that implements the body of the function.
When we create a variable whose value is a function object and we then reference that variable followed by parentheses, that gets converted into a call to the apply method of the function object.
Explaining Method i.e def:
Methods in Scala are not values, but functions are.
A Scala method, as in Java, is a part of a class. It has a name, a signature, optionally some annotations, and some bytecode.
The implementation of a method is an ordered sequence of statements that produces a value that must be compatible with its return type.

How to understand this Scala function call

I am Scala beginner. Below Scala code runs well, but I cannot understand it. Log shows, line 19 finally run to line 12. How could it be?
object TestClassDef {
class Person {
private var _age = 0
def age:Int = _age
def age_=(newAge: Int) = {
_age = newAge
println("age changed to " + _age) // line 12
}
}
def main(args: Array[String]) {
var p = new Person()
// p.age_=(25)
p.age = 26 // line 19
}
}
If I get your question correctly, you're surprised that the method is called when you assign the value on line 19. This is because the _= (at the end of the age function with an Int parameter) means that it's an assignment operator (also see What are all the uses of an underscore in Scala?) so it does make sense that it's called when you simply type p.age = 26.
This is mutator
def age_=(newAge: Int) = {
_age = newAge
println("age changed to " + _age)
}
So the call
p.age = 26
is converted by compiler to
p.age_=(26)
which makes call to mutator.
Mutator naming conventions from http://docs.scala-lang.org/style/naming-conventions.html
For mutators, the name of the method should be the name of the property with “_=” appended. As long as a corresponding accessor with that particular property name is defined on the enclosing type, this convention will enable a call-site mutation syntax which mirrors assignment. Note that this is not just a convention but a requirement of the language.
Also to see what compiler is creating pass -Xprint:typer to the Scala compiler. For reference the above code with this parameter generates:
package <empty> {
object TestClassDef extends scala.AnyRef {
def <init>(): TestClassDef.type = {
TestClassDef.super.<init>();
()
};
class Person extends scala.AnyRef {
def <init>(): TestClassDef.Person = {
Person.super.<init>();
()
};
private[this] var _age: Int = 0;
<accessor> private def _age: Int = Person.this._age;
<accessor> private def _age_=(x$1: Int): Unit = Person.this._age = x$1;
def age: Int = Person.this._age;
def age_=(newAge: Int): Unit = {
Person.this._age_=(newAge);
scala.this.Predef.println("age changed to ".+(Person.this._age))
}
};
def main(args: Array[String]): Unit = {
var p: TestClassDef.Person = new TestClassDef.this.Person();
p.age_=(26)
}
}
}
Scala allows non-alphanumerics in identifiers (in two ways):
case 1:
(specialcharacters)*
scala> val ##*# = 1000000
scala> val #Alpha# = 1 // mixing alphanumerics not allowed
case 2:
letter(alphanumerics)* _ (specialcharacters)*
scala> val k12? = 1 // doesn't work, _ is mandatory
scala> val k12_? = 1
scala> val k12_?*&^% = 1
scala> val k12_?Alpha = 1 // doesn't work, can't mix alphanumeric
Special cases:
Some symbols/combination-of-symbols are reserved e.g. = # <%
scala> val # = 1 // doesn't work
scala> val ### = 1 // works fine
scala> val <% = 1 // doesn't work
scala> val <%> = 1 // works fine
Some symbol-combinations are special, _= can be used in method names but not in variable names.
scala> val k_= = 1 // doesn't work
scala> def k_= = 1 // works fine
method names ending in _= are setters.
if a class/object's setter method def x_= is defined along with a parameter-less method of same name def x, then x = e is interpreted as x_=(e)

What is the difference between "def" and "val" to define a function

What is the difference between:
def even: Int => Boolean = _ % 2 == 0
and
val even: Int => Boolean = _ % 2 == 0
Both can be called like even(10).
Method def even evaluates on call and creates new function every time (new instance of Function1).
def even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = false
val even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = true
With def you can get new function on every call:
val test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -1049057402
test()
// Int = -1049057402 - same result
def test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -240885810
test()
// Int = -1002157461 - new result
val evaluates when defined, def - when called:
scala> val even: Int => Boolean = ???
scala.NotImplementedError: an implementation is missing
scala> def even: Int => Boolean = ???
even: Int => Boolean
scala> even
scala.NotImplementedError: an implementation is missing
Note that there is a third option: lazy val.
It evaluates when called the first time:
scala> lazy val even: Int => Boolean = ???
even: Int => Boolean = <lazy>
scala> even
scala.NotImplementedError: an implementation is missing
But returns the same result (in this case same instance of FunctionN) every time:
lazy val even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = true
lazy val test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -1068569869
test()
// Int = -1068569869 - same result
Performance
val evaluates when defined.
def evaluates on every call, so performance could be worse than val for multiple calls. You'll get the same performance with a single call. And with no calls you'll get no overhead from def, so you can define it even if you will not use it in some branches.
With a lazy val you'll get a lazy evaluation: you can define it even if you will not use it in some branches, and it evaluates once or never, but you'll get a little overhead from double check locking on every access to your lazy val.
As #SargeBorsch noted you could define method, and this is the fastest option:
def even(i: Int): Boolean = i % 2 == 0
But if you need a function (not method) for function composition or for higher order functions (like filter(even)) compiler will generate a function from your method every time you are using it as function, so performance could be slightly worse than with val.
Consider this:
scala> def even: (Int => Boolean) = {
println("def");
(x => x % 2 == 0)
}
even: Int => Boolean
scala> val even2: (Int => Boolean) = {
println("val");
(x => x % 2 == 0)
}
val //gets printed while declaration. line-4
even2: Int => Boolean = <function1>
scala> even(1)
def
res9: Boolean = false
scala> even2(1)
res10: Boolean = false
Do you see the difference? In short:
def: For every call to even, it calls the body of the even method again. But with even2 i.e. val, the function is initialized only once while declaration (and hence it prints val at line 4 and never again) and the same output is used each time it accessed. For example try doing this:
scala> import scala.util.Random
import scala.util.Random
scala> val x = { Random.nextInt }
x: Int = -1307706866
scala> x
res0: Int = -1307706866
scala> x
res1: Int = -1307706866
When x is initialized, the value returned by Random.nextInt is set as the final value of x. Next time x is used again, it will always return the same value.
You can also lazily initialize x. i.e. first time it is used it is initialized and not while declaration. For example:
scala> lazy val y = { Random.nextInt }
y: Int = <lazy>
scala> y
res4: Int = 323930673
scala> y
res5: Int = 323930673
See this:
var x = 2 // using var as I need to change it to 3 later
val sq = x*x // evaluates right now
x = 3 // no effect! sq is already evaluated
println(sq)
Surprisingly, this will print 4 and not 9! val (even var) is evaluated immediately and assigned.
Now change val to def.. it will print 9! Def is a function call.. it will evaluate each time it is called.
val i.e. "sq" is by Scala definition is fixed. It is evaluated right at the time of declaration, you can't change later. In other examples, where even2 also val, but it declared with function signature i.e. "(Int => Boolean)", so it is not Int type. It is a function and it's value is set by following expression
{
println("val");
(x => x % 2 == 0)
}
As per Scala val property, you can't assign another function to even2, same rule as sq.
About why calling eval2 val function not printing "val" again and again ?
Orig code:
val even2: (Int => Boolean) = {
println("val");
(x => x % 2 == 0)
}
We know, in Scala last statement of above kind of expression (inside { .. }) is actually return to the left hand side. So you end up setting even2 to "x => x % 2 == 0" function, which matches with the type you declared for even2 val type i.e. (Int => Boolean), so compiler is happy. Now even2 only points to "(x => x % 2 == 0)" function (not any other statement before i.e. println("val") etc. Invoking event2 with different parameters will actually invoke "(x => x % 2 == 0)" code, as only that is saved with event2.
scala> even2(2)
res7: Boolean = true
scala> even2(3)
res8: Boolean = false
Just to clarify this more, following is different version of the code.
scala> val even2: (Int => Boolean) = {
| println("val");
| (x => {
| println("inside final fn")
| x % 2 == 0
| })
| }
What will happen ? here we see "inside final fn" printed again and again, when you call even2().
scala> even2(3)
inside final fn
res9: Boolean = false
scala> even2(2)
inside final fn
res10: Boolean = true
scala>
Executing a definition such as def x = e will not evaluate the expression e. In- stead e is evaluated whenever x is invoked.
Alternatively, Scala offers a value definition
val x = e,which does evaluate the right-hand-side as part of the evaluation of the definition.
If x is then used subsequently, it is immediately replaced by the pre-computed value of e, so that the expression need not be evaluated again.
also, Val is a by value evaluation. Which means the right-hand side expression is evaluated during definition. Where Def is by name evaluation. It will not evaluate until it's used.
In addition to the above helpful replies, my findings are:
def test1: Int => Int = {
x => x
}
--test1: test1[] => Int => Int
def test2(): Int => Int = {
x => x+1
}
--test2: test2[]() => Int => Int
def test3(): Int = 4
--test3: test3[]() => Int
The above shows that “def” is a method (with zero argument parameters) that returns another function "Int => Int” when invoked.
The conversion of methods to functions is well explained here: https://tpolecat.github.io/2014/06/09/methods-functions.html
In REPL,
scala> def even: Int => Boolean = { _% 2 == 0 }
even: Int => Boolean
scala> val even: Int => Boolean = { _% 2 == 0 }
even: Int => Boolean = $$Lambda$1157/1017502292#57a0aeb8
def means call-by-name, evaluated on demand
val means call-by-value, evaluated while initialization
Note: There are different types of functions in Scala: abstract, concrete, anonymous, high order, pure, impure etc...
Explaining val function:
A val function in Scala is a complete object. There are traits in Scala to represent functions with various numbers of arguments: Function0, Function1, Function2, etc. As an instance of a class that implements one of these traits, a function object has methods. One of these methods is the apply method, which contains the code that implements the body of the function.
When we create a variable whose value is a function object and we then reference that variable followed by parentheses, that gets converted into a call to the apply method of the function object.
Explaining Method i.e def:
Methods in Scala are not values, but functions are.
A Scala method, as in Java, is a part of a class. It has a name, a signature, optionally some annotations, and some bytecode.
The implementation of a method is an ordered sequence of statements that produces a value that must be compatible with its return type.

Using lazy evaluation functions in varargs

What is wrong is the following method?
def someMethod(funcs: => Option[String]*) = {
...
}
That actually "works" under 2.7.7 if you add parens:
scala> def someMethod(funcs: => (Option[String]*)) = funcs
someMethod: (=> Option[String]*)Option[String]*
except it doesn't actually work at runtime:
scala> someMethod(Some("Fish"),None)
scala.MatchError: Some(Fish)
at scala.runtime.ScalaRunTime$.boxArray(ScalaRunTime.scala:136)
at .someMethod(<console>:4)
at .<init>(<console>:6)
at .<clinit>(<console>) ...
In 2.8 it refuses to let you specify X* as the output of any function or by-name parameter, even though you can specify it as an input (this is r21230, post-Beta 1):
scala> var f: (Option[Int]*) => Int = _
f: (Option[Int]*) => Int = null
scala> var f: (Option[Int]*) => (Option[Int]*) = _
<console>:1: error: no * parameter type allowed here
var f: (Option[Int]*) => (Option[Int]*) = _
But if you try to convert from a method, it works:
scala> def m(oi: Option[Int]*) = oi
m: (oi: Option[Int]*)Option[Int]*
scala> var f = (m _)
f: (Option[Int]*) => Option[Int]* = <function1>
scala> f(Some(1),None)
res0: Option[Int]* = WrappedArray(Some(1), None)
So it's not entirely consistent.
In any case, you can possibly achieve what you want by passing in an Array and then sending that array to something that takes repeated arguments:
scala> def aMethod(os: Option[String]*) { os.foreach(println) }
aMethod: (os: Option[String]*)Unit
scala> def someMethod(funcs: => Array[Option[String]]) { aMethod(funcs:_*) }
someMethod: (funcs: => Array[Option[String]])Unit
scala> someMethod(Array(Some("Hello"),Some("there"),None))
Some(Hello)
Some(there)
None
If you really want to (easily) pass a bunch of lazily evaluated arguments, then you need a little bit of infrastructure that as far as I know doesn't nicely exist in the library (this is code for 2.8; view it as inspiration for a similar strategy in 2.7):
class Lazy[+T](t: () => T, lt: Lazy[T]) {
val params: List[() => T] = (if (lt eq null) Nil else t :: lt.params)
def ~[S >: T](s: => S) = new Lazy[S](s _,this)
}
object Lz extends Lazy[Nothing](null,null) {
implicit def lazy2params[T : Manifest](lz: Lazy[T]) = lz.params.reverse.toArray
}
Now you can easily create a bunch of parameters that are lazily evaluated:
scala> import Lz._ // To get implicit def
import Lz._
scala> def lazyAdder(ff: Array[()=>Int]) = {
| println("I'm adding now!");
| (0 /: ff){(n,f) => n+f()}
| }
lazyAdder: (ff: Array[() => Int])Int
scala> def yelp = { println("You evaluated me!"); 5 }
yelp: Int
scala> val a = 3
a: Int = 3
scala> var b = 7
b: Int = 7
scala> lazyAdder( Lz ~ yelp ~ (a+b) )
I'm adding now!
You evaluated me!
res0: Int = 15
scala> val plist = Lz ~ yelp ~ (a+b)
plist: Lazy[Int] = Lazy#1ee1775
scala> b = 1
b: Int = 1
scala> lazyAdder(plist)
I'm adding now!
You evaluated me!
res1: Int = 9
Evidently repeated arguments are not available for by-name parameters.