Explain what `Closure` is
Opened this issue · 6 comments
I found https://github.com/reboot-dev/respect/pull/572 almost impossible to review because there is no documentation about what an ::eventuals::Closure
is. How does it differ from a ::eventuals::Then
? When do I use it?
Even a simple set of comments in closure.h
explaining why it exists would have been sufficient for me to work with it, but alas, there's no documentation of any kind, not even comments. :(
I suggest we add "what does this do, why does this exist" comments at the top of all of our files in eventuals/
- but this issue tracks the now-known-to-have-caused-pain closure.h
.
In essence, Closure
does exactly what capture lists in lambdas do. It owns some variables that you would like to use in the eventuals "enclosed" by it. Please see test/filesystem.cc
for examples.
I agree with the need for the comments or documentation. I constantly am baffled by some of the stuff that we have, especially when it's about schedulers 😄
In essence,
Closure
does exactly what capture lists in lambdas do. It owns some variables that you would like to use in the eventuals "enclosed" by it. Please seetest/filesystem.cc
for examples.
... But Closure
just takes a lambda, no additional variables. How does Closure
capture anything? How does it make things available to "enclosed" eventuals? What does it even mean for an eventual to be "enclosed" by it? Why doesn't Then
do the same thing with the identical signature?
(Just to be clear, I appreciate an explanation here, AND we should still add an explanation to the file! 😃 )
I just spent 30 minutes staring at closure.h
(and comparing it to then.h
), and I currently don't feel like I'm capable of documenting what this does or how it does it :/
One thing that looks like a key difference between the two:
Then
passes the result obtained from invoking f_(...)
into k_.Start()
, after which that result is forgotten:
Lines 126 to 133 in 1a31f7c
In contrast, Closure
stores that result in a member optional
field that persists until the eventual is destroyed:
Line 60 in 1a31f7c
But stuff I don't understand:
- What are
f_
andk_
?- not just their meanings, but also their types (why does
Then
passStart
's args to itsf_
invocation, whereasClosure
passes itsk_
to itsf_
invocation, and then it passesStart
's args to aStart
method called on the result? What arguments do each functor type expect?) - what's the return type of
f_
? What does storing it do? - is
f_
just the passed in thing, e.g. the lambda? If so, why does storing its return value make sense, and why does it affect capture lifetime?
- not just their meanings, but also their types (why does
- What arguments are passed to
Start
? - Is this comment about
Closure::k_
's lifetime wrong or misleading (sincek_
ismove()
'd intocontinuation_
, meaning thatcontinuation_
's lifetime is just as important ask_
's?) - How long do lambda captures last for?
Tentatively assigning to @benh who might be most able to help clear up our collective confusion here!
I've thrown some synchronous time on the calendar for the 3 of us to discuss this.
@benh is going to come up with an example to clarify this