guile-user
[Top][All Lists]
Advanced

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

Re: Macro to prepend element to list


From: Linus Björnstam
Subject: Re: Macro to prepend element to list
Date: Sat, 20 Mar 2021 19:10:06 +0100
User-agent: Cyrus-JMAP/3.5.0-alpha0-206-g078a48fda5-fm-20210226.001-g078a48fd

I see!

To be honest, this seems like a guile-1.8ism... I don't think such code would 
work for guile2 though 3. Why? Because your are mutating a pointer local to 
your procedure, not the actual data pointed to by the music property You are 
modifying the pointer to the list returned by the call, not the list where it 
is stored. 

I don't know enough lilypond, but a more standard way of doing that would be 
something like (ly:music-property-set! m 'articulations (cons  (make-music 
'ArticulationEvent 'articulation-type "staccato") (ly:music-property m 
'articulations))) (or a shorthand thereof).

More verbose, sure, but also standard scheme...

This could of course be abstracted away in some nicer way, like something I 
just pulled out of my posterior without much prior knowledge of lilypond 
(except for a fingering chart for bassoon I maintain): 

(update! (select '(note-event 'artuculations)) (lambda (p) (cons (make-music 
...) m)))

 This could be done with higher order functions and passing lambdas around 
without having to rely on macros...

-- 
  Linus Björnstam

On Sat, 20 Mar 2021, at 18:05, Jean Abou Samra wrote:
> Le 20/03/2021 à 17:04, Linus Björnstam a écrit :
> 
> > Well, mutating like that is not very common, except for maybe with alists.
> >
> > In which situations are you mutating the list like that? Usually you would 
> > build a reverse list using a recursive function and an accumulator, which 
> > can be done without set! (which has a boxing overhead).
> 
> 
> Mostly to mutate properties of LilyPond's probs (property objects).
> This works somewhat like Guile's object properties. For example, to
> add articulations on notes:
> 
> \version "2.23.1"
> 
> #(define-macro (prepend! thing lst)
>     `(set! ,lst (cons ,thing ,lst)))
> 
> addStaccato =
> #(define-music-function (music) (ly:music?)
>     (map-some-music
>       (lambda (m)
>         (if (music-is-of-type? m 'note-event)
>             (prepend! (make-music 'ArticulationEvent 'articulation-type 
> "staccato")
>                       (ly:music-property m 'articulations)))
>         #f)
>       music))
> 
> \addStaccato { c'4 d' e'8 f' g' a' }
> 
> (Output attached.)
> 
> It is also of use in so-called engravers (it's harder
> to find a simple use case for these). I guess all of this
> is so LilyPond-specific that it suits better in my personal
> libraries, and maybe upstream if I see a compelling use
> case in the code base.
> 
> Thanks!
> Jean
> 
> 
> Attachments:
> * prepend-example.ly
> * prepend-example.pdf



reply via email to

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