lilypond-user
[Top][All Lists]
Advanced

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

Re: scheme-question about accumulating lists of lists


From: David Pirotte
Subject: Re: scheme-question about accumulating lists of lists
Date: Sat, 20 Apr 2019 21:34:08 -0300

Hi Thomas,

> ...
> Thanks pointing me to this possibility, in my use-case I then could do:
> (define (p) (cons '(1 2 3) '(4 5 6)))
> (define l1 '(a b c))
> (define l2 '(x y z))
> (cons* l1 l2 (car (p)) (cdr (p)) '())
> =>  
> ((a b c) (x y z) (1 2 3) (4 5 6))

Yes, if you can (you mentioned the code was not yours and couldn't be
changed ...) that would be a lot cleaner, imo, and will let you use 'built-in'
scheme, guile and srfi-1 procedures that work on lists, as mentioned in my first
answer.

> > (define (blue-walk blue proc)
> >   (let loop ((blue blue)
> >              (result '()))
> >     (match blue
> >       ((a . rest)
> >        (if (pair? a)
> >            (loop rest
> >                  (cons (proc a) result))
> >            (reverse! (cons (proc (cons a rest))
> >                            result))))
> >       (()
> >        (reverse! result)))))

In the above code, I am performing an extra and therefore useless cons, here
is a correction (not a bug, but one should _always_ avoid consing whenever 
possible):

(define (blue-walk blue proc)
  (let loop ((blue blue)
             (result '()))
    (match blue
      ((a . rest)
       (if (pair? a)
           (loop rest
                 (cons (proc a) result))
->           (reverse! (cons (proc blue)
                           result))))
      (()
       (reverse! result)))))

> My guile-knowledge is mostly limited to what LilyPond needs.
> As far as I can tell (ice-9 match) isn't used in our source.
> So I need to study your `blue-walk´ from scratch.

In this particular case, match is 'convenient', but not really indispensable - 
and I
see now it's not in guile-1.8.  Here is a version that does not need match 
(though
you might not even need it if you can (cons* a b c ... '()) as you mentioned 
here
above):

(define (fox-walk fox proc)
  (let loop ((fox fox)
             (result '()))
    (if (null? fox)
        (reverse! result)
        (let ((a (car fox)))
          (if (pair? a)
              (loop (cdr fox)
                    (cons (proc a) result))
              (reverse! (cons (proc fox)
                              result)))))))

Now, if/when you (lily devs I mean, not just you of course) plan to use 2.0, 
2.2 or
3.0 (2.9.1 is it is ...) [*], it is highly recommended to use match 'everywhere'
you'd use car, cdr, cadr ... but not only, look at the "7.7 Pattern Matching"
section of a recent manual for more ...  the code is/becomes a lot more 
readable,
and match is not only extremely powerful, but also extremely fast (no figures, 
but
it's being said there is no penalty compared to using 'older' destructuring
techniques ... (referred to, among guilers, 'the car cdr hell' :))

David.

[*]     I know why the change hasn't been made, I don't expect any answer here,
        just mentioning that if/when ... (saying this so you save your energy 
and to
        avoid to start yet another conversation on this already deeply discussed
        mater among you ...)

Attachment: pgph_j8EAV2kU.pgp
Description: OpenPGP digital signature


reply via email to

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