On 2020-10-18 5:36 pm, Matthew Fong wrote:
Hello everyone,
I am likely in over my head with nesting pairs. I read the
documentation
link from Jean, and I don't completely understand the internal
representation of this nesting in scheme.
dictHymn.HymnOne.ID = "210"
dictHymn.HymnOne.Meter = "8.8.8.8"
dictHymn.HymnTwo.ID = "344"
dictHymn.HymnTwo.Meter = "12.12.12.8"
Would it be something like:
( ( HymnOne . (( ID . 210 ) ( Meter . "8.8.8.8" )) )
( HymnTwo . (( ID . 344 ) ( Meter . "12.12.12.8" )) ) )
Yes, it ends up being an alist of alists.
assoc-get doesn't seem to work here with the syntactic sugar, likely
because I may not understand how nested pairs work.
dictHymnValue = #(ly:assoc-get 'ID dictHymn.HymnOne "error")
\markup \dictHymnValue
The dot notation I showed is part of LilyPond syntax, not Scheme.
ly:assoc-get does not support nested alists directly, so you need to
explicitly perform multiple lookups:
(NOTE: lily-library.scm defines an alias for ly:assoc-get omitting the
ly: prefix.)
%%%%
\markup #(assoc-get 'ID (assoc-get 'HymnOne dictHymn '()) "error")
\markup #(assoc-get 'Tune (assoc-get 'HymnTwo dictHymn '()) "error")
\markup #(assoc-get 'Meter (assoc-get 'HymnThree dictHymn '()) "error")
%%%%
If you end up nesting alists more deeply, it can be cumbersome to do all
of the individual assoc-get calls. Here's a recursive wrapper that
accepts a list of keys to lookup one after the other:
%%%%
#(define (assoc-get* key alist . args)
(if (and (list? key) (not (null? (cdr key))))
(apply assoc-get* (cdr key) (assoc-get (car key) alist '()) args)
(apply assoc-get (if (pair? key) (car key) key) alist args)))
foo.one.two.three.four = "!"
\markup #(assoc-get* '(one two three four) foo "?")
\markup #(assoc-get* '(one two five six seven) foo "?")
%%%%
-- Aaron Hill