- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
I Heart 2429
Fri, 2009-10-23, 16:35
I realize this isn't the most opportune moment to be asking for
elaborations, but if you could find a few minutes to briefly sketch out
how you diagnosed bugs #2429A/B (and to a lesser extent how you fixed
them, but I can read diffs and eventually understand them on my own) I
would drink that information like a very thirsty person who drinks
information instead of water.
Not only was I not looking in the right ballpark, I wasn't playing the
right sport. I'm not sure I was on the same plane of existence.
Fri, 2009-10-23, 19:07
#2
Re: I Heart 2429
On Fri, Oct 23, 2009 at 06:54:44PM +0200, martin odersky wrote:
> [path to 2429]
Thank you very much!
> Morale: side effects are very very tricky. It would have been much
> safer if I had done the following:
>
> Completely duplicate `original' and typecheck that. If that fails with
> an implicit failure, re-typecheck the original `original' with an
> undefined expected type.
I would like to try to encapsulate this sort of thing when it affects
super fundamental operations like tree transformations. If there is an
"obvious"/straightforward/slow way to do something and also the way we
actually do it, command line switches could selectively enable the slow
way. I imagine at least three good sized payoffs:
a) debugging
b) "documentation" because the slow simple way is usually much clearer
about what the point is, as the real way tends to become obscured by
caches and hard-to-comprehend short-circuit tests and whatall
c) sometimes -- maybe not in this case, but for sure at times -- we'll
find out that the "slow way" is immeasurably slower. Or faster.
Hi Paul,
Diagnosing was mainly done on a hunch:
- I verified that with an explicit call to the implciit evreything is fine.
- I knew that I had recently changed the implicit logic to cause a retry
on typechecking with an implicit failure with an unknow expected type, and I
knew that this change was prompted by previous prblems with NodeSeq
that manifested themselves in Lift.
So it looked like some stale symbols were left in the tree that was
attributed twice. Sure enough I forgot the reset the type and symbol
info for the tree before re-typechecking.
So I added a call to resetAttrs and that took case of 2429A. As to
2429B, it looked like resetAttrs did not quite work as it should
because it seems there were still stale symbols
in that case. I added a lot of debug code to resetAttrs and
TreePrinters to find out what went on. Then it dawned on me:
We typecheck tree `original' to give `tree', but that fails with an
implicit failure.
We reset attributes of `original' and retypecheck `original' with
unknown expected type.
But `original' still contains stale symbols.
Why?
The resetAttrs traverser only erases local symbols, that is symbols
that were defined in the tree itself. It leaves external references
alone (that's needed for generating patterns twice in
partialFunctions, for instance). But it turned out that `original'
shared the use of symbol `e' with `tree', but not its definition! So
for the purpose of resetAttrs the use of `e' was a global reference
which was left alone. I solved the problem by adding a mode to
resetAttrs in which it would unconditionally erase all symbol info,
local or not.
So the fix was small, but to find it was hard.
Morale: side effects are very very tricky. It would have been much
safer if I had done the following:
Completely duplicate `original' and typecheck that.
If that fails with an implicit failure, re-typecheck the original
`original' with an undefined expected type.
Unfortunately, it would also have been much slower.
Cheers