-
Notifications
You must be signed in to change notification settings - Fork 13
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
Handle integer overflow in for loops #60
base: master
Are you sure you want to change the base?
Conversation
(Note: the above test-case is 64-bit specific, I think it's the first one. We never discussed what's the plan for Titan in 32-bit machines, but we're using |
Codecov Report
@@ Coverage Diff @@
## master #60 +/- ##
==========================================
- Coverage 91.31% 90.76% -0.55%
==========================================
Files 9 9
Lines 1554 1559 +5
==========================================
- Hits 1419 1415 -4
- Misses 135 144 +9
Continue to review full report at Codecov.
|
Please squash the for commits into a single one when merging! Three of them were just to get everything passing on Travis. |
This solution is nice, but its consequences are far-reaching:
Also, the change in semantics is not to be taken lightly, but opening up this issue I was aware of that. If we adopt this as an optimization, is it still possble to do a portable fallback? In more concrete terms, would changing the semantics of for i = x, y, step do
k(i)
end from do -- simplified for positive step only
local i = x
while i < y do
k(i)
i = i + step
end
end to do -- simplified for positive step only
local i = x
if i <= y then
while true do
k(i)
if y - step < i then
break
end
i = i + step
end
end
end be sufficient, or are there further corner cases? |
The semantics is actually to do
to:
where |
Another big consequence is that Titan for loops would have a different semantics than Lua for loops. With respect to portability, it would also be harder to create a version of Titan that compiles down to Lua, if we ever wish do do something like that. |
We only need a portable fallback for |
Someone in the lua-l list seems to have found an alternative solution that we may check and compare with ours, although I suspect the overflow check will be cheaper, even if done in a fully portable way (with compiler intrinsics overflow checking is certainly faster). But the ongoing discussion also brought to attention the fact that the numeric for loop for floating point intervals has some nasty edge cases, too. My gut tells me to simply restrict the numeric for loop to integers; getting a for loop to have nice closed interval semantics for any values assigned to start/finish/step is hopeless, I think their semantics can only be really understood operationally, as loop that does successive floating point additions and comparisons, so we might as well require the user to just write a |
Having had used for loops with decimal steps many times over the years (in Lua and other languages) I think this is not something we can afford to discard.
The alternatives become:
Pragmatically speaking, option 1 sounds the way to go for the time being. |
Yes, that would be my choice too... it would be surprising to have nice closed interval semantics for integers, but while loop semantics for floating point, I think most people do not expect an innocent-looking
In Pyret comparing two floating point numbers ("roughnums") for equality is an error, you have two use one of a set of specialized operators where you have to explicitly supply the tolerances. |
A fine choice for a language aimed at teaching, as well! |
Test case for issue #59.