On Monday 22 September 2008 18:06:25 Arthur Smyles wrote: ...
My original example
(if (values #f #f) #t #f)
doesn't work in scheme because values creates a special object that is not false so to make it work properly,
No.
The example does not work as you expect because you are expecting a different language semantics than the Scheme standard specifies.
I have to do:
(if (call-with-values (lambda () (values #f #f)) (lambda (primary . secondary) primary)) #t #f)
But if I always have to do that in order to use my function, then I might as well not use values/call-with-values and split the function into 2.
The root problems with what you suggest are [1] not all functions talk an arbitrary number of values and [2] making this change would really torque the semantics.
You are asking for ((lambda (x) (* x x)) 2 3) -> 4 (if (vaues #f 2 3 4) 1 2) -> 1
The decision that the language designers made was for safety and for compiler optimization.
The safety assumption is that an error message is more appropriate than ignoring "extra" values and filling in "missing" values.
Perhaps it is best to think of calling a function. Do you want all functions to pay the cost of a "rest" list? I.e. you wish to require the following two functions to be equivalent?
(define (double n) (* 2 n)) == (define (double n . rest) (* 2 n))
[Some languages are defined this way. I would claim that they pay a performance penalty, but that is another discussion.]
Unfortunately, the only way to use the current implementation of 'values' properly is to de-structure it using call-with-values.
In many/most common used cases a compiler can optimize this so that values are transmitted directly without the need of a procedure call or construction of a function.
I.e. (call-with-values (values 2 3) cons) can be transformed to (cons 2 3) by the compiler and even constant folded to '(2 . 3) if the compiler can "prove" from context that the cons cell is never side effected and that CONS refers to the classical binding of the cons function.
Whether or not this is done is a compiler optimization problem. [I have not looked, so don't know if Gambit currently performs this optimization. You should probably do so].
You are asking that this type of optimization never be done.
I think it is a lot to ask.
$0.02, -KenD