[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: when and unless
From: |
Chris K. Jester-Young |
Subject: |
Re: when and unless |
Date: |
Wed, 7 Dec 2011 10:58:34 -0500 |
User-agent: |
Mutt/1.5.20 (2009-06-14) |
On Wed, Dec 07, 2011 at 10:23:25AM +0100, David Kastrup wrote:
> Lilypond is not Scheme but has a more complex syntax. You can use
> Scheme in a lot of places with different implications on the grammar
> depending on the type of the expression. It would not be feasible to
> create a separate Scheme calling operator for every possible type of
> expression. And "called just for action" is one such type.
In that case, to be proper, you have to do what the REPL does, which is
to wrap the Scheme expression within a call-with-values wherever you
process the calling operator. Remember that the continuation can be a
case-lambda:
(call-with-values
(lambda () (values))
(case-lambda
(() "No return values")
((x) (format #f "Single value: ~a" x))
(x (format #f "Multiple values: ~a" x))))
(Guile 2.0 has built-in (VM-level) support for case-lambda, which makes
this super awesome.)
> Well, you'd need to have
>
> (call-with-values (lambda () *unspecified*) (lambda x (length x))) => 0
[...]
> That means that one _only_ needs to consider the implications on
> call-with-values continuations.
Correct. However, how would you detect whether you're in a context where
call-with-values is being used? Here are some things that won't work:
1. You can't walk the stack. Your void expression would be in tail
position (it would transfer to the continuation directly, not return
to call-with-values---try (call-with-values (lambda () (throw 'foo))
(lambda () 42)) and see what the backtrace looks like).
2. Guile's continuations don't provide meaningful arities: (call/cc
(lambda (k) (procedure-minimum-arity k))) always says it takes zero
or more arguments. (Same deal applies with Racket, so I presume it's
not "just a Guile quirk".)
> And it is not like Guile has a problem distinguishing content and
> package itself (at least Guile 1.8):
>
> guile> (write *unspecified*)
> #<unspecified>guile> (write (values))
> #<values ()>guile>
In Guile 2.0, multiple values is not a first-class object. Instead, it
works like Common Lisp: in any context where a single value is needed,
and multiple values are supplied, then only the first value is used,
and the rest are thrown away.
scheme@(guile-user)> (+ (values 1 2 3) (values 4 5 6))
$1 = 5
scheme@(guile-user)> (+ (values 1 2 3) (values))
ERROR: In procedure values:
ERROR: Throw to key `vm-error' with args `(vm-run "Zero values returned to
single-valued continuation" ())'.
> So I still don't quite see the problem that would arise from making
> (eq? *unspecified* (values)) => #t
Simply that (values) is not valid to pass to eq?, since eq? is a normal
function, that thus expects one value for every argument. That this may
possibly work for Guile 1.8 is simply an accident of its implementation
of multiple values.
Cheers,
Chris.
- Re: when and unless, Andy Wingo, 2011/12/05
- Re: when and unless, Marijn, 2011/12/06
- Re: when and unless, Alex Shinn, 2011/12/06
- Re: when and unless, David Kastrup, 2011/12/06
- Re: when and unless, Andy Wingo, 2011/12/06
- Re: when and unless, David Kastrup, 2011/12/06
- Re: when and unless, Andy Wingo, 2011/12/06
- Re: when and unless, David Kastrup, 2011/12/06
- Re: when and unless, Chris K. Jester-Young, 2011/12/06
- Re: when and unless, David Kastrup, 2011/12/07
- Re: when and unless,
Chris K. Jester-Young <=
- Re: when and unless, David Kastrup, 2011/12/08
- Re: when and unless, Chris K. Jester-Young, 2011/12/08
- Re: when and unless, David Kastrup, 2011/12/08
- Re: when and unless, Ian Price, 2011/12/08
- Re: when and unless, Chris K. Jester-Young, 2011/12/07
Re: when and unless, Chris K. Jester-Young, 2011/12/06
Re: when and unless, Ludovic Courtès, 2011/12/06