-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Allow for an overriden lazy val to be accessed through super
#1999
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Same with Dotty. Did I misunderstand what you asked? |
I expect the answer |
super
The above obviously works if you use |
ok, let me ask several follow-up questions which are believe are the reasons why this is prohibited. trait A { lazy val s = {println("A"); 1} }
trait B extends A { override lazy val s = {println("B"); super.s + super.s} }
class C extends B { override lazy val s = {println("C"); super.s + super.s} }
new C.s edit: changed A from class to trait |
jsonnet says |
In jsonnet language the code that you've wrote isn't a single assignment with a side-effect, but two independent assignments.
the initialization of |
jsonnet computes fields a single time. But yes, I see that super.s needs to itself be a lazy val for that to happen, so that it's not enough to reuse java inheritance on an underlying computation function. |
Though that's better than nothing. |
In particular, lack of caching matters only when OTHER methods refer to the method's super value. It only one method refers to it, then it can manually cache the value in a val. One ugly implementation strategy: a hidden field (or a set of hidden fields) contains a cache of (SuperTrait, LazyFieldName) => LazyCell, and the super.x accessors use that. Ouch. |
you can't make such an assumption and you don't know the entire world. Someone-somewhere else may be sub-classing the same trait and also accessing the same super-lazy val. It is technically possible in example above to create 3 underlying fields in This can be implemented, the implementation would need to introduce crosstalk between While this is possible, I would expect the implementation to be a can of worms and, given that there's a simple workaround, this will not have high priority. |
What about this implementation strategy:
Also, what about having a decent macro system a la Racket, so it can all be implemented as an independent module? |
I think the cost of the change far outweighs the possible benefits, so I am going to close this one. |
When programming in jsonnet (pure lazy functional-object dynamic language), it is great to be able to use inheritance on lazy vals (all vals are lazy in jsonnet).
To reproduce the same pattern in Scala, I have to define two different entities,
Then, when using the lazy val I must use lv, but when I want to use inheritance, I must override computeLv instead. That's awkward.
I propose that there should always be an underlying computeLv, that is overridden when you override the lazy val, so that you can use lv both when referring to the value and when overriding it.
The text was updated successfully, but these errors were encountered: