Stephen Lewis | 16 Jun 2012 08:39
Picon
Favicon

exit continuation doesn't like multiple values

Shiro,

I tried to pass multiple values to an exit continuation and it doesn't
seem to work. Is this a bug or is this not allowed?

gosh> (gauche-version)
"0.9.2"
gosh> (define (multiple x y z)
  (call/cc
    (lambda (escape)
      (if (zero? x) 
        (escape (values 3.0 2.0 1.0))
        (values x y z)))))
multiple
gosh> (multiple 11 22 33)
11
22
33
gosh> (multiple 0 1 2)
3.0
gosh> 

I expected to get 3 values 3.0 2.0 1.0 but got only the first one.

Guile does what I expect,

guile> (version)
"1.8.8"
guile> (define (multiple x y z)
...   (call/cc
(Continue reading)

Shiro Kawai | 16 Jun 2012 10:05
Favicon

Re: exit continuation doesn't like multiple values

You should write

   (escape 3.0 2.0 1.0)

instead of 

   (escape (values 3.0 2.0 1.0))

The latter is invalid in Scheme semantics.  The expression E
in the position of (escape E) has a continuation that expects
exactly 1 value, since 'escape' is just a procedure and E is
an argument passed to it.  You pass an expression that yield
three values '(values 3.0 2.0 1.0)' in a position where one
value is expected, which makes the program incorrect.

In other words, the following two expressions should be
equivalent.

 (f <expr>) == (call-with-values (lambda () <expr>) (lambda (x) (f x)))

That said, R5RS does not state what should exactly happen when
you pass multiple values where a single value is expected,
so Guile's behavior may be considered as the implementation's
extention.  Although it looks weird w.r.t. Scheme's semantics.

(Gauche is also loose on checking number of values, for I prefer
speed to strict checking.  So you may occasionally get surprising
result when you violate the semantics of multiple values.  Recently
I started feeling it created more confusion than the benefit of
marginal speed gain, though, and I'm inclined to put more strict
(Continue reading)

Stephen Lewis | 16 Jun 2012 18:28
Picon
Favicon

Re: exit continuation doesn't like multiple values

On Fri, 15 Jun 2012 22:05:34 -1000 (HST)
Shiro Kawai <shiro <at> lava.net> wrote:

> You should write
> 
>    (escape 3.0 2.0 1.0)
> 
> instead of 
> 
>    (escape (values 3.0 2.0 1.0))
> 

Ah! Thank you for the help, I am still a novice Scheme writer.
Using '(escape 3.0 2.0 1.0)' works correctly in Gauche, Guile and Racket.
I was confused because Guile happened to do what I expected even
with invalid code.

> The latter is invalid in Scheme semantics.  The expression E
> in the position of (escape E) has a continuation that expects
> exactly 1 value, since 'escape' is just a procedure and E is
> an argument passed to it.  You pass an expression that yield
> three values '(values 3.0 2.0 1.0)' in a position where one
> value is expected, which makes the program incorrect.
> 
> In other words, the following two expressions should be
> equivalent.
> 
>  (f <expr>) == (call-with-values (lambda () <expr>) (lambda (x) (f x)))
> 
> That said, R5RS does not state what should exactly happen when
(Continue reading)

Eli Barzilay | 22 Jun 2012 20:59
Favicon
Gravatar

Re: exit continuation doesn't like multiple values

On Sat, 16 Jun 2012 Stephen Lewis <lewis+gauche <at> freeshell.org> wrote:
> 
> I tested with Racket which is more of a teaching environment and
> Racket did complain about the arity but I still did not understand
> how to fix my problem. So I am not sure an error message would have
> helped me :-(

Racket is not a teaching environment.

--

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/

Gmane