Add support for lazy (explicit|implicit) parameters #11
Comments
Hey, Miles, what is the status of this issue? |
No recent progress as far as I'm aware. I'll come back to it when I have time. |
I may have some time to contribute (actually, I am writing library code where the feature would be very useful). But I'm not sure if I'm the right kind of person to contribute (it has been some time since I've been involved in similar stuff). |
Two main changes: - values with type => T are stable if T is stable - types deriving from scala.Singleton are considered stable The two changes together allow to declare by-name-parameters to be stable by declaring them to have a Singleton type.
I have a potential fix for this. The program can be compiled if we change the definition of
See #3773. WDYT? |
does "foo: => Foo & Singleton" indeed mean that foo is evaluated by need and at most once? |
No, it just means that the actual argument to So it seems this would not in general solve the problem of lazy implicits because the inferred arguments to lazy implicits are most often not stable. It actually looks quite hard to find a good solution that maintains soundness. |
In fact #3005 does not seem to be a useful fix for the problem. And I don't know what a sound solution would look like. I am leaving this open for a while in case others have ideas, but if not we will close with stat:revisit. |
@milessabin Lazy vals are allowed in paths, but they must be final and their type must be a concrete class. Here are some test cases. The code in
So on third thought, yes, this could actually still allow many important use cases. |
Suppose we used the same criteria for lazy parameters? They can be viewed as effectively final and we can restrict types to those that are concrete in the same sense as class |
@milessabin Was there any change here? I'm studying realizability right now, so this is good time to discuss it.
That currently makes sense to me. |
BTW, I think there are two questions here:
Beware I need to talk again to somebody who understands realizability here (that is, @odersky). |
I've not done any more on this recently. I'd be very happy to pick this up in Scala if Dotty decides in favour of supporting lazy parameters. |
Is there some sort of SIP for this in Dotty? |
The way we left it was that @odersky needed to rule on the stability issue. |
#1998 makes implicit parameters consistent with explicit parameters by allowing implicit parameters to also be by-name. This change was motivated in Dotty (and work in progress on Scala 2) to support the same sort of type level programming use cases which are currently enabled by shapeless's
Lazy
type.However, the bynamity of a parameter prevents it from being stable which means that the following,
doesn't compile (either in Dotty or Scala 2 with by-name implicit support) because the by-name argument
foo
is not stable,This pattern is very important in implicit-based type level programming, so this would be a disappointing limitation. By contrast, shapeless's
Lazy
captures the value in a stable context and hence supports the following with vanilla Scala 2,Currently the following is a workaround with by-name implicits which compiles both on my Scala 2 branch and with Dotty,
ie. we use the Aux pattern to avoid the need for a stable value. This is clumsy however, and the additional type parameter (which typically must be inferred) can make it hard to express methods which also require explicit type arguments.
So, whilst by name implicits get us close be being able to replace shapeless's
Lazy
macro, it's not quite there.It was proposed in the discussion on #1998 to use the
lazy
modifier on method parameters to express by-need (ie. at most once) evaluation semantics. If such parameters could participate in stable paths (at least modulo the restrictions described here and the issues enumerated in the Scala 2 ticket) then alazy implicit
parameter would more or less exactly replicate the semantics of shapeless'sLazy
.The text was updated successfully, but these errors were encountered: