-
Notifications
You must be signed in to change notification settings - Fork 33
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
add between/3 #179
add between/3 #179
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AWESOME!! There might be a weird behaviour on the edge case of low = high = math.MaxInt64
so could you check it, please?
Other than that, this is a superb contribution. Thanks!
engine/builtin.go
Outdated
|
||
switch value := env.Resolve(value).(type) { | ||
case Integer: | ||
if value >= low && value <= high { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a minor point but it'd be better to flow to k(env)
.
The code reads well if the successful flow of control runs down the page, eliminating error cases as they arise.
https://go.dev/doc/effective_go#if
*
|
+--> Bool(false)
|
+--> Error(err)
|
v
k(env)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! I tweaked it a bit. Should we go further and put k(env) at the very end? I'm OK with either way.
engine/builtin.go
Outdated
return Delay(func(context.Context) *Promise { | ||
return Unify(value, low, k, env) | ||
}, func(context.Context) *Promise { | ||
return Between(low+1, upper, value, k, env) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When low = high = math.MaxInt64
, low+1
overflows and becomes a negative integer.
This could be solved by checking if low < high
:
if low == high { // Since we've already checked low <= high.
return Bool(false)
}
return Between(low+1, upper, value, k, env)
Or, for a better performance:
ks := make([]func(*Env) *Promise, 0, 2)
ks = append(ks, func(context.Context) *Promise {
return Unify(value, low, k, env)
})
if low < high {
ks = append(ks, func(context.Context) *Promise {
return Between(low+1, upper, value, k, env)
})
}
return Delay(ks...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I changed it to the better performance suggestion.
Before it would overflow but get caught by
if low > high {
return Bool(false)
}
but now it should completely eliminate that dead end 👍
This should be definitely in the default predicates! You can register it anywhere in Line 23 in 66a3f9f
|
Codecov Report
@@ Coverage Diff @@
## main #179 +/- ##
==========================================
- Coverage 95.95% 95.92% -0.03%
==========================================
Files 20 20
Lines 6083 6117 +34
==========================================
+ Hits 5837 5868 +31
- Misses 205 208 +3
Partials 41 41
Continue to review full report at Codecov.
|
Awesome! I added it below Compare in builtin.go and interpreter.go because it seems kind of similar to Compare 🙂 |
Added a couple extra tests using MaxInt64 👍 |
I added a few more tests. This should bring coverage up to 100% I think. |
This adds between/3 as discussed in #163.
Thanks for the advice about control flow! I tried refactoring it.
Let me know if I should make any changes and I will be happy to.
BTW, should I add this to the default predicates too?