Function0 vs. By-name parameters

112 views
Skip to first unread message

Alex Cruise

unread,
Jun 27, 2012, 1:19:13 PM6/27/12
to scala-debate
How hard would it be to make them mutually substitutable?

-0xe1a

Rex Kerr

unread,
Jun 27, 2012, 1:29:11 PM6/27/12
to Alex Cruise, scala-debate
Can you say a bit more about what you envision?  Right now Scala has to go to some trouble to _avoid_ having them substitute for each other since they not only erase to the same thing but a by-name parameter _is_ just a `Function0` typed differently.

  --Rex

Alex Cruise

unread,
Jun 27, 2012, 1:40:51 PM6/27/12
to Rex Kerr, scala-debate
On Wed, Jun 27, 2012 at 10:29 AM, Rex Kerr <ich...@gmail.com> wrote:
Can you say a bit more about what you envision?  Right now Scala has to go to some trouble to _avoid_ having them substitute for each other since they not only erase to the same thing but a by-name parameter _is_ just a `Function0` typed differently.

I'm talking about allowing a Function0[T] formal parameter to take an => T actual parameter, and vice versa.  I really haven't thought about any possible negative implications, I just like to throw ideas out there. :)

-0xe1a

Rex Kerr

unread,
Jun 27, 2012, 1:50:40 PM6/27/12
to Alex Cruise, scala-debate
Your answer doesn't really help.  Why do you want to do this?

Not making a change is always easier than making a change.  It's helpful to provide _some_ sort of motivation when you propose a change.

  --Rex

James Earl Douglas

unread,
Jun 27, 2012, 1:55:23 PM6/27/12
to Rex Kerr, Alex Cruise, scala-debate
Why not just use an implicit conversion from Function0[A] to A?

scala> implicit def f0ToByName[A](f0: Function0[A]): A = f0()
f0ToByName: [A](f0: () => A)A

scala> def foo(x: => String) = "x ++ x is " + x + x
foo: (x: => String)java.lang.String

scala> val bar: Function0[String] = () => { println("bar()"); "bar" }
bar: () => String = <function0>

scala> foo(bar)
bar()
bar()
res0: java.lang.String = x ++ x is barbar

James Earl Douglas

unread,
Jun 27, 2012, 3:46:32 PM6/27/12
to Rex Kerr, Alex Cruise, scala-debate
> allowing a Function0[T] formal parameter to take an => T actual parameter

On second thought, it sounds like you want the reverse of what I just posted, but I can't quite get it to work the way I want:

scala> implicit def byNameToF0[A](a: => A): Function0[A] = () => a
byNameToF0: [A](a: => A)() => A

scala> def baz(x: Function0[String]) = "x ++ x is " + x() + x()
baz: (x: () => String)java.lang.String

scala> baz({ println("raz()") ; "raz" })
raz()
res0: java.lang.String = x ++ x is razraz

scala> baz(byNameToF0{ println("raz()") ; "raz" })
raz()
raz()
res1: java.lang.String = x ++ x is razraz

If I call the conversion directly, the full block is treated as the by-name, but it doesn't work if I let the implicit conversion handle it.

Paul Butcher

unread,
Jun 28, 2012, 9:52:16 AM6/28/12
to Rex Kerr, Alex Cruise, scala-debate
I'm not sure whether this is what Alex has in mind, but I certainly have some issues with FunctionN traits and by-name parameters in ScalaMock. To see the kind of thing I mean, take a look at the gyrations I have to perform in this test in ScalaMock3 which tests a method that takes a by-name parameter:


If anyone has any suggestions for ways to make this less ugly, I'm all ears!

--
paul.butcher->msgCount++

Snetterton, Castle Combe, Cadwell Park...
Who says I have a one track mind?

http://www.paulbutcher.com/
LinkedIn: http://www.linkedin.com/in/paulbutcher
MSN: pa...@paulbutcher.com
AIM: paulrabutcher
Skype: paulrabutcher

Reply all
Reply to author
Forward
0 new messages