Closed demobox closed 10 years ago
@nermin: ping..?
The idea behind this option was that a reader might have a (Java influenced) model in which by default all variables are first initialized with zero, and if you don't think too much a possible solution would be that adding 1 to both initial zeros leads to a value 1 for both objects.
Moreover, the answers are currently very symmetric (1, 2, both or an expression), and I like such symmetries.
In addition, as a puzzler solver I am not that much interested in whether a compile-time or a runtime exception is thrown on a particular puzzler, usually these are not the correct answers. I see your point that a runtime-exception might be a valuable option and propose to change the last option from fails with a compilation exception
either to fails with a runtime exception
or simply fails with an exception
.
I see your point that a runtime-exception might be a valuable option and propose to change the last option from fails with a compilation exception either to fails with a runtime exception or simply fails with an exception.
Thanks for the feedback, @dgruntz! To be clear, I also liked the prints 1
, it was just a matter of trying to choose the least likely one ;-)
Most other puzzlers differentiate between compilation and runtime exceptions, so I don't think we'd want to introduce a generic "fails with an exception here", but am happy to replace the compilation exception with the runtime one (which, incidentally, is actually what happens with two object
s in a class
, as discussed on scala-lang)
Question is: do we feel readers are more likely to think "it doesn't compile - perhaps Scala doesn't support circular definitions" vs. "it will print 1 - perhaps Scala doesn't bother initializing the other one for some reason and just returns the default value instead"? I think I as a reader would be more likely to eliminate the second option, but I agree that "does not compile" answers are boring. So am ultimately happy either way ;-)
@nermin: thoughts from you on this one..?
just realized that we already discussed this topic two years ago (how time passes!) in pull request #21. @nermin supported a proposal by @dgruntz to add 5 answers. And the user named @demobox proposed the answer "Fails with a compilation error or runtime exception"?
. Finally the option "runtime exception" was dropped, but for me it would be fine to replace the compilation exception
answer with the runtime exception
one.
Btw, do you have statistics on which option is clicked most?
"it will print 1 - perhaps Scala doesn't bother initializing the other one for some reason and just returns the default value instead"?
you mean that the value fields of both XY.X.value and XY.Y.value are initialized with 1 (as I explained above).
But there could be another interpretation, namely that the field of the object accessed first is initialized with 1 (default value 0 + 1), and that the field of the object accessed second is initialized with 2, i.e. that the reader realizes that the order in which the objects are accessed is irrelevant but then makes the wrong choice.
And the user named @demobox proposed the answer "Fails with a compilation error or runtime exception"?
Tee hee hee. How time passes ;-) Statistics would be very interesting, but hard to collect in the current setup because users don't "vote" for a particular answer, they simply unhide the explanation. Nice feature suggestion, though!
namely that the field of the object accessed first is initialized with 1 (default value 0 + 1), and that the field of the object accessed second is initialized with 2
That's actually also what I meant - sorry, wasn't clear there. The reasoning would be something like:
XY.X.value
firstXY.X.value refers to
XY.Y.value`. But that's not initialized yet, so we get the default value, 0Question would be: in the second step, why would the system decide not to initialize the other value?
But, in any case, I think replacing "does not compile" is probably the less boring choice, too. Just waiting to hear what @nermin has to say...
Question would be: in the second step, why would the system decide not to initialize the other value?
it is difficult to explain the wrong models readers might have in their minds. An explanation could be that the value is only initialized if it is accessed directly using the (implicit) getter method and that probably the system accesses the field directly. I have tried to demonstrate such a model with the following implementation:
object XY {
object X {
var init: Boolean = false
var value_ : Int = 0
def value : Int = { if(!init) { value_ = Y.value_ + 1; init= true }; value_ }
}
object Y {
var init: Boolean = false
var value_ : Int = 0
def value : Int = { if(!init) { value_ = X.value_ + 1; init= true }; value_ }
}
}
The first accessed field now prints 1
:
scala> XY.X.value
res0: Int = 1
scala> XY.Y.value
res1: Int = 2
scala> XY.X.value
res2: Int = 1
and that probably the system accesses the field directly
Ah, like that...bypassing the accessor. Naughty code! ;-)
I've updated the PR, in any case.
LGTM
@dgruntz @nermin: What do you think..?