[gambit-list] strange results using values

Christian Jaeger christian at pflanze.mine.nu
Mon Sep 22 16:36:16 EDT 2008


Arthur Smyles wrote:
> I've looked into your bug comment.
>
> The additional use case that I see is your example code:
>
> (let ((v (values 1 2))) (call-with-values (lambda () v) cons))
>
> It could be re-written as:
>
> (let ((v '(1 2))) (call-with-values (lambda () (apply values v)) cons))
>
> I don't see what a user-visible values structure provides when the user already has cons, vectors, and records.
>   

I don't understand your point.

My point was that the (values 1 2) would be from user code.

Example (and yes macros don't even have to be involved):

;; library code:

(define (db-transaction db thunk)
  (db-begin! db)
  (with-exception-catcher
   (lambda (e)
     (db-rollback! db)
     (raise e))
   (lambda ()
     (let ((res (thunk)))
       (db-commit! db)
       res))))

;; user code:

(define (dosomequery-with-x x)
  (db-transaction mydb (lambda ()
			 (let ((a (db-query mydb "foo" x))
			       (b (db-query mydb "bar" x)))
			   (values a b)))))

(call-with-values
    (dosomequery-with-x 1234)
  (lambda (a b)
    ...))

;; or

(let-values ((a b (dosomequery-with-x 1234)))
   ...)




The point was that the (values 1 2) would be provided by the user of the 
library. And that the user doesn't know about the implementation of the 
library. But be able to pass multiple values through the layer that the 
library might have (again, the user wouldn't necessarily be able to know 
whether the library imposes an additional layer between the continuation 
of the callback code and the continuation of the library call). And the 
library author needn't bother about multiple values either.

In this example, if Gambit were to work as you suggest, the let-values 
couldn't get at the b value.

> I see the call-with-values as a way to create multi-value continuations and values as the standard way to call them. If the continuation does not accept multiple values (any continuation not created by call-with-values) then I'd like to see it behave as if you just returned one value.
>   

I guess my and Brad's suggestions are to specify that at the call site 
explicitely.

> Unfortunately, the only way to use the current implementation of 'values' properly is to de-structure it using call-with-values. I think that is redundant since I can perform the same with a list, vector, or record.

As I said, and as has discussed many times, yes, multiple-values is kind 
of redundant.

The idea has always been that since there are multiple-value function 
entries, there should also be (as a symmetry) multiple-values function 
exits.

Now whether the current ways multiple values are being implemented solve 
that well is an open question.

Manual continuation passing style is the best pre-existing and probably 
still best current way for passing multiple "return" values; then you 
can give (lambda (a . ignore) ...) as the continuation if you don't want 
to look at the remaining values.

Christian.




More information about the Gambit-list mailing list