[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