I see two fairly straightforward paths to simulating multiple returns
without breaking existing callers. Both take advantage of thread-local
state and establish one convention for the caller: before calling the
function again, every caller interested the extra return values must
ask for these extra returned values before calling the function again.
1.  Use and Abuse VarsThe multiple return idea sounds a lot like the
global errno facility used commonly in C to communicate out of band
errors that cannot be conveniently conveyed via the function's
actually return, except with namespacing to help multiple functions
cooperate for the scarce resources.  That bit of magic can be pretty
nasty and metadata usually solves the majority of cases needed to move
that auxiliary information (errno changed from a simple global
variable to a complicated macro with the advent of multi-threaded C
applications).
However, in cases that metadata simply is unavailable, one way might
be to augment the run time system with a mapping of functions to a
thread local store of this auxiliary information just like errno.
 Clojure already comes with batteries to handle this case called push-
thread-bindings.  Push-thread-bindings allows a function to
arbitrarily associate data with predetermined vars, and get-thread-
bindings provides a function to retreive the information stored in the
thread.  Then, all that would be necessary to establish multiple
returns would be to establish a dynamic var associated with each
function that wanted to be able to return multiple objects.  The
interested caller would just know to read this preveriously var
(probably via macro) to get the extra data it wanted.
The only downside is that, per the documentation, push-thread-bindings
does not handle its own housekeeping: it requires the calling function
to ensure that the thread bindings are cleaned up via pop-thread-
bindings, called in a finally block.  This, of course, is not ideal,
because the function that establishes the extra information can't be
sure when or even if its own caller will use it!  A more magical push-
thread-bindings that could clean up after itself upon thread
completion is necessary.
Essentially, it sounds like dynamic vars work basically the way you
want.  If there is a good way to garbage collect them when the thread
dies, a couple macros will make implementation relatively
straightforward.  By the way, more flexibly handling dynamic vars
seems to be part of a general goal for the future:
http://dev.clojure.org/display/design/Improve+Binding.  Directly using
the ThreadLocal class might also provide you with all the machinery
necessary to implement this idea and provide garbage collection for
free on thread completion.
2.  Use and Abuse Metadata on the FunctionSimilar to memoize, we could
store extra return values in function's own metadata via an atom that
mapped Java thread-id's to extra return values.  To return an extra
value, the function would simply grab its own metadata set an extra
return value by thread-id.  Callers wanting to access this extra data
would be provided a macro to look this value up on demand, probably
passing the function (something like (return-more! f)).  Subsequent
calls could just continually update this value.  This essentially
would emulate thread-local variables though, so the first approach is
probably preferable.
Either way, this sounds like it might be implementable via a nice
little library without having to change the language at all, with very
little namespace mucking required.
Hope that helps,Mark
On Jan 3, 12:24 pm, nchurch <[email protected]> wrote:
> > I think, I'll stop here.  You won't convince me that this approach is
> > practicable anytime soon. ;-)
>
> I certainly won't try too hard either.  I'm not questioning here
> whether it is immediately practicable to implement (maybe not, and in
> case a very long discussion) but is it potentially useful? (A shorter
> discussion.)
>
> In answer to your questions:
>
> The name of a returned value, of course, \does become part of the
> interface.  Perhaps library writers would want to have a discipline of
> using their own internal names and then passing them out in one final
> values call inside of a let.
>
> As to the second: the recursive (bar ...) call has no effect on any
> foo-values used outside of it, whether before or after.  This accords
> with our expectation for how functions work.
>
> Think of Values as a magical macro that \at \runtime reaches outside
> of the function it was used in and writes a little let inside the
> calling function's scope.  Is this possible?  I don't think so.
> Presumably it would have to be part of the language, just like Values
> is part of Common Lisp.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to