lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Changed behaviour of 'split-at' with guilev2


From: David Kastrup
Subject: Re: Changed behaviour of 'split-at' with guilev2
Date: Sun, 14 Oct 2018 12:31:10 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

Thomas Morley <address@hidden> writes:

> Am So., 14. Okt. 2018 um 11:56 Uhr schrieb David Kastrup <address@hidden>:
>>
>> Thomas Morley <address@hidden> writes:
>>
>> > Hi,
>> >
>> > I stumbled across different behaviour of 'split-at' in guilev1/2. Doing
>> > (define (foo) (write (split-at '(1 2 3) 1)))
>> > (foo)
>> > returns
>> > in guilev1
>> > #<values ((1) (2 3))>
>> > in guilev2 only
>> > (1)
>>
>> I rather think that Guilev2 just deals a bit differently with multiple
>> values, dropping additional values in scheme-only contexts with
>> single-value takers like `write'.
>
> It bombed out one of my codings, before I found the culprit.

You cannot generally _store_ multiple-value objects in Guilev2 (or
actually Scheme proper) since they are not conceptually proper objects
(C++ programmers will be reminded of references as opposed to pointers).
Basically you can only return them, and functions calling a
multiple-value returning function as the last thing they do will return
the same multiple values.

The only thing guaranteed to do anything with multiple values is
call-with-values and stuff derived from it.

The documentation states:

 -- Scheme Procedure: values arg ...
 -- C Function: scm_values (args)
     Delivers all of its arguments to its continuation.  Except for
     continuations created by the ‘call-with-values’ procedure, all
     continuations take exactly one value.  The effect of passing no
     value or more than one value to continuations that were not created
     by ‘call-with-values’ is unspecified.

     For ‘scm_values’, ARGS is a list of arguments and the return is a
     multiple-values object which the caller can return.  In the current
     implementation that object shares structure with ARGS, so ARGS
     should not be modified subsequently.

and indeed R5RS states the possible implementation of values as

(define (values . things)
  (call-with-current-continuation
    (lambda (cont) (apply cont things))))

Of course, this still requires call-with-values itself for creating a
continuation taking multiple values.  Note that the standard as well as
Guile's documentation itself states

     The effect of passing no value or more than one value to
     continuations that were not created by ‘call-with-values’ is
     unspecified.

and the Guilev1 behavior was to create a multiple-values object while
the Guilev2 behavior is to drop extra values unless the continuation is
a C API call, in which a multiple-values object does get passed.

If this is giving you a headache, rest assured that it is giving
_everyone_ a headache.

-- 
David Kastrup



reply via email to

[Prev in Thread] Current Thread [Next in Thread]