See, this is part of my problem with by-name parameters. Itâs part of the execution model, and its execution is represented by its type. However, the type has a limited representation in surface syntax. Thatâs what Iâd really like to fix. I canât speak for @pathikrit.
=> A
is so bizarre, it has special rules in the parser. Itâs a type thatâs only allowed in specific conditions, and you can never actually create an instance. def
s donât count, because they are : A
, not : => A
. As far as I know, no other Scala type behaves like by-name parameters.
An alternative to getting rid of it would be to add some syntax for it. Iâm not sure what it should be.
Following is how Scala currently works.
scala> def f(i: => Int): Int = i
f: (i: => Int)Int
What is this => Int
? I canât actually create a value of that type. Somehow, anything that is : Int
unifies with : => Int
. Bizarrely, @sjrd, you say by-name parameters are Function0s, but a Function0[A]
doesnât unify with => A
, whereas A
does. Interestingly, they could. My first thought is that => A
needs to have some constructor. I donât care what.
Suppose we call the constructor for a by-name value byname
.
scala> def x: Int = 3
f: Int
scala> def f(i: => Int): Int = i
f: (i: => Int)Int
scala> val xByName: => Int = byname x
xByName: => Int
scala> f(byname x)
3
scala> f(xByName)
3
scala> f(x)
<console>:1: error: by-name parameter type required here
f(x)
^
Or, since by-name parameters are Function0s, make () =>
be required for passing a by-name parameter.
scala> def x: Int = 3
f: Int
scala> def f(i: => Int): Int = i
f: (i: => Int)Int
scala> val xByName: => Int = () => x
xByName: => Int
scala> f(() => x)
3
scala> f(xByName)
3
scala> f(x)
<console>:1: error: by-name parameter type required here
f(x)
^
This would allow Function0[A]
to be a synonym for => A
. Perhaps also the other way around.
@sjrd please correct me if Iâm wrong, but I donât think this breaks the Unified Access Principle.