On Sat 21 May 2011 06:59, Alex Shinn <
alexshinn@x> writes:
> (define-syntax time
> ((time expr)
> (let* ((start (current-time))
> (res expr))
> (report-time 'expr start (current-time))
> res)))
This is actually an incorrect program. If `expr' returns two values,
you want to return them to the continuation. You need:
(let ((start (current-time)))
(call-with-values (lambda () expr)
(lambda vals
(report-time 'expr start (current-time))
(apply values vals))))
> Now, you may dislike these idioms, and argue in
> particular that the first doesn't work if expr returns
> multiple values, but it works fine for users who were
> not previously using MV in that context, or perhaps
> in any of their code. And using MV at all is still a
> contentious issue for some people. There's a
> difference between providing a feature, forcing
> people to use that feature in new code, and forcing
> them to rewrite their old code to support the feature.
> We debated this and voted strongly in favor of not
> breaking existing code.
..and I think Andy is making the point that the code is already broken if MV is at all possible, or more precisely, the R5RS makes not promises about it's behavior, because multiple values are potentially not being handled by a call-with-values.
Now, I have heard why this isn't that big an issue -- that the above code is not broken *in practice* -- because apparently every major implementation wraps up multiple values into a single first-class object which can be passed around until a call-with-values detects it and de-composes it again (please correct me if I'm wrong).
So, then, it is choices made by implementors that is keeping the above code working, not the Standard, not the WG. If the WG went with "...returns unspecified VALUES", the implementors still have the CHOICE to continue what they're doing to keep the above code from breaking -- i.e. they can choose NOT to implement a non-wrapped MV implementation, and/or they can choose to return a single unspecified from set!, (if #f #f), etc.
I think if you're going to depend on the above code forever, the WG could make it officially portable, by requiring (values...) to return a single first-class object, one which can be de-composed by call-with-values, and preferably does not return #t to any standard predicate, but has no other semantics. (I am NOT recommending this, except to the extent that it makes your argument more consistent).
-jim