On Sat, Apr 24, 2010 at 5:21 PM, Tobias C. Rittweiler tcr@freebits.de wrote:
Well, in the original patch it just returned the first value, and the second value is the completed/interrupted flag. That's on obvious error, so I'm attaching a new patch that returns all of the values, plus the completed interrupted flag (for a function returning (values 1 2) thread-join will now return 1, 2, T)
That strictly couples the caller with its return sites; pain that multiple values are usually supposed to obliterate from.
I think that the biggest problem with returning a status code at the end of multiple values is that if you want to write a wrapper to change the way the call operates (e.g. if you want to write a sb-thread-join that throws like the sbcl version) at some point you've got to convert the multiple values into a list, strip off the last element, and then convert the list back into multiple values -- which seems a bit inelegant.
SBCL returns the values as multiple values, and signals an error in case it couldn't join. I'm not sure what interface I'd like more. On SBCL, you pretty much always have to wrap HANDLER-CASE around join-thread which makes it unappropriate to use with MAPC.
At the project I'm currently working on, I added the following wrapper:
(defun join-thread (thread &key timeout (on-timeout :timeout) (on-failure :error)) ...)
The ON-TIMEOUT/FAILURE arguments are returned as primary results, making it potentially ambiguous (does :error come from the return value of the thread or because of a failure?); however the user can specify these values -- and the user should almost always know in what range a thread's return value is going to be -- so it's my humble opinion on how I think JOIN-THREAD should look like. :-)
This version looks very convenient to use most of the time. But it's not easy to write a generic wrapper to change the semantics without knowing the allowed return values of the underlying function. Or is it? (That's a real question!)
It could be made fully general if we add an interrupted flag to LispThread, and a function for querying it. I think that way thread-join is easy to use most of the time, but if there is uncertainty to if :error is an allowed return value you can just query the thread to see if it completed normally.
Whatever we do, we should have a timeout keyword.
I'm happy to change things, if we can agree what to change them to!
Cheers,
-david