-
Notifications
You must be signed in to change notification settings - Fork 274
Add a lazyt class for delaying computations #5090
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 a lazyt class for delaying computations #5090
Conversation
1fed884
to
e5bf82d
Compare
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: e5bf82d).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/126077346
Codecov Report
@@ Coverage Diff @@
## develop #5090 +/- ##
===========================================
+ Coverage 69.66% 69.66% +<.01%
===========================================
Files 1319 1321 +2
Lines 109250 109269 +19
===========================================
+ Hits 76106 76125 +19
Misses 33144 33144
Continue to review full report at Codecov.
|
src/util/lazy.h
Outdated
|
||
/// Force the computation of the value. If it was already computed (even if | ||
/// \p info was different), return the same result. | ||
valuet force(infot info) |
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.
I find "force" an unintuitive name. How about "evaluate", "compute" or "force_evaluation"?
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.
force
is used by .net, scheme and ocaml https://en.wikipedia.org/wiki/Lazy_evaluation so I think it's relatively standard, but I don't know if someone encountered similar concepts in other libraries or languages?
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.
If it's a standard term then that's fine.
static lazyt from_fun(std::function<valuet(infot)> fun) | ||
{ | ||
return lazyt{std::move(fun)}; | ||
} |
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.
Why not a public constructor?
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.
I think having a static function with a name is clearer in that case, when I read lazyt::from_fun(f)
I know we use a function f
to make a lazyt
object, but lazyt(f)
is more obscure.
This generalizes a pattern for which we have several potential usage.
This tests that the force function returns the expected result and the evalution function is not called more than necessary.
e5bf82d
to
8dbbca1
Compare
@owen-mc-diffblue @danpoe following the suggestion of @LAJW I've removed the |
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: 8dbbca1).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/126233098
return s.length(); | ||
}; | ||
auto lazy_length = | ||
lazyt<int>::from_fun([&]() { return length_with_counter("foo"); }); |
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.
😊 https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/lazy-expressions
And now you could even infer return type by doing:
template<T> auto lazy(T func) -> lazyt<decltype(func())> { ... }
Also, ()
in zero-argument lambdas is optional.
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.
I'm adding it in a follow-up PR: #5101
This class is meant to be used for delaying the computation of a value to the first time we need it, but avoid recomputing it if it is needed several times.
In particular I would have found such a class useful when writing this pull request: #5078