My use case for using 'values' is to pass a primary value and secondary values to a caller. If the caller can only use one value then I want it to use the primary value and discard the secondary values. So what I would like to see is:
(if (values #f #f) #t #f) => #f
since the primary value is false and the 'if' function can only use the primary value.
As it stands now, as a caller of an api that uses 'values', I'd have to deal with it as a specialized data structure, in which case, the utility of it is very limited since I could just as well pass a vector or some other structure.
I think the above semantics could be implemented and still be R5 compliant.
Arthur
----- Original Message ---- From: Marc Feeley feeley@iro.umontreal.ca To: Arthur Smyles atsmyles@earthlink.net Cc: gambit-list@iro.umontreal.ca Sent: Sunday, September 21, 2008 7:35:59 PM Subject: Re: [gambit-list] strange results using values
On 21-Sep-08, at 3:25 PM, Arthur Smyles wrote:
(if (values #f) #t #f)
=> #f
(if (values #f #f) #t #f)
=> #t
I was surprised to discover this. Although technically not a bug since the scheme spec considers this situation unspecified, it makes using multiple-values unreliable.
In what way is it "unreliable"? The situation is defined as an error by the Scheme standard, which means a user cannot expect any specific behavior.
Gambit handles multiple values by treating the "values" procedure as a data structure constructor (just like "vector" except with a different type tag). The exception is that when it is given a single argument it behaves like the identity function, so (values 123) = 123 . This explains why (if (values #f #f) 11 22) gives 11, just like (if (vector #f #f) 11 22) gives 11, but (if (values #f) 11 22) = (if #f 11 22) = 22 .
This affects pp as well
(pp (values #f #f))
=> #<unknown>
What would you expect this to give? I'm not sure this is related to what you want to do, but these operations are available:
(##values? (values 11 22))
#t
(##vector->list (values 11 22))
(11 22)
(for-each pp (##vector->list (values 11 22)))
11 22
Marc
Afficher les réponses par date
On Sep 22, 2008, at 11:29 AM, Arthur Smyles wrote:
My use case for using 'values' is to pass a primary value and secondary values to a caller. If the caller can only use one value then I want it to use the primary value and discard the secondary values. So what I would like to see is:
(if (values #f #f) #t #f) => #f
since the primary value is false and the 'if' function can only use the primary value.
As it stands now, as a caller of an api that uses 'values', I'd have to deal with it as a specialized data structure, in which case, the utility of it is very limited since I could just as well pass a vector or some other structure.
I think the above semantics could be implemented and still be R5 compliant.
It sound like you want every place in the program that takes a value to check whether there are more than one value returned, and pick the "primary" one.
So if you have
(define (f a b) (+ a b))
(define (g a b) (values a b))
(f (g 0 1) 2)
you'd want the code to f to check that g returned only a single value, strip out extra ones if it returned more than 1, perhaps signal an error if g didn't return any values, do something else?
Common Lisp deals with this somehow, but I'm not sure that we want the semantics of values in Scheme to be complicated so much in able to implement such a proposal.
Brad
Arthur Smyles wrote:
My use case for using 'values' is to pass a primary value and secondary values to a caller. If the caller can only use one value then I want it to use the primary value and discard the secondary values. So what I would like to see is:
(if (values #f #f) #t #f) => #f
since the primary value is false and the 'if' function can only use the primary value.
As it stands now, as a caller of an api that uses 'values', I'd have to deal with it as a specialized data structure, in which case, the utility of it is very limited since I could just as well pass a vector or some other structure.
I think the above semantics could be implemented and still be R5 compliant.
I've once written a response to someone posting this as bug in bugzilla:
http://www.iro.umontreal.ca/~gambit/bugzilla/show_bug.cgi?id=63
I.e. I personally still think the "take first value if continuation only expects one value" approach is a bad idea.
If you're really wanting to see that behaviour, maybe you could describe the reasons in more detail and think about the issues I've lined out above; maybe there is a way to achieve both.
Christian.