├── internals
├── docs
│ ├── index.md
│ ├── engravers
│ │ └── README.md
│ ├── overriding-stencils.md
│ ├── scheme-music
│ │ └── README.md
│ └── built-in
│ │ └── README.md
└── mkdocs.yml
├── lilypond
├── docs
│ ├── index.md
│ ├── functions
│ │ ├── interface.md
│ │ ├── markup-functions.md
│ │ ├── switch-languages.md
│ │ ├── music-scheme-void.md
│ │ └── list-music-expressions.md
│ └── old-stuff
│ │ └── functions
│ │ └── 01.md
└── mkdocs.yml
├── scheme
├── docs
│ ├── index.md
│ ├── conditionals
│ │ ├── case.md
│ │ ├── README.md
│ │ ├── if.md
│ │ ├── logical.md
│ │ └── cond.md
│ ├── loops
│ │ ├── do-while.md
│ │ ├── recursion.md
│ │ ├── README.md
│ │ ├── for-each.md
│ │ └── map.md
│ ├── data-types
│ │ ├── lists-and-pairs
│ │ │ ├── pair-definitions.scm
│ │ │ ├── symbol-lists.ly
│ │ │ ├── examples.ly
│ │ │ ├── README.md
│ │ │ ├── list-pair-comparison.md
│ │ │ ├── accessing-lists.md
│ │ │ ├── creating-lists.md
│ │ │ ├── creating-pairs.md
│ │ │ └── structure.md
│ │ ├── compound.md
│ │ ├── booleans.md
│ │ ├── vectors.md
│ │ ├── symbols.md
│ │ ├── numbers.md
│ │ ├── README.md
│ │ ├── custom.md
│ │ └── strings.md
│ ├── concepts.md
│ ├── quoting
│ │ ├── README.md
│ │ ├── preventing-evaluation.md
│ │ ├── unquoting.md
│ │ └── lists-and-pairs.md
│ ├── lists
│ │ ├── README.md
│ │ ├── iteration.md
│ │ ├── modifying.md
│ │ ├── extend-reverse.md
│ │ ├── filtering.md
│ │ └── accessing.md
│ ├── binding
│ │ ├── README.md
│ │ ├── local.md
│ │ ├── top-level.md
│ │ ├── letstar.md
│ │ └── let.md
│ ├── procedures
│ │ ├── README.md
│ │ ├── lambda-signatures.md
│ │ ├── parameter-types.md
│ │ ├── lambda.md
│ │ ├── binding.md
│ │ └── predicates.md
│ ├── scheme
│ │ └── README.md
│ ├── equality.md
│ ├── music-function-primer.md
│ ├── alists
│ │ ├── README.md
│ │ ├── retrieving.md
│ │ └── modifying.md
│ └── including.md
└── mkdocs.yml
├── .gitignore
├── .vscode
└── settings.json
└── introduction
├── docs
├── assets
│ └── images
│ │ ├── pairs-small.png
│ │ ├── pairs-fullsize.png
│ │ ├── pairs-random-small.png
│ │ └── pairs-random-fullsize.png
├── integrating.md
├── advanced.md
├── license.md
├── lilyponds-scheme.md
├── language.md
└── index.md
└── mkdocs.yml
/internals/docs/index.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lilypond/docs/index.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/scheme/docs/index.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/scheme/docs/conditionals/case.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/scheme/docs/loops/do-while.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/scheme/docs/loops/recursion.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/internals/docs/engravers/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/internals/docs/overriding-stencils.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/internals/docs/scheme-music/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lilypond/docs/functions/interface.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | site/
2 | .vscode/
3 | *.pdf
4 |
--------------------------------------------------------------------------------
/lilypond/docs/functions/markup-functions.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lilypond/docs/functions/switch-languages.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lilypond/docs/functions/music-scheme-void.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typewriterScrollMode.enable": false
3 | }
--------------------------------------------------------------------------------
/introduction/docs/assets/images/pairs-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uliska/lilyponds-scheme/HEAD/introduction/docs/assets/images/pairs-small.png
--------------------------------------------------------------------------------
/introduction/docs/assets/images/pairs-fullsize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uliska/lilyponds-scheme/HEAD/introduction/docs/assets/images/pairs-fullsize.png
--------------------------------------------------------------------------------
/introduction/docs/assets/images/pairs-random-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uliska/lilyponds-scheme/HEAD/introduction/docs/assets/images/pairs-random-small.png
--------------------------------------------------------------------------------
/introduction/docs/assets/images/pairs-random-fullsize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uliska/lilyponds-scheme/HEAD/introduction/docs/assets/images/pairs-random-fullsize.png
--------------------------------------------------------------------------------
/scheme/docs/data-types/lists-and-pairs/pair-definitions.scm:
--------------------------------------------------------------------------------
1 | (define a (cons 1 2))
2 | (define b (cons '(3 . 4) "5"))
3 | (define c (cons (cons 6 7) "8"))
4 | (define d (cons (cons (cons (cons (cons 1 2) 3) 4) 5) 6))
5 | (define e (cons random (random 100.0)))
6 |
--------------------------------------------------------------------------------
/scheme/docs/concepts.md:
--------------------------------------------------------------------------------
1 | # Scheme Concepts
2 |
3 | The following chapters introduce fundamental concepts of Scheme. To some extent
4 | this introduction is independent from LilyPond, as most of the concepts are
5 | general Scheme techniques. However, they are all taken from the LilyPond
6 | perspective.
7 |
8 | We start with discussing *data types*, followed by a sequence of discussions of
9 | more complex concepts and techniques.
10 |
--------------------------------------------------------------------------------
/scheme/docs/loops/README.md:
--------------------------------------------------------------------------------
1 | # Iteration and Looping Constructs
2 |
3 | Iteration and loops are fundamental programming tasks in any language. However,
4 | in Scheme iteration over lists is somewhat special, as discussed on [list
5 | iteration](../lists/iteration.html), and the general looping constructs `do` and
6 | `while` are considered somewhat unidiomatic.
7 |
8 | As list iteration and particularly recursion are very much limited without
9 | making use of custom procedures their discussion has been deferred to this
10 | chapter, after writing procedures had been introduced.
11 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/lists-and-pairs/symbol-lists.ly:
--------------------------------------------------------------------------------
1 | \version "2.19.40"
2 |
3 | one = #'(this is a symbol-list)
4 | failOne = this.is.a.symbol-list
5 |
6 | #(display "")
7 |
8 | #(display failOne)
9 |
10 | two = #'(this doesn@t work)
11 | %failTwo = this.doesn@t.work
12 |
13 | #(display "")
14 |
15 | three = #'(one false4 symbol-list)
16 | %failThree = one.false4.symbol-list
17 |
18 | four = #'(4 this seems to work)
19 | wrongFour = this.'4.seems.to.work
20 |
21 | %five = #'(one 4false symbol-list)
22 | %failFive = one.4false.symbol-list
23 |
24 | {
25 | c
26 | }
27 | #(display failFive)
--------------------------------------------------------------------------------
/scheme/docs/data-types/lists-and-pairs/examples.ly:
--------------------------------------------------------------------------------
1 | \version "2.19.40"
2 |
3 | start = 1
4 | myList =
5 | #'(1 .
6 | (2 .
7 | (3 .
8 | (4 . 5))))
9 |
10 | #(display myList)
11 |
12 | #(define (random-positions) (cons (random 5.0) (random 5.0)))
13 |
14 | #(define beam-pos 0)
15 |
16 | #(define (inc-bar-positions)
17 | (set! beam-pos (+ beam-pos 0.25))
18 | (cons beam-pos (+ beam-pos 0.5)))
19 |
20 |
21 | {
22 | \override Beam.positions = #(cons (random 5.0) (random 5.0))
23 | \once \override DynamicText.extra-offset = #(cons (random 5.0) (random 5.0))
24 | c'8 \p b a b
25 | }
--------------------------------------------------------------------------------
/introduction/docs/integrating.md:
--------------------------------------------------------------------------------
1 | # Integrating Scheme in LilyPond
2 |
3 | The second challenge is the integration of Scheme as an extension language in
4 | LilyPond input files. Actually this works quite smoothly because LilyPond's
5 | language itself is parsed in a way that is very close to Scheme. But on the
6 | other hand this affinity can be confusing to the user. I will give particular
7 | emphasis on disentangling these things by discussing Scheme always from the
8 | perspective of a LilyPond user. After the general
9 | [Scheme](../scheme.index.html) bookpart I will cover the integration of Scheme
10 | *in LilyPond* in more depth, in a bookpart dedicated to the integration of
11 | [Scheme in LilyPond](../lilypond/index.html).
12 |
--------------------------------------------------------------------------------
/scheme/docs/conditionals/README.md:
--------------------------------------------------------------------------------
1 | # Conditionals
2 |
3 | All programming languages provide constructs to choose code to execute based on
4 | some conditions. These constructs are known as *conditionals*, and Scheme is no
5 | exception to this rule. The keywords provided by Scheme are `if`, `cond` and
6 | `case`, and they are accompanied by the *logical operators/expressions* `and`,
7 | `or` and `not`.
8 |
9 | There is a conceptual difference to conditionals in other languages, though.
10 | Colloquially one would phrase the *if* conditional as “*if* a certain condition
11 | is met *then* do the following”. In Scheme, however, the conditional is a single
12 | expression, and depending on the tested condition this evaluates to one of its
13 | subexpressions. We will investigate this closer in the following chapters.
14 |
--------------------------------------------------------------------------------
/lilypond/docs/functions/list-music-expressions.md:
--------------------------------------------------------------------------------
1 | # Creating Lists of Music Expressions
2 |
3 | Using music functions is very handy to make overrides parametrical, for example using a construct like the following:
4 |
5 | ```lilypond
6 | colorGrob =
7 | #(define-music-function (grob color)(symbol? color?)
8 | #{
9 | \once \override #grob #'color = #color
10 | #})
11 |
12 | {
13 | c'
14 | \colorGrob NoteHead #red
15 | d'
16 | \colorGrob Flag #green
17 | e'8 f'
18 | }
19 | ```
20 |
21 | However, often it is necessary to wrap multiple expressions in the single music expression that a music function can return, for example
22 |
23 | ```lilypond
24 | #{
25 | \once \override NoteHead.color = #color
26 | \once \override Dots.color = #color
27 | \once \override Flag.color = #color
28 | % etc.
29 | #}
30 | ```
31 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/compound.md:
--------------------------------------------------------------------------------
1 | # Compound Data Types
2 |
3 | The data types we have seen so far was a selection of “simple” data types.
4 | These “atomic” data types can be seen as building blocks from which larger data
5 | types and objects can be composed. In the context of the “data types” chapter
6 | we are not going to discuss “objects” in the sense of real-world models but
7 | start with compound data types.
8 |
9 | Compound data types are types that have more than one atomic member. For
10 | example if you imagine a data type representing a “point” in a two-dimensional
11 | space it will have two members, namely values on both axes. In Scheme we would
12 | express this as a *pair*, which is Scheme's most fundamental compound data type.
13 |
14 | We will take a close look at *lists* and *pairs* now, and after that investigate
15 | how *custom data types* can look like in Scheme.
16 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/lists-and-pairs/README.md:
--------------------------------------------------------------------------------
1 | # Lists and Pairs
2 |
3 | *Lists* and *pairs* are the fundamental entities in Scheme programming, which is
4 | pretty natural as Scheme is a member of the
5 | [LISP](https://en.wikipedia.org/wiki/Lisp_%28programming_language%29) family of
6 | languages whose name is derived from *LIS*t *P*rocessing. We have already
7 | touched lists in the course of discussing [expressions](../expressions.html),
8 | but now we are going to have a much closer look at them. Lists are constructed
9 | from pairs, so it's actually the pair that makes the foundation of Scheme's
10 | data structures.
11 |
12 | There are so many walls one can run into with lists and pairs when one isn't
13 | perfectly clear about all the different quotes and backticks, dots and parens
14 | and how to apply all those. Therefore it is really well-spent time and energy
15 | to get one's head properly around them.
16 |
--------------------------------------------------------------------------------
/introduction/docs/advanced.md:
--------------------------------------------------------------------------------
1 | # Interacting With LilyPond Internals
2 |
3 | The third challenge is the more advanced interaction with LilyPond's internals
4 | that is possible through Scheme. LilyPond can reveal information about every
5 | object's most secret properties, and the user can interact very closely with
6 | these internals. This is the part where the average LilyPond user tends to give
7 | up and will even be more confused than informed by the helping hands given by
8 | more knowledgeable people on the mailing lists. But on the other hand this is
9 | where the true power of extending LilyPond can finally be unleashed. And: this
10 | becomes much more accessible once the user has a firm understanding of the
11 | fundamentals of Scheme and its integration in LilyPond documents.
12 |
13 | The [third part](../advanced/index.html) of this book will introduce selected
14 | topics from this field, but is less targeted at being a comprehensive guide.
15 |
--------------------------------------------------------------------------------
/scheme/docs/quoting/README.md:
--------------------------------------------------------------------------------
1 | # Quoting
2 |
3 | A very fundamental concept in Scheme is *quoting*. Unfortunately it is often
4 | made unnecessarily confusing for new users. If introduced slowly enough and
5 | digested thoroughly the idea isn't that complicated after all. But instead
6 | users are mostly confronted with it through code pasted from some helpful
7 | snippet, and when trying to modify that unknown code they are left alone with
8 | sloppily placed comments on mailing lists or ready-made corrections.
9 |
10 | Quoting is hidden beneath the keywords `quote`, `quasiquote`, `unquote` and
11 | `unquote-splicing` and their slightly confusing shorthands `'` (single quote),
12 | ` (backtick), `,` (comma) and `@` (at), combined
13 | with picky requirements regarding the placement of parens.
14 |
15 | Being thrown back to one's own experimentation and to trying to adapt other's
16 | code is a recipe for frustration in this case. Therefore we'll proceed slowly
17 | and dissect this valuable item in the Schemer's toolkit step by step.
18 |
--------------------------------------------------------------------------------
/scheme/docs/lists/README.md:
--------------------------------------------------------------------------------
1 | # List Operations
2 |
3 | Lists are maybe the most important building blocks in Scheme, and processing
4 | lists is fundamental to working with Scheme. Having a better understanding now
5 | how lists are organized we will investigate a number of higher-level operations
6 | that can be done with lists.
7 |
8 | The first topic to be covered is accessing lists and retrieving their elements
9 | beyond the basic `car` and `cdr` procedures. After that we'll investigate how
10 | to retrieve specific elements from lists and how lists can be modified. Finally
11 | we'll see how to process all elements of a list in sequence.
12 |
13 | This chapter will *not* cover all list operations comprehensively, as this is
14 | the task of the official
15 | [reference](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Lists.html#Lists).
16 | However, in order to make efficient use of the reference it is necessary to have
17 | a good understanding of the concepts, and therefore I will cover a subset of the
18 | functionality at a slower pace.
19 |
--------------------------------------------------------------------------------
/scheme/docs/binding/README.md:
--------------------------------------------------------------------------------
1 | # Binding Variables
2 |
3 | One of the bread-and-butter tasks in programming is handling variables. We
4 | already have seen predefined and custom variable definitions, but now it is time
5 | to have a closer look at the topic.
6 |
7 | We have seen that *symbols* can be used as self-evaluating *data* or as
8 | *references* to something else: the quoted symbol `'red` simply evaluates to
9 | that name while the symbol `red` evaluates to the list `(1.0 0.0 0.0)`.
10 |
11 | ```
12 | guile> 'red
13 | red
14 |
15 | guile> red
16 | (1.0 0.0 0.0)
17 | ```
18 |
19 | The usual Scheme terminology for the latter case is to say that “the name `red`
20 | *evaluates to* that list” and that “the list is *bound* to the variable/name
21 | `red`”.
22 |
23 | In the case of `red` this binding is available because it has been created
24 | explicitly somewhere in the LilyPond initialization files, but when we need our
25 | own variable name, say `violet` evaluating to `(0.5 0.0 1.0)`, we have to
26 | “create the binding” ourselves.
27 |
28 | Bindings can be created at top-level or locally, which we'll investigate in the
29 | following chapters.
30 |
--------------------------------------------------------------------------------
/scheme/docs/loops/for-each.md:
--------------------------------------------------------------------------------
1 | # Iterating Over Lists: `for-each`
2 |
3 | `for-each` is very much like `map` with one single difference: the results of
4 | the procedure are not used for anything. Concretely, `for-each` iterates over
5 | the elements of a list (or multiple lists) and applies a procedure to each,
6 | without creating a new list from the results.
7 |
8 | ```
9 | guile> (for-each display '(1 2 3 4 5 6 7 8 9))
10 | 123456789
11 | ```
12 |
13 | In this short example the procedure `display` is applied to all the numbers in
14 | the list. `display` simply prints the value to the console but doesn't evaluate
15 | to anything. So one can also say `for-each` applies the procedure only for its
16 | *side-effects*, not for its *value*.
17 |
18 | It is also possible to apply procedures that *do* evaluate to something, but
19 | that value will simply not be used, so the following example is actually
20 | useless:
21 |
22 | ```
23 | guile> (for-each symbol->string '(a b c d e))
24 | ```
25 |
26 | This will convert all the symbols in the list to strings but not *do anything*
27 | with them.
28 |
29 | Everything that is said about processing multiple lists with `map` applies to
30 | `for-each` as well.
31 |
32 | But actually `for-each` is most useful in combination with custom procedures,
33 | even more so than `map`.
34 |
--------------------------------------------------------------------------------
/introduction/mkdocs.yml:
--------------------------------------------------------------------------------
1 | # Common stuff
2 |
3 | theme:
4 | name: 'material'
5 | logo: 'assets/images/frescobaldi.svg'
6 | feature:
7 | tabs: true
8 | markdown_extensions:
9 | # - codehilite:
10 | # guess_lang: false
11 | - admonition
12 | - toc:
13 | permalink: true
14 | use_directory_urls: false
15 | extra:
16 | search:
17 | tokenizer: '[\s\-\.]+'
18 | social:
19 | - type: 'github'
20 | link: 'https://github.com/openlilylib'
21 | - type: 'wordpress'
22 | link: 'http://lilypondblog.org'
23 | plugins:
24 | - search
25 | - minify:
26 | minify_html: true
27 | - git-revision-date-localized
28 | repo_url: https://github.com/uliska/lilyponds-scheme/
29 |
30 | # Subbook specific stuff
31 | site_dir: ../site/introduction
32 | edit_uri: edit/master/introduction/docs
33 | site_name: LilyPond's Scheme
34 | nav:
35 | - Introduction:
36 | - Home: index.md
37 | - "LilyPond's Scheme": 'lilyponds-scheme.md'
38 | - Challenges:
39 | - 'Learning the Language': 'language.md'
40 | - 'Integrating in LilyPond': 'integrating.md'
41 | - 'Advanced Interaction': 'advanced.md'
42 | - 'Scheme':
43 | - Home: '../scheme/index.html'
44 | - 'Scheme in LilyPond':
45 | - Home: '../lilypond/index.html'
46 | - 'LilyPond Internals':
47 | - Home: '../internals/index.html'
48 |
--------------------------------------------------------------------------------
/internals/mkdocs.yml:
--------------------------------------------------------------------------------
1 | # Common stuff
2 |
3 | theme:
4 | name: 'material'
5 | palette:
6 | primary: 'Teal'
7 | accent: 'Teal'
8 | feature:
9 | tabs: true
10 | markdown_extensions:
11 | - codehilite:
12 | guess_lang: false
13 | - admonition
14 | - toc:
15 | permalink: true
16 | use_directory_urls: false
17 | extra:
18 | search:
19 | tokenizer: '[\s\-\.]+'
20 | social:
21 | - type: 'github'
22 | link: 'https://github.com/openlilylib'
23 | - type: 'wordpress'
24 | link: 'http://lilypondblog.org'
25 | plugins:
26 | - search
27 | - minify:
28 | minify_html: true
29 | - git-revision-date-localized
30 | repo_url: https://github.com/uliska/lilyponds-scheme/
31 | site_dir: '../site/internals'
32 | edit_uri: edit/master/internals/docs
33 | site_name: LilyPond's Scheme Internals
34 | nav:
35 | - Introduction:
36 | - Home: '../introduction/index.html'
37 | - 'Scheme':
38 | - Home: '../scheme/index.html'
39 | - 'Scheme in LilyPond':
40 | - Home: '../lilypond/index.html'
41 | - 'Advanced Interaction With Scheme':
42 | - 'Intro': 'index.md'
43 | - 'Built-in Scheme Functions': 'built-in/README.md'
44 | - 'Overriding Stencils]': 'overriding-stencils.md'
45 | - 'Scheme Engravers': 'engravers/README.md'
46 | - 'Scheme Representation of Music': 'scheme-music/README.md'
47 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/booleans.md:
--------------------------------------------------------------------------------
1 | # Booleans
2 |
3 | *Boolean expressions* are expressions that represent a “true” or ”false” value.
4 | This sounds trivial, but in fact, although *any* programming language relies on
5 | having some boolean representation , there are significant differences in how
6 | they are actually handled.
7 |
8 | Scheme has two explicit constants for true and false, namely `#t` and `#f`.
9 | They start with the `#` hash sign, therefore it has to be stressed that *in
10 | LilyPond* these constants have to be written with *two* hash signs, one for
11 | switching to Scheme and the other as part of the constant itself. This is
12 | consequent but often causes confusion:
13 |
14 | ```
15 | guile>#t
16 | #t
17 |
18 | guile>#f
19 | #f
20 | ```
21 |
22 | but
23 |
24 | ```lilypond
25 | \paper {
26 | ragged-bottom = ##t
27 | ragged-last-bottom = ##f
28 | }
29 | ```
30 |
31 |
32 | #### `#t` vs. ”A true value”
33 |
34 | We have already encountered booleans in predicates, which are procedures that
35 | evaluate to `#t` or `#f`. However, beside the two boolean *constants* there is
36 | the concept of “true value” and “false value”. Expressions that “have a true
37 | value” do *not* necessarily “evaluate to `#t`”. Rather they are everything that
38 | is not `#f`. This distinction will become important when we talk about
39 | [conditionals](../conditionals.html).
40 |
--------------------------------------------------------------------------------
/scheme/docs/procedures/README.md:
--------------------------------------------------------------------------------
1 | # Defining Procedures
2 |
3 | Procedures are the driving force of programming languages because that's where
4 | the static data is actually processed. So far we have used a number of
5 | procedures that are provided by Scheme or have been defined by Guile or
6 | LilyPond. Now we're going to “roll our own”, and that's about where the fun
7 | starts (i.e. where we start being able to achieve something useful).
8 |
9 | Procedures are created using the `lambda` expression, that is: a `lambda`
10 | expression *evaluates to a procedure*. At the core of things even the
11 | fundamental language features are expressed as evaluating expressions! This
12 | also means that procedures are *values* just like every other value in Scheme.
13 | So procedures can be used like any other value, e.g. bound to different names,
14 | stored in pairs or whatever. We will discuss this in more detail in the
15 | following chapters.
16 |
17 | There are different ways `lambda`-generated procedures handle arguments, which
18 | is important enough to warrant a dedicated chapter. Some words have to be spent
19 | on the binding of procedures to names, which is how procedures can actually be
20 | made useful. And finally we will have a closer look at a specific type of
21 | procedures: predicates. The main use of this chapter is to get some practise
22 | with writing procedures.
23 |
--------------------------------------------------------------------------------
/internals/docs/built-in/README.md:
--------------------------------------------------------------------------------
1 | # Built-in Scheme Functions
2 |
3 | LilyPond's documentation has a page "Scheme Function", which is
4 | [here](http://lilypond.org/doc/v2.18/Documentation/notation/scheme-functions)
5 | for the current stable version 2.18 and
6 | [here](http://lilypond.org/doc/v2.19/Documentation/notation/scheme-functions)
7 | for the current development version 2.19.
8 |
9 | This is a reference of an enormous number of extremely useful functions, namely
10 | all those Scheme function starting with `ly:` that provide an interface with
11 | the inner state and workings of LilyPond and a score document. Unfortunately
12 | this page is extremely difficult to digest - to a point to being barely usable
13 | as more than a *reminder* of what's available. This is mostly due to the fact
14 | that this whole page is generated from "docstrings", concise explanations
15 | stored directly in the source code. So if you are feeling dumb when reading
16 | the docs be assured that you're not alone. Usually it is only possible to get
17 | some value out of it when someone on the `lilypond-user` mailing list gives you
18 | some snippets to digest or to simply insert into your current project.
19 |
20 | The purpose of this section of the book is to provide usable explanations of the
21 | different Scheme functions, giving you the knowledge that is necessary to
22 | successfully make use of that "communication channel" into LilyPond's heart.
23 |
24 | {% credits %}{% endcredits %}
--------------------------------------------------------------------------------
/scheme/docs/binding/local.md:
--------------------------------------------------------------------------------
1 | # Local Bindings
2 |
3 | A much more interesting - but also complicated - topic is the *local* binding,
4 | which is done with the `let` expression and its relatives. The primary use
5 | case for local binding is the reuse of evaluations. When the result of a
6 | complex expression is used more than once it is more efficient and gives a
7 | cleaner input structure to create a local binding for the result and (re)use
8 | that.
9 |
10 | Colloquially spoken you can say that `let` allows you to create one or more
11 | local variables and then evaluate one or more expressions. But in fact `let`
12 | represents exactly *one* expression with some local bindings and an expression
13 | *body*. The `let` expression itself evaluates to a value that can then be used
14 | externally.
15 |
16 | With `let` we finally reach the point where the nested parentheses in Scheme can
17 | become pretty daunting, with lots of frightening and confusing error messages in
18 | the console. I remember very well how I desparately moved, removed and added
19 | random parens to make `let` expressions work, and once I managed to get them
20 | compile without errors I had no idea *why* and couldn't make use of the
21 | experience for future challenges. This was until I started understanding how
22 | consequently the expressions are structured and what each part is actually
23 | necessary for, and if you follow me through the next few chapters you will
24 | hopefully reach a comfortable level of familiarity pretty soon.
25 |
--------------------------------------------------------------------------------
/introduction/docs/license.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 |
6 |
7 | The
9 | (Plain) (Text) (And) (Music) Book is released under a Creative Commons
11 | Attribution-ShareAlike 4.0 International License.
12 |
13 | Copyright is held by Urs Liska and others, respectively by the authors of
16 | the individual chapters and sections as documented
17 |
18 | * in the “Credits” block at the bottom of each page,
19 | * through the Git history of the book which can be inspected on its [Project
20 | page](https://git.openlilylib.org/oll/book), and
21 | * through the attribution of individual lines that can be reached from the
22 | “Credits” blocks.
23 |
24 | This license applies to all texts and images as well as code examples contained
25 | in the book. If there should be any contents not fitting into that description
26 | their licensing has to be considered upon request.
27 |
28 | ---
29 |
30 | **TODO:** The credits block should contain a link to the license page and
31 | the `git blame` page for the given page ("released according to CC, but the
32 | individual copyright can be retrieved from this page").
33 |
--------------------------------------------------------------------------------
/scheme/docs/scheme/README.md:
--------------------------------------------------------------------------------
1 | # Scheme Fundamentals
2 |
3 | This main part of the book covers the fundamentals of Scheme as used in
4 | LilyPond documents. However, while it *does* give a basic explanation how
5 | Scheme code is integrated in LilyPond documents its focus is the language
6 | itself. In particular it doesn't give many examples that would make much sense
7 | in real-world documents, so if you work through the book in order you may find
8 | that part not to be real fun. However, I think that it is crucial to have a
9 | firm understanding of these fundamentals because it's exactly these that make
10 | using Scheme in LilyPond so (unnecessarily) confusing if not learned properly.
11 |
12 | If it is an issue for you having to learn the concepts without the opportunity
13 | to try them out right away I have two alternative suggestions for you. You may
14 | jump directly to the [Scheme in LilyPond](../lilypond/index.html) part. But as
15 | I won't explain the fundamental concepts there again you will need to jump back
16 | and forth to look up anything you have difficulties with. This way you will
17 | only need to read through the explanations of what you really need, but on the
18 | other hand you run the risk of neglecting some fundamental understanding.
19 |
20 | As another “offer” this part of the book provides a [Music Function
21 | Primer](music-function-primer.html), which gives you a few tools to use as
22 | building blocks in LilyPond documents. With these you can try out the Scheme
23 | concepts in actual score contexts. However, even if you intend to go that way I
24 | strongly recommend reading the next two chapters before.
25 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/vectors.md:
--------------------------------------------------------------------------------
1 | # Vectors
2 |
3 | Vectors are much like lists in that they have values separated with spaces, but
4 | their values are accessed by an "index", which is the position of the value in
5 | the vector. Indexes are zero-based, so the first position is 0 and the second
6 | is 1, and so on. The advantage that vectors have over lists is the retrieval of
7 | the values is much faster.
8 |
9 | ## Creating Vectors
10 |
11 | Like lists, vectors can be created as a literal.
12 |
13 | ```
14 | guile> #(1 "a")
15 | #(1 "a")
16 | ```
17 |
18 | Or they can be created with the procedure `vector`.
19 |
20 | ```
21 | guile> (vector 1 "a")
22 | #(1 "a")
23 | ```
24 |
25 | Note that unlike lists, the literal form of vectors (with the `#`) will assume
26 | that symbols are quoted. So...
27 |
28 | ```
29 | guile> #(a b)
30 | #(a b)
31 | ```
32 |
33 | But the procedure will not.
34 |
35 | ```
36 | guile> (vector a b)
37 | standard input:12:1: While evaluating arguments to vector in expression (vector a b):
38 | standard input:12:1: Unbound variable: a
39 | ABORT: (unbound-variable)
40 | ```
41 |
42 | ## Accessing Vectors
43 |
44 | Instead of using `car` and `cdr` as you do with lists, with vectors you use the procedure
45 | `vector-ref` and an index. (They start at zero.)
46 |
47 | ```
48 | guile> (define v #(1 "a"))
49 | guile> (vector-ref v 1)
50 | "a"
51 | ```
52 |
53 | Note that `vector-ref *will* try to evaluate any symbols in the vector, so...
54 |
55 | ```
56 | guile> (define v #(a, b))
57 | guile> v
58 | #(a, b)
59 | guile> (vectors-ref v 1)
60 | standard input:14:1: In expression (vectors-ref v 1):
61 | standard input:14:1: Unbound variable: vectors-ref
62 | ABORT: (unbound-variable)
63 | ```
64 |
--------------------------------------------------------------------------------
/lilypond/mkdocs.yml:
--------------------------------------------------------------------------------
1 | # Common stuff
2 |
3 | theme:
4 | name: 'material'
5 | palette:
6 | primary: 'Deep Purple'
7 | accent: 'Deep Purple'
8 | feature:
9 | tabs: true
10 | markdown_extensions:
11 | - codehilite:
12 | guess_lang: false
13 | - admonition
14 | - toc:
15 | permalink: true
16 | extra:
17 | search:
18 | tokenizer: '[\s\-\.]+'
19 | social:
20 | - type: 'github'
21 | link: 'https://github.com/openlilylib'
22 | - type: 'wordpress'
23 | link: 'http://lilypondblog.org'
24 | plugins:
25 | - search
26 | - minify:
27 | minify_html: true
28 | - git-revision-date-localized
29 | use_directory_urls: false
30 | site_dir: '../site/lilypond'
31 | repo_url: https://github.com/uliska/lilyponds-scheme/
32 | edit_uri: edit/master/lilypond/docs
33 | site_name: Scheme in LilyPond
34 | nav:
35 | - Introduction:
36 | - Home: '../introduction/index.html'
37 | - 'Scheme':
38 | - Home: '../scheme/index.html'
39 | - 'Scheme in LilyPond':
40 | - Home: 'index.md'
41 | - 'Switching Between Scheme and LilyPond': 'functions/switch-languages.md'
42 | - 'Music, Scheme and Void Functions': 'functions/music-scheme-void.md'
43 | - 'Interface of the functions': 'functions/interface.md'
44 | - 'Markup Functions': 'functions/markup-functions.md'
45 | - 'Creating Lists of Music Expressions': 'functions/list-music-expressions.md'
46 | - 'Old Stuff':
47 | - 'Writing Music Functions': 'old-stuff/functions/README.md'
48 | - 'Getting to Grips with Scheme in LilyPond': 'old-stuff/functions/01.md'
49 | - 'Start Doing Something Useful': 'old-stuff/functions/02.md'
50 | - 'Reusing Code': 'old-stuff/functions/03.md'
51 | - 'Recursion': 'old-stuff/functions/04.md'
52 | - 'LilyPond Internals':
53 | - Home: '../internals/index.html'
54 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/lists-and-pairs/list-pair-comparison.md:
--------------------------------------------------------------------------------
1 | # A Comparison of Pairs and Lists
2 |
3 | In an [earlier chapter](accessing-pairs.html) we created a nested pair whose
4 | `car`s were again pairs:
5 |
6 | ```
7 | guile> (define p (cons (cons (cons (cons (cons 1 2) 3) 4) 5) 6))
8 | guile> p
9 | (((((1 . 2) . 3) . 4) . 5) . 6)
10 | ```
11 |
12 | This definition is remarkably similar to a definition of a list in the previous
13 | chapter:
14 |
15 | ```
16 | guile> (define l (cons 1 (cons 2 (cons 3 (cons 4 (cons 5 (cons 6 '())))))))
17 | guile> l
18 | (1 2 3 4 5 6)
19 | ```
20 |
21 | Earlier we had visualized the structure of the nested pair in a pseudo-code
22 | manner, and now we compare that to the corresponding rendering of the list as
23 | chained pairs, and additionally the same for an improper list `(1 2 3 4 5 . 6)`.
24 |
25 | ```
26 | # Nested pair
27 | ( . 6)
28 | ( . 5)
29 | ( . 4)
30 | ( . 3)
31 | (1 . 2)
32 |
33 | # Proper List
34 | (1 . )
35 | (2 . )
36 | (3 . )
37 | (4 . )
38 | (5 . )
39 | (6 . '())
40 |
41 | # Improper List
42 | (1 . )
43 | (2 . )
44 | (3 . )
45 | (4 . )
46 | (5 . 6)
47 | ```
48 |
49 | This visualization and comparison is provided as an opportunity to get a
50 | “picture” of the structure of different list/pair-like constructs in Scheme.
51 | You can also consider the definitions in the code above, and think about how
52 | unwieldy constructs in Scheme can be managed by taking them apart one piece at a
53 | time. This is something you should regularly take your time for, then you'll
54 | eventually become really familiar with Scheme and its “way of thinking”.
55 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/lists-and-pairs/accessing-lists.md:
--------------------------------------------------------------------------------
1 | # Accessing Lists
2 |
3 | Accessing lists and retrieving their elements is really similar to handling
4 | pairs - which seems quite natural as lists are built from pairs. In this
5 | chapter we will discuss the basic procedures to access list elements.
6 |
7 | #### car/cdr Access
8 |
9 | In the previous chapter we have already seen how the `car` and the `cdr` of
10 | lists can be retrieved, and the `cadr` (and friends) shorthands are available for
11 | lists as well:
12 |
13 | ```
14 | guile> (define l (list 1 2 3 4))
15 | guile> l
16 | (1 2 3 4)
17 | guile> (car l)
18 | 1
19 | guile> (cdr l)
20 | (2 3 4)
21 | guile> (cadr l)
22 | 2
23 | guile> (cddr l)
24 | (3 4)
25 | guile> (caddr l)
26 | 3
27 | guile> (cdddr l)
28 | (4)
29 | guile> (cadddr l)
30 | 4
31 | ```
32 |
33 | Adding `d`s in the `cXXr` procedure name selects increasingly “right” parts of
34 | the list, while using an `a` as the initial letter selects the corresponding
35 | *value* at that position.
36 |
37 | One point of specific interest is the *last* element. As explained in the
38 | previous chapter *any* `cdr` variant retrieves a *list* (at least from a
39 | *proper* list), so `(cdddr l)` also returns `(4)`. In order to retrieve
40 | *values* from a list one always has to use the `a` as the first letter,
41 | equivalent to using “the car of whatever position in the list we are interested
42 | in”.
43 |
44 | As a mental exercise think about what the `cdar` of this list would be and why
45 | `(cddddr l)` returns what it returns (if you have read the previous chapter the
46 | second question should be clear).
47 |
48 |
49 | #### Other Access Options
50 |
51 | Scheme and Guile provide much more convenient ways to handle lists and their
52 | elements. However, I think these should better be discussed after you are
53 | familiar with more basic concepts. Therefore I have moved the more elaborate
54 | access methods to a [separate chapter](../../lists/index.html).
55 |
--------------------------------------------------------------------------------
/scheme/docs/lists/iteration.md:
--------------------------------------------------------------------------------
1 | # Iterating Over Lists
2 |
3 | Iterating over the elements of a list is an extremely common programming task.
4 | However, this is an area where Scheme is quite different from other languages,
5 | and its idioms are very elegant - once they are not confusing anymore. It is
6 | therefore important to really understand this topic in order to work
7 | efficiently without being constantly frustrated.
8 |
9 | Most languages approach this iteration in a `for` loop. The basic approach would
10 | be counting an index variable and accessing each list element through this
11 | index. For example in “classic” C++
12 |
13 | ```cpp
14 | int v[5] = {4,3,2,1,0};
15 | for (int i=0; i<5; i++)
16 | {
17 | printf("%d: %d", i, v[i]);
18 | }
19 |
20 | ```
21 |
22 | Of course this works, but the loop construct is semantically unrelated to the
23 | actual list iteration because it uses an independent counter variable. Moreover
24 | you are responsible yourself for not exceeding the list index. Therefore
25 | languages provide a loop construct that is closer to the list, e.g. in Python
26 |
27 | ```python
28 | values = [4, 3, 2, 1, 0]
29 | for v in values:
30 | print v
31 | ```
32 |
33 | “Modern” C++ provides an equivalent construction:
34 |
35 | ```cpp
36 | int v[5] = {4,3,2,1,0};
37 | for (int x : v)
38 | {
39 | printf("%d", x);
40 | }
41 | ```
42 |
43 | This approach makes the elements of the list available in the body of the loop.
44 | This is closer to the list semantics, and it guarantees that the actual range of
45 | list elements is used. However, the *body* of the loop is still unrelated to
46 | the list, as you could do *anything* inside.
47 |
48 | Scheme's approach is similar to Python's (and the second C++ variant) in
49 | actually iterating over the elements of a list passed as argument. But it goes
50 | one step further by *applying a procedure* to each element. There are two
51 | procedures available, differing in what they evaluate to, `map` and `for-each`
52 | which we will discuss in detail. However, as these concepts are mostly useful
53 | with custom procedures these discussion is post-poned to a [later
54 | chapter](../loops/index.html).
55 |
--------------------------------------------------------------------------------
/scheme/docs/lists/modifying.md:
--------------------------------------------------------------------------------
1 | # Modifying Lists
2 |
3 | The distinction between filtering/searching lists and *modifying* them is
4 | somewhat blurred, for reasons I will discuss more closely in a minute. You may
5 | notice that also the official reference pages about list
6 | [modification](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/List-Modification.html#List-Modification)
7 | and
8 | [searching](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/List-Searching.html#List-Searching)
9 | mix entries in a somewhat arbitrary way.
10 |
11 | I will not cover all procedures on this page but try to explain the basic
12 | behaviour. But I strongly recommend you visit the two reference pages and
13 | familiarize yourself with what is available.
14 |
15 | #### Changing a Single List Element
16 |
17 | `list-set!` is the corresponding procedure to `list-ref`:
18 |
19 | ```
20 | (list-set! )
21 | ```
22 |
23 | changes the element addressed by the (zero-based) index argument to the new
24 | value. The trailing `!` in the name indicates (by convention) that `list-set!`
25 | actually modifies the list instead of returning a copy. The expression
26 | evalulates to the new value.
27 |
28 | ```
29 | guile> (define a '(1 2 3 4 5))
30 | guile> (list-set! a 1 'b)
31 | b
32 | guile> a
33 | (1 b 3 4 5)
34 | ```
35 |
36 | You can see that if the list is bound to a variable the change is also persistent.
37 |
38 | #### Changing the Remainder of a List
39 |
40 | With `list-cdr-set!` you can change the n-th `cdr` of a list to something else,
41 | usually another list.
42 |
43 | ```
44 | guile> (define a '(1 2 3))
45 | guile> (define b '(4 5 6))
46 | guile> (list-cdr-set! a 1 b)
47 | (4 5 6)
48 | guile> a
49 | (1 2 4 5 6)
50 | ```
51 |
52 | What does happen here exactly? The procedure determines the list element at
53 | position `1`, which is the *second* element, `2`. Then it sets the `cdr` of this
54 | element to the list `b`, effectively appending the second list to the list head
55 | of the first.
56 |
57 | The same list could equally have been constructed with
58 |
59 | ```
60 | guile> (append (list-head a 2) b)
61 | (1 2 4 5 6)
62 | ```
63 |
64 | with the difference that the latter would have returned a *new* list.
65 |
--------------------------------------------------------------------------------
/scheme/docs/quoting/preventing-evaluation.md:
--------------------------------------------------------------------------------
1 | # Preventing Evaluation
2 |
3 | As we have seen in an [earlier chapter](../expressions.html) Scheme has the
4 | concept of self-evaluating expressions, which is applicable for most simple data
5 | types: `5` evaluates to `5`, `"foo"` to `"foo"`, and `#t` to `#t`.
6 |
7 | However, [symbols](data-types/symbols.html) are different as they are by default
8 | names referring to something else and evaluating to that else's value. `red`
9 | evaluates to the color definition list `(1.0 0.0 0.0)`, `random` evaluates to a
10 | procedure. However, sometimes we need to work with the names themeselves,
11 | regardless of some entity the refer to or not. We might want to express
12 | something like “hey, we want violet”, no matter how violet is constructed as a
13 | color and whether it is actually defined.
14 |
15 | In order to achieve this we can *quote* any Scheme value to prevent it from
16 | being evaluated. This is done using the `quote` procedure which is applied to a
17 | single object:
18 |
19 | ```
20 | guile> red
21 | (1.0 0.0 0.0)
22 |
23 | guile> (quote red)
24 | red
25 | ```
26 |
27 | In this case Scheme doesn't care that there is a variable `red` referring a list
28 | of three values and representing the color “red”. Scheme will also ignore that
29 | there is no color “violet” in
30 |
31 | ```
32 | guile> violet
33 | ERROR: Unbound variable: violet
34 | ABORT: (unbound-variable)
35 |
36 | guile> (quote violet)
37 | violet
38 | ```
39 |
40 | Quoting can not only be applied to symbols but (as said) to *any* Scheme value,
41 | for example procedures:
42 |
43 | ```
44 | guile> random
45 | #
46 |
47 | guile> (quote random)
48 | random
49 | ```
50 |
51 | In all these cases we are dealing with names just as names, without any notion
52 | of a content the names might be referring to.
53 |
54 | #### Shorthand Notation
55 |
56 | Using `quote` is the explicit way to quote objects, but far more often you will
57 | encounter and use the shorthand notation with a prepended single quote.
58 |
59 | ```
60 | guile> 'red
61 | red
62 |
63 | guile> 'violet
64 | violet
65 |
66 | guile> 'random
67 | random
68 | ```
69 |
70 | However, you should still be familiar with at least reading the explicit form,
71 | as Scheme may use it to format expressions that you may display for learning or
72 | debugging purposes.
73 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/symbols.md:
--------------------------------------------------------------------------------
1 | # Symbols
2 |
3 | Symbols are a double-edged thing in Scheme. While seeming completely natural
4 | they can cause substantial confusion for beginners.
5 |
6 | The [Guile
7 | reference](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Symbols.html#Symbols)
8 | states that *“Symbols in Scheme are widely used in three ways: as items of
9 | discrete data, as lookup keys for alists and hash tables, and to denote variable
10 | references.”* This sounds pretty complicated, but I hope to make that become
11 | clear soon.
12 |
13 | On a first level you can see symbols as “names for something”.
14 | Symbols are quite similar to strings in so far as they are sequences of
15 | characters - but written without additional quotation marks. And in some
16 | contexts in LilyPond they can even be used interchangeably. But still they *are*
17 | something different.
18 |
19 | First of all symbols are not self-evaluating. Earlier we learnt about
20 | self-evaluating expressions in Scheme, so for example `4` evaluates to the value
21 | `4`, and `"Hello"` evaluates to the string with content `Hello`. A symbol on the
22 | other hand doesn't evaluate to itself but always denotes something else - it is
23 | a symbol *for something*. When Scheme encounters the symbol `Hello` it will
24 | treat it as the reference to a *variable* whose *name* is `Hello` and will then
25 | evaluate to the *value* of that variable.
26 |
27 | ```
28 | guile> 4
29 | 4
30 | guile> "Hello"
31 | "Hello"
32 | guile> Hello
33 | ERROR: Unbound variable: Hello
34 | ABORT: (unbound-variable)
35 | ```
36 |
37 | In this case there is no variable with the name `Hello`, which triggers this
38 | error. But earlier we saw how that works when a respective variable exists:
39 |
40 | ```
41 | guile> red
42 | (1.0 0.0 0.0)
43 | ```
44 |
45 | `red` is a symbol (defined in LilyPond) that evaluates to the value of a
46 | variable which represents a list of three numbers.
47 |
48 | Often we need the symbol “itself” to pass along as data. To achieve this we
49 | make use of *quoting* - a way to tell Scheme that a symbol does *not* denote
50 | something else. There are two equivalent ways to express this:
51 |
52 | ```
53 | guile> (quote red)
54 | red
55 | guile> 'red
56 | red
57 | ```
58 |
59 | `quote` is a procedure that takes one argument - a symbol -, and prevents the
60 | evaluation of that symbol. This is a somewhat confusing concept, and therefore
61 | we have a dedicated section on [quoting](../quoting.html).
62 |
63 | There is much more to symbols than can be said in this short introduction, and
64 | we will come back to the topic whenever necessary. In need of more detailed
65 | information one can head for the section in the [Guile
66 | reference](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Symbols.html#Symbols).
67 |
68 | **TODO:**
69 | Presumably there are substantial aspects still missing from this page.
70 |
--------------------------------------------------------------------------------
/scheme/docs/binding/top-level.md:
--------------------------------------------------------------------------------
1 | # Top-level Bindings
2 |
3 | Like most programming languages Scheme has the concept of *scope*, which
4 | basically means that names are visible and invisible in/from certain places.
5 |
6 | *Top-level bindings* are variable definitions outside of any expression, somewhere
7 | in the input files. Bindings created on top-level are globally visible in the
8 | LilyPond files, both from and in included files as well. But of course they are
9 | only visible *after* they have been created, and it is an error to refer to them
10 | earlier in the input file. There is a notable difference that will be discussed
11 | in the context of [procedure definitions](../defining-procedures.html).
12 |
13 | In the chapter about [including](../including.html) Scheme in LilyPond we have
14 | already seen top-level bindings (or “global variables” as they are often named
15 | in other languages). As demonstrated there bindings can be created in LilyPond
16 | and in Scheme syntax, and both produce equivalent bindings
17 |
18 | ```lilypond
19 | % This is written in a LilyPond file
20 | variableA = "Hello, I'm defined in LilyPond"
21 | #(define variableB "And I'm defined in Scheme")
22 | ```
23 |
24 | Now we have *bound* two strings to the variable names `variableA`
25 | and `variableB`. Structurally the bindings are equivalent and both variables
26 | can equally be referred to using Scheme and LilyPond syntax (`\variableA` vs.
27 | `#variableA`). The only difference is in the rules for naming the variables, as
28 | one will be parsed by LilyPond and the other by Scheme/Guile. LilyPond is rather
29 | restricted with regard to identifier naming while Scheme more or less allows
30 | everything.
31 | **TODO:** Reference to LilyPond naming options (including advanced options)
32 | For example the following definition is perfectly valid in Scheme, while the
33 | LilyPond definition would fail:
34 |
35 | ```lilypond
36 | #(define f9!^¡ "What is this?")
37 |
38 | f9!^¡ = "What is this?"
39 | ```
40 |
41 | Such a variable will *not* be available through LilyPond's backslash syntax, but
42 | you can always access the actual Scheme value using the `#` hash sign:
43 |
44 | ```lilypond
45 | {
46 | c'1 \mark #f9!^¡
47 | }
48 | ```
49 |
50 |
51 | ## Special Scope in Scheme Modules
52 |
53 | As said earlier ariables defined in *LilyPond* files this way are *globally*
54 | visible also from or in included files. However, defined in *Scheme* modules
55 | there are different rules of visibility or “scope”. For now you are far from
56 | writing Scheme modules, so I'm only mentioning the fact.
57 |
58 | By default, when you bind a variable in a Scheme file using `(define)`, it is
59 | only visible from within the same module, respectively file. In order to make
60 | it available from outside one has to use `(define-public)` instead. This is an
61 | important method to hide elements that should not be accessed directly from
62 | outside.
63 |
64 | Additionally there is the concept of `(define-session-public)`, which *does*
65 | make an element publicly visible, but only for the current compilation out of a
66 | set of multiple files that are being processed.
67 |
--------------------------------------------------------------------------------
/scheme/docs/procedures/lambda-signatures.md:
--------------------------------------------------------------------------------
1 | # Alternative `lambda` Signatures
2 |
3 | In the previous chapter we discussed the creation of procedures with the signature
4 |
5 | ```
6 | (lambda ( ...) ...)
7 | ```
8 |
9 | In this each `` represents a single argument that is expected by and then
10 | available within the procedure. But this isn't the only form of specifying a
11 | procedure's *signature* in Scheme, there are two other options available,
12 | allowing for more flexibility.
13 |
14 | ---
15 |
16 | The following form allows to pass an arbitrary number of actual arguments to a
17 | procedure:
18 |
19 | ```
20 | (lambda ...)
21 | ```
22 |
23 | All arguments that follow the `lambda` expression are then wrapped into a list
24 | that is bound to the name `` within the procedure body:
25 |
26 | ```
27 | guile>
28 | ((lambda var-list
29 | (display (car var-list))
30 | (newline)
31 | (length var-list))
32 | 'one 'two 'three 'four)
33 | one
34 | 4
35 | ```
36 |
37 | The four arguments are wrapped in the list `'(one two three four)` which is
38 | available as `var-list` in the procedure. This way we can handle arbitrary
39 | numbers of arguments within a function. The first expressions in the procedure
40 | body print the first element of the argument list while the last expression
41 | determines the value of the whole expression, which is then printed on the last
42 | line of output.
43 |
44 | Please note that a) when you pass a single argument to such a procedure you
45 | *still* have to unpack it from the list, and b) there is no extra pair of parens
46 | around the variable declaration or the procedure body - it's basically `lambda`
47 | with an arbitrary number of expressions, whose first represents the name to
48 | which the argument list will be bound.
49 |
50 | ---
51 |
52 | A third form is actually a hybrid of the two others, accepting both a fixed
53 | number of named arguments plus a list of unnamed remaining ones.
54 |
55 | ```
56 | (lambda ( ... . ) ...)
57 | ```
58 |
59 | The “formals” are given as an improper list here, while the starting entries
60 | `` through `` represent individual actual arguments, while
61 | `` after the dot collects all remaining arguments in a list:
62 |
63 | ```
64 | guile>
65 | ((lambda (x y . z)
66 | (* (+ x y)
67 | (length z)))
68 | 1 2 3 4 5 6)
69 | 12
70 | ```
71 |
72 | Of course the procedure is pretty useless, but it shows how the signature works.
73 | We have two actual arguments, `x` and `y`, which are taken from the first two
74 | arguments passed to the list: `x = 1` and `y = 2`. The remaining arguments are
75 | wrapped to the list `'(3 4 5 6)` and bound to the name of `z`. The body adds
76 | `x` and `y` (= 3) and multiplies that with the number of remaining arguments
77 | (4).
78 |
79 | ---
80 |
81 | As said earlier it will rarely make sense to create a procedure using `lambda`
82 | for a single application as seen so far. I think each of these examples would
83 | have been realized simpler with “normal” expressions. Procedures are getting
84 | interesting when they are *bound* to a name and made *reusable*.
85 |
--------------------------------------------------------------------------------
/scheme/docs/binding/letstar.md:
--------------------------------------------------------------------------------
1 | # `let*` and `letrec`
2 |
3 | Creating one or more local bindings with `let` is a powerful concept, but there
4 | are cases where it is limited by the fact that the bindings are only accessible
5 | in the body of the expression.
6 |
7 | The easiest way to make the point is an example. For this we will continue to
8 | work with the expression from the previous chapters, factoring out yet another
9 | set of objects to bindings:
10 |
11 | ```lilypond
12 | dampedYellowWithLet =
13 | #(let ((color (car props))
14 | (damping (cdr props)))
15 | (list
16 | (/ (first color) damping)
17 | (/ (second color) damping)
18 | (/ (third color) damping)))
19 | ```
20 |
21 |
22 | ### `let*`
23 |
24 | Suppose we don't want to repeatedly access `color` in the expression body but
25 | rather have bindings for the RGB values that we can use like
26 |
27 | ```
28 | (list
29 | (/ r damping)
30 | (/ g damping)
31 | (/ b damping)
32 | )
33 | ```
34 |
35 | Again, in this example case this doesn't make much sense, but when real-world
36 | objects are complex it can be a crucial simplification.
37 |
38 | We might be tempted to write
39 |
40 | ```lilypond
41 | #(let ((color (car props))
42 | (r (first color))
43 | (g (second color))
44 | (b (third color))
45 | (damping (cdr props)))
46 | (list
47 | (/ r damping)
48 | (/ g damping)
49 | (/ b damping)))
50 | ```
51 |
52 | which seems like it might do the job: create three additional bindings making
53 | use of the `color` binding done previously. However, this doesn't work out:
54 |
55 | ```
56 | .../main.ly:7:2: error: GUILE signaled an error for the expression beginning here
57 | #
58 | (let ((color (car props))
59 | Unbound variable: color
60 | ```
61 |
62 | When we try to access `color` (in `(r (first color))`) that binding hasn't been
63 | created yet because all the bindings are only available when the bindings part
64 | of the expression has been completed.
65 |
66 | For this use case there is the alternative `let*`. This works like `let`, with
67 | the difference that each binding is accessible immediately, already within the
68 | bindings part of the expression. Thus the following works:
69 |
70 | ```lilypond
71 | #(let* ((color (car props))
72 | (r (first color))
73 | (g (second color))
74 | (b (third color))
75 | (damping (cdr props)))
76 | (list
77 | (/ r damping)
78 | (/ g damping)
79 | (/ b damping)))
80 | ```
81 |
82 | In fact the necessity to use the `let*` form is quite regular, and therefore
83 | many people tend to write `(let*` before thinking of the actual use case. But
84 | while this works always one should consider that the added flexibility always
85 | comes at the cost of added computation, and while this may usually be
86 | negligible it should be good practice not to use up resources without need.
87 |
88 | ### `letrec`
89 |
90 | There is another form of local binding, `letrec`. This works like `let*` with
91 | the added convenience that *all* bindings are available for *all* other
92 | bindings, regardless of the order. With this expression it is possible to
93 | create bindings that are mutually dependent. This isn't required very often,
94 | therefore I won't go into more details about it, but you should at least have in
95 | mind that this option is available.
96 |
--------------------------------------------------------------------------------
/scheme/docs/equality.md:
--------------------------------------------------------------------------------
1 | # Three Different Levels of Equality
2 |
3 | Comparing the equality of values is a regular task in programming, usually as the base for a decision. However, deciding whether two values are “equal” isn't as
4 | trivial as one might think, and different programming languages have different
5 | approaches to this question.
6 |
7 | Scheme has three different concepts of equality, represented by the three
8 | equality operators `eq?` `eqv?` and `equal?`. We will see these three again in
9 | various incarnations, as variants to different comparison operators. The exact
10 | interpretation of each level of equality is left to the discretion of the
11 | “implementation”, so everything described here is explicitly valid for [Guile
12 | Scheme](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Equality.html#Equality)
13 | only and may differ from any information you might encounter regarding MIT
14 | Scheme or Racket etc.
15 |
16 | Objects of different *type* are never equal in Scheme.
17 |
18 | ## eq?
19 |
20 | `eq?` checks for the *identity* of two objects, and the scope of that identity
21 | is very narrow in Scheme. Basically this predicate returns true if and only if
22 | the two arguments refer to the *same object in memory*, regardless of their
23 | values. This means that for a lot of comparisons `eq?` isn't applicable, but it
24 | is by far the most efficient predicate.
25 |
26 | Most importantly *symbols* with the same name *are* identical, so `(eq?
27 | 'my-symbol 'my-symbol)` will always evaluate to `#t`. Strings with the same
28 | content are, on the other hand, *not* equal in the sense of `eq?`: `(eq?
29 | "my-string" "my-string")` will always evaluate to `#f`. Consequently you should
30 | try to use symbols wherever possible to *name* things, especially keys in
31 | [association lists](alists/index.html).
32 |
33 | Booleans of the same value are identical, which can be used in decision
34 | processes: `(eq? #t (number? 2.4))` evaluates to `#t` because the evaluation of
35 | the `number?` predicate evaluates to `#t`, which is “identical” to the other
36 | `#t` argument.
37 |
38 | Another object that is unique and can be compared with `eq?` is the end-of-list
39 | element `()`: `(eq? (cdr '(1)) (cdr '(2)))` evaluates to `#t` because the `()`
40 | exists only once.
41 |
42 | **Note:** Numbers and characters *may* be `eq?` to the numbers and characters
43 | with the same content, but - according to the reference - you can't rely on
44 | that fact. So depending on the context both is possible: `(eq? 1 1) => #t` or
45 | `(eq? 1 1) => #f`.
46 |
47 | ## eqv?
48 |
49 | Numbers and characters should rather be compared with `eqv?`. This doesn't look
50 | for *identity* but for *equivalence* of the compared objects - for numbers and
51 | characters. For all other data types `eqv?` behaves the same as `eq?`, which
52 | should not be used regularly since: `(eq? '(1 . 2) '(1 . 2))` evaluates to `#f` even
53 | if the pairs have the same content.
54 |
55 | ## equal?
56 |
57 | For all cases except the ones mentioned above `equal?` should be used - which is
58 | the least strict but also the most “expensive” procedure. In the case of
59 | compound data types `equal?` checks for equivalent content recursively, walking
60 | over the individual elements and comparing their content. So all these
61 | expressions evaluate to `#t`:
62 |
63 | ```
64 | (equal? "a-string" "a-string")
65 | (equal? '(1 . 2) '(1 . 2))
66 | (equal? (list 1 2 3 4) (list 1 2 3 4))
67 | ```
68 |
69 |
70 | **TODO:** Investigate and discuss the difference between `=` and `eqv?` or
71 | **`string=?` and `equal?`.
72 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/numbers.md:
--------------------------------------------------------------------------------
1 | # Numbers
2 |
3 | Numbers are ubiquituous in computing, and according to the [Guile
4 | reference](https://www.gnu.org/software/guile/manual/html_node/Numbers.html#Numbers)
5 | there is a whole lot of aspects that can be discussed about them. However, for
6 | LilyPond users there is not that much required information to begin with.
7 | Scheme supports many different number types, but for LilyPond use, integers and
8 | real numbers are usually sufficient.
9 |
10 | To check if a value is a number we can use the predicate `number?`
11 |
12 | ```
13 | guile> (number? 4.2)
14 | #t
15 |
16 | guile> (number? "Hi")
17 | #f
18 | ```
19 |
20 | ## Integers
21 |
22 | Integers, or whole numbers, are written as they are, `5`, `-12` or `1234`. If
23 | written in a LilyPond file they *can* be prepended with the `#` sign or written
24 | literally, so `#13` is equivalent to `13`
25 |
26 | ```lilypond
27 | \paper {
28 | min-systems-per-page = 5
29 | max-systems-per-page = #7
30 | }
31 | ```
32 |
33 | If arithmetic operations are performed on integers the results are integers as well:
34 |
35 | ```
36 | guile> (+ 123 345)
37 | 468
38 |
39 | guile> (* 4 5)
40 | 20
41 | ```
42 |
43 | The predicate for integers is `integer?`
44 |
45 |
46 | ## Real and Rational Numbers
47 |
48 | Real numbers are all the non-integer numbers, in computing often referred to as
49 | floating-point numbers. Rational numbers are a subset thereof, namely all
50 | numbers that can be expressed as a fraction of integers. Fractions are written
51 | as two integers separated by a slash, without any whitespace in between.
52 |
53 | ```
54 | guile> (real? 1.20389175)
55 | #t
56 |
57 | guile> (fraction? 5/4)
58 | #t
59 |
60 | guile> (fraction? 1.25)
61 | #f
62 | ```
63 |
64 |
65 | #### Mixing Reals, Rationals and Integers
66 |
67 | Above we said that arithmetic operations on integers produce integers again.
68 | However, if only *one* operand is a real number the whole expression gets
69 | converted to reals:
70 |
71 | ```
72 | guile> (+ 3 1.0)
73 | 4.0
74 | ```
75 |
76 | When integers are divided Scheme will express the result as a fraction that is
77 | shortened as much as possible, but as soon as one real number is involved the
78 | fraction is converted to a floating point number:
79 |
80 | ```
81 | guile> (/ 4 2)
82 | 2
83 |
84 | guile> (/ 10 4)
85 | 5/2
86 |
87 | guile> (/ 4 3)
88 | 4/3
89 |
90 | guile> (/ 4 3.0)
91 | 1.33333333333333
92 | ```
93 |
94 | #### Exact and Inexact Numbers
95 |
96 | Integers and fractions are always *exact* values that can be recalculated as
97 | often as desired, giving always the same result. Real numbers on the other hand
98 | are *inexact* as they are subject to an arbitrary *precision* as implemented by
99 | the programming language system. This means that when performing mathematical
100 | operations with real numbers one has to expect the possibility of rounding
101 | errors. Generally this is not an issue when using Scheme in LilyPond, but it
102 | should be noted that there *is* this issue.
103 |
104 | ## Calculations With Numbers
105 |
106 | In order to learn what operations can be done with numbers in Scheme it may be a
107 | good idea to familiarize oneself with the documentation on
108 | [integers](https://www.gnu.org/software/guile/manual/html_node/Integers.html#Integers)
109 | and
110 | [reals](https://www.gnu.org/software/guile/manual/html_node/Reals-and-Rationals.html#Reals-and-Rationals).
111 | Diving into these pages *now* may also be a good test on how to handle the
112 | reference style of the GNU Guile Manual.
113 |
--------------------------------------------------------------------------------
/scheme/docs/quoting/unquoting.md:
--------------------------------------------------------------------------------
1 | # Unquoting
2 |
3 | OK, we have seen the quoted and the explicit syntax to create lists and pairs,
4 | the difference being that in the `list` approach the elements are evaluated:
5 |
6 | ```
7 | guile> '(red random 1)
8 | (red random 1)
9 |
10 | (list red random 1)
11 | ((1.0 0.0 0.0) # 1)
12 | ```
13 |
14 | But quite often one needs a list where *some* elements are taken literally while
15 | others should be evaluated. Consider the previous example and imagine that with
16 | `random` we don't want to refer to the procedure of that name, but instead read
17 | it as, say, an option name, e.g. one out of a list of `'random`, `'sorted` and
18 | `'weighted`.
19 |
20 | The most straightforward approach would be to create the list using `list` and
21 | individually quote the element that needs it:
22 |
23 | ```
24 | guile> (list red (quote random) 1)
25 | ((1.0 0.0 0.0) random 1)
26 | guile> (list red 'random 1)
27 | ((1.0 0.0 0.0) random 1)
28 | ```
29 |
30 | But Scheme offers an alternative approach for this that you will encounter quite
31 | often:
32 |
33 | ## Quasiquoting
34 |
35 | In addition to `quote` Scheme has the procedure `quasiquote`. On first sight it
36 | does the same as `quote`, namely it quotes an object. As with `quote` there is
37 | also a shorthand notation available that is usually used in input files, the
38 | backtick `.
39 |
40 | ```
41 | guile> (quasiquote (red random 1))
42 | (red random 1)
43 |
44 | guile> `(red random 1)
45 | (red random 1)
46 | ```
47 |
48 | So here the list elements are quoted as well. The difference is that with
49 | `quasiquote` it is possible to *unquote* individual elements within the object.
50 |
51 | ## Unquoting
52 |
53 | *Unquoting* an element, that is, forcing this specific element to be evaluated,
54 | is achieved using `unquote` or its shorthand notation, the comma:
55 |
56 | ```
57 | guile> (quasiquote ((unquote red) random 1))
58 | ((1.0 0.0 0.0) random 1)
59 |
60 | guile> `(,red random 1)
61 | ((1.0 0.0 0.0) random 1)
62 | ```
63 |
64 | In this example we have (quasi)quoted the expression as a whole but explicitly
65 | unquoted the `red` element. You can see that `red` is evaluated while `random`
66 | is read as a name.
67 |
68 | Note that I have used the written and shorthand notations consistently within
69 | each expression, but that is *not* necessary, the shorthand forms can freely be
70 | mixed with the verbal ones, like e.g. `(quasiquote (,red random 1))`.
71 |
72 | ## Unquoting a List
73 |
74 | When unquoting an element that happens to be a list this list is inserted into
75 | the surrounding list as a single item, such as
76 |
77 | ```
78 | guile> `(1 2 ,(list 3 4) 5)
79 | (1 2 (3 4) 5)
80 | ```
81 |
82 | However, there are many occasions where you will want the individual items of
83 | that list to be inserted in the resulting list. This can be achieved with the
84 | `unquote-splicing` syntax or its shorthand “comma-at” `,@`:
85 |
86 | ```
87 | guile> `(1 2 ,@(list 3 4) 5)
88 | (1 2 3 4 5)
89 | ```
90 |
91 | To be more concrete, in a quasiquoted expression `unquote-splicing` takes any
92 | Scheme expression that evaluates to a list and inserts the elements individually
93 | in the surrounding list.
94 |
95 | ## Nesting `quasiquote` Levels
96 |
97 | It is possible to nest multiple levels of quoting and unquoting, but we won't
98 | discuss this in more detail as it is not regularly used in LilyPond. But you may
99 | want to keep that fact in mind, in case you encounter a complicated quoted
100 | expression and unquoting doesn't seem to do its job.
101 |
--------------------------------------------------------------------------------
/scheme/docs/lists/extend-reverse.md:
--------------------------------------------------------------------------------
1 | # Extending and Reversing Lists
2 |
3 | The title of this section is a little bit misleading as the discussed procedures
4 | do not actually *modify* the lists but return a modified *copy* of the original
5 | list(s). However, they are nevertheless very useful in common programming
6 | tasks.
7 |
8 | ## Appending Lists to Lists
9 |
10 | `append` takes (at least) two lists and returns a new list that concatenates
11 | them:
12 |
13 | ```
14 | guile>(define a '(1 2 3))
15 | guile>(define b '(4 5 6))
16 | guile>(define c '(a b c))
17 | guile>(append a c b)
18 | (1 2 3 a b c 4 5 6)
19 | ```
20 |
21 | Note that the lists defined as `a`, `b` and `c` are not changed through these
22 | operations. In order to make use of the resulting list you will have to bind it
23 | to something else:
24 |
25 | ```
26 | guile>(define c (append a b))
27 | guile>c
28 | (1 2 3 4 5 6)
29 | ```
30 |
31 | ### Appending a Single Element to a List
32 |
33 | Of course it is possible to append single elements to a list, and in fact this
34 | is a very common task. However, there is a caveat that can lead to a very
35 | typical error:
36 |
37 | ```
38 | guile> (append '(1 2 3) 4)
39 | (1 2 3 . 4)
40 | ```
41 |
42 | Appending a single element seems to create an *improper list!* But if we take a
43 | step back and consider what actually happens when lists are concatenated it is
44 | clearly correct behaviour.
45 |
46 | We know that lists in Scheme are chained pairs, with the `car` of each pair
47 | holding the data of the element and the `cdr` pointing to the next element's
48 | pair. The last element of a proper list is also a pair, with the `cdr` being the
49 | *empty list* `()`. What `append` actually does is pointing that trailing empty
50 | list to the appended list, making the first element of the second list a natural
51 | member of the first. Consequently, when we append the simple value `4` to a list
52 | the `cdr` of the last list element *becomes* `4` - making the first list an
53 | improper list.
54 |
55 | Fortunately the “solution” is very easy - just something one tends to forget
56 | most of the time. “`append` takes (at least) two lists” is what I wrote at the
57 | top, and you have to take that literally: you need a *list*, even if it consists
58 | of only one element. So the proper way would have been to write
59 |
60 | ```
61 | guile>(append '(1 2 3) '(4))
62 | (1 2 3 4)
63 | ```
64 |
65 | **NOTE:** As an exercise you can figure out how to achieve that result by not
66 | appending a *list* but a *pair*.
67 |
68 | ## Reversing Lists
69 |
70 | As with the above `reverse` does not change the list itself but returns a new
71 | list with the same elements in reverse order. The behaviour is not surprising at
72 | all:
73 |
74 | ```
75 | guile>(reverse '(1 2 3 4))
76 | (4 3 2 1)
77 | ```
78 |
79 | Apart from simply reverting the order of a complete list `reverse` can be made
80 | useful for accessing list elements from the end. For example the second-to-last
81 | element of a list with unknown length can be accessed through `(second (reverse
82 | '(1 2 3 4)))` (which would evaluate to `3`). The same result could be achieved
83 | using `(list-ref '(1 2 3 4 ) (- (length '(1 2 3 4)) 2))`, but apart from needing
84 | to refer to the list *twice* this may be semantically less straightforward, and
85 | often you'd prefer juggling with reversed lists. As another example you can
86 | retrieve all the elements of a list *except the last* through
87 |
88 | ```
89 | guile> (reverse (cdr (reverse '(1 2 3 4))))
90 | (1 2 3)
91 | ```
92 |
93 | First we reverse the list, then we apply `cdr` (giving us all elements except
94 | the first one (i.e. the last one of the original list)), and finally we reverse
95 | the order again. As an exercise you should try achieving the same result using
96 | `list-head`.
97 |
--------------------------------------------------------------------------------
/scheme/docs/procedures/parameter-types.md:
--------------------------------------------------------------------------------
1 | # Handle Different Parameter Data types
2 |
3 | At several places we have seen that Scheme doesn't enforce types for procedure
4 | arguments but that (naturally) certain procedure applications may only work with
5 | certain types, e.g. numbers or strings. So while the following procedure `double`
6 | can be invoked with parameters of arbitrary type everything except numbers will
7 | cause errors:
8 |
9 | ```lilypond
10 | #(define (double x)
11 | (+ x x))
12 | ```
13 |
14 | But with everything we know by now about types, predicates and local binding we
15 | can rewrite this procedure in a robust manner. Concretely, what we want to
16 | achieve is: if `x` is a number we create the double, if it is a string that
17 | represents a number then first convert it and then double it, but return it as a
18 | string again. Finally, if it is a string that can't be converted to a number
19 | then it should be “doubled” in the way some other languages understand it:
20 | concatenating the string to itself. Finally we need a fallback action if it is
21 | neither a string nor a number.
22 |
23 | The requirement of two specific cases plus a fallback suggests to use the `cond` conditional:
24 |
25 | ```
26 | (cond
27 | (number: just double it)
28 | (string:
29 | (if it can be converted to a number:
30 | convert, double, return back
31 | )
32 | (else concatenate)
33 | )
34 | (else: report an error)
35 | )
36 | ```
37 |
38 | Leaving out the more complex handling of the string this looks like this in LilyPond:
39 |
40 | ```lilypond
41 | #(define (double x)
42 | (cond
43 | ((number? x)
44 | (+ x x))
45 | ((string? x)
46 | "not implemented yet")
47 | (else
48 | "'double' needs a number or a string as parameter")))
49 | ```
50 |
51 | To implement the string handling we have to know the procedure `string->number` that will return a number - or `#f` if the conversion fails. This is exactly what we need. We could now do something like:
52 |
53 | ```
54 | (if (string->number x)
55 | (string->number y)
56 | ... else clause)
57 | ```
58 |
59 | but that looks inefficient because the conversion is actually processed twice.
60 | Now (as we have seen) this is exactly the use case for local binding: we bind
61 | the result of that procedure to a local variable, and if that has a true value
62 | we use it, otherwise do the alternative concatenation:
63 |
64 | ```lilypond
65 | #(define (double x)
66 | (cond
67 | ((number? x)
68 | (+ x x))
69 | ((string? x)
70 | (let ((num (string->number x)))
71 | (if num
72 | (number->string (+ num num))
73 | (string-append x x))))
74 | (else
75 | "'double' needs a number or a string as parameter")))
76 |
77 | #(display (double 3))
78 | #(newline)
79 | #(display (double "3"))
80 | #(newline)
81 | #(display (double "A"))
82 | #(newline)
83 | #(display (double '(2 . 3)))
84 | ```
85 |
86 | If the string can be converted to a number this value will be doubled and
87 | converted back to a string, otherwise the original input string is taken and
88 | concatenated to itself. Now the invocations correctly return `6`, `6` (as a
89 | string), `AA` and the error string.
90 |
91 | A perfect exercise would now be to extend that procedure to handle the last
92 | invocation as well: if the parameter is a pair holding two numbers we return a
93 | pair with the numbers doubled each.
94 |
95 | ---
96 |
97 | This is the general approach to handle variable parameter types in Scheme. If
98 | you don't know what type the input parameter will have and your procedure body
99 | has to care about types then you can block or choose within the procedure body
100 | using built-in or custom predicates.
101 |
--------------------------------------------------------------------------------
/lilypond/docs/old-stuff/functions/01.md:
--------------------------------------------------------------------------------
1 | # Music Functions 1: Getting to Grips with Scheme in LilyPond
2 |
3 | With this post I intend to start a series of posts introducing writing Scheme music functions in LilyPond input files. Please note that this is not a guru's wisdom poured into blog posts but rather a documentation of my own thorny learning process.
4 |
5 |
6 | #### The First Basic Scheme Function
7 |
8 | Now we're going to write our first *music function* as described in the [Extending](http://www.lilypond.org/doc/v2.18/Documentation/extending/music-functions.html) manual. Actually it will be a quite useless function but at least it will work - and hopefully get you an understanding how to do it.
9 | But let's start with doing it the normal LilyPond way:
10 |
11 | ```lilypond
12 | \version "2.18.0"
13 |
14 | myFunction = { c2 }
15 |
16 | \relative c' {
17 | c4 \myFunction c
18 | }
19 | ```
20 |
21 |
22 |
23 | Here we define a variable with the (unusual) name of `myFunction`, which we can later insert in the main music expression. As you can see it will insert a half note `c` into the music. But as you can also see it does so without affecting the parser - the next note will be a quarter note again, referencing the previous duration *encountered in the source code*.
24 |
25 | Now we'll do the same with a Scheme music function:
26 |
27 | ```lilypond
28 | mySchemeFunction =
29 | #(define-music-function (parser location)()
30 | #{
31 | c2
32 | #})
33 |
34 | \relative c' {
35 | c4 \mySchemeFunction c
36 | }
37 | ```
38 |
39 | First we define a LilyPond variable `mySchemeFunction` and assign it - a Scheme expression (as you can see from the hash with consecutive parentheses). This expression consists of four parts:
40 |
41 | - The keyword `define-music-function`
42 | This isn't a Scheme keyword but a function defined by LilyPond. As the name suggests it defines a “music function”, which is a function that *returns some music*. And as such it can be *used* like a music expression as you see it in the last line of the example. The following three items are the arguments `define-music-function` expects.
43 | - The list of arguments
44 | the two arguments `parser` and `location` are mandatory, and as long as you won't need to make use of the information in them you can just forget about them and type it out for each music function you define.
45 | If you want your function to process individual arguments (which we'll see in a later post) you will add telling names to this list, for example `(parser location slope)` for one additional argument.
46 | - The *types* of your individual arguments.
47 | In the example given for `slope` you would add a type (or “predicate”) here, e.g. `(number?)`, but in the example we used you have to provide an empty pair of parens.
48 | - The actual music expression to be returned
49 | As we've said a music function returns a music expression. Scheme functions generally return what the evaluation of the last expression produces, so this is where we have to do it. Instead of having to write some Scheme code producing a LilyPond music expression (for which we don't have any means so far) we fortunately can use the `#{ ... #}` construct which allows us to switch to LilyPond mode within Scheme code. Concretely this means the section enclosed in the hash+curly braces is treated as one Scheme expression but can be written with LilyPond code. In our case this returns a music expression with the content of `c2`. So our whole music function returns `{ c2 }`. And so our second example produces exactly the same result as the first one: `{ c4 c2 c4 }`.
50 |
51 | Of course it doesn't make much sense to write a function that returns a hard-coded value. But I think it was a good example to understand the first steps of integrating LilyPond and Scheme code. And I promise that in the next post we'll do something useful.
52 |
53 | {% credits %}{% endcredits %}
54 |
--------------------------------------------------------------------------------
/introduction/docs/lilyponds-scheme.md:
--------------------------------------------------------------------------------
1 | # LilyPond's Scheme
2 |
3 | LilyPond uses *Scheme* as its extension language, OK. But it has to be noted
4 | that this is only half of the story, and in order not to get confused it's
5 | crucial to have a clear idea of what this actually means.
6 |
7 | ## *Why* An Extension Language?
8 |
9 | LilyPond adheres to the concept of compiling plain text input files. This makes
10 | it possible to include compiler instructions beyond the basic *contents* in the
11 | files, and these are written using an *extension language*. Programs could use
12 | arbitrary languages or even invent their own, but in LilyPond's case it was a
13 | natural choice to use Scheme, as it is the official extension language of
14 | [GNU](http://gnu.org), GNU LilyPond's parenting organization and application
15 | framework.
16 |
17 | LilyPond's internal architecture is also based heavily on Scheme, and as a
18 | consequence you can interact with LilyPond's internals the same way, as a
19 | developer working on LilyPond *or* a user writing input files. This makes the
20 | potentials of the extension language so incredibly powerful.
21 |
22 | ## *What* Is Scheme?
23 |
24 | Scheme is a programming language from the
25 | [Lisp](https://en.wikipedia.org/wiki/Lisp_%28programming_language%29) family of
26 | languages, which adhere to the paradigm of [functional
27 | programming](https://en.wikipedia.org/wiki/Functional_programming). This is
28 | very different from the concept of [imperative
29 | programming](https://en.wikipedia.org/wiki/Imperative_programming#History_of_imperative_and_object-oriented_languages)
30 | which the majority of (non-professional) programmers is more familiar with and
31 | which is present in languages like Python, JavaScript or (Visual) BASIC, Java or
32 | the C family of languages. This makes getting in touch with Scheme challenging
33 | for many potential users.
34 |
35 | ## *Which* Scheme?
36 |
37 | It is important to note that *Scheme is not (necessarily) Scheme*, as there are
38 | many Scheme
39 | [implementations](http://community.schemewiki.org/?scheme-faq-standards#implementations)
40 | around. In real life this means that when you search for “Scheme” solutions on
41 | the internet you have to expect results that may not be (completely) compatible
42 | with LilyPond. If you are not fully aware of that fact looking for help on the
43 | net can be quite off-putting.
44 |
45 | The Scheme implementation used by LilyPond is the one included in [Guile
46 | 1.8](http://www.gnu.org/software/guile/), which is the official application
47 | platform and extension language of the [GNU](http://gnu.org) operating and
48 | software system *(please note that Guile 1.8 is not the current version of
49 | Guile, so even web searches for “Guile Scheme” may bring up incompatible
50 | results)*. Therefore the official resource for any questions is the [GNU Guile
51 | Reference Manual](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/),
52 | especially the [API
53 | reference](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/API-Reference.html#API-Reference).
54 | But it has to be said that this documentation is suited rather as a *reference*
55 | if you are already experienced with Scheme.
56 |
57 |
58 | Apart from this the only trustworthy resources for Scheme *in LilyPond* are the
59 | [LilyPond manual](http://lilypond.org/doc/v2.18/Documentation/extending/), this
60 | book, tutorials on [Scores of Beauty](http://lilypondblog.org) or the
61 | [lilypond-user](https://lists.gnu.org/mailman/listinfo/lilypond-user) mailing
62 | list.
63 |
64 |
65 | ## *How* To Use Scheme in LilyPond?
66 |
67 | Learning to use Scheme in LilyPond causes challenges on three layers:
68 |
69 | * learning the language,
70 | * integrating Scheme code in LilyPond code, and
71 | * (advanced) interaction with LilyPond internals through Scheme.
72 |
73 | The following pages will flesh this out somewhat more detailed, while the rest
74 | of the book will provide an idea about the “look and feel” of writing Scheme in
75 | LilyPond. Selected language characteristics are introduced slowly and
76 | thoroughly, while at the same time discussing how Scheme code can painlessly be
77 | mixed with LilyPond input code. The higher mysteries of advanced interaction
78 | with LilyPond internals are deferred to a later bookpart.
79 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/README.md:
--------------------------------------------------------------------------------
1 | # Scheme Concepts
2 |
3 | The following chapters introduce fundamental concepts of Scheme. To some extent
4 | this introduction is independent from LilyPond, as most of the concepts are
5 | general Scheme techniques. However, they are all taken from the LilyPond
6 | perspective.
7 |
8 | We start with discussing *data types*, followed by a sequence of discussions of
9 | more complex concepts and techniques.
10 |
11 | # Data Types
12 |
13 | When talking to a computer there's no room for ambiguity. Approaching a
14 | computational task with irony is almost bound to fail, as the programming
15 | language will always want to know what it really *is* you are talking about.
16 | Therefore in programming languages each value has a *type*, and this is not
17 | different in Scheme. If a function processes a number you have to *give* it a
18 | number, sometimes you even have to make a difference between, say, integer and
19 | real numbers, e.g. between `1` and `1.0`. And so on.
20 |
21 | Scheme is extremely flexible and permeable with regard to type. If you have an
22 | expression like
23 |
24 | ```
25 | (some-procedure arg1 arg2)
26 | ```
27 |
28 | then Scheme will not check in any way what types the values `arg1` and `arg2`
29 | have. Any type mismatch will only become visible upon the procedure application
30 | within the expression:
31 |
32 | ```
33 | guile> (+ "1" "2")
34 | ERROR: In procedure +:
35 | ERROR: Wrong type argument in position 1: "1"
36 | ABORT: (wrong-type-arg)
37 | ```
38 |
39 | You can compare this behaviour with other programming languages. In “strongly
40 | typed” languages like Java or C++ the function interface would already act as a
41 | shield against arguments with wrong types. The `"1"` and `"2"` wouldn't even
42 | reach the `+`, so to say. Other languages, like e.g. Python or JavaScript will
43 | try to make the best out of it. In the example they would both *concatenate* the
44 | two digits and return `"12"`.
45 |
46 | So Scheme doesn't check the type of an argument passed into an expression but
47 | doesn't do anything to help with improper types either. This is an important
48 | characteristic because instead of the three literal elements the expression
49 | could equally consist of expressions themselves whose resulting type will only
50 | be known at runtime:
51 |
52 | ```
53 | ((return-a-procedure) (return-arg1) (return-arg2))
54 | ```
55 |
56 | So Scheme is open for very elegant and concise dynamic programming tricks.
57 | Admittedly this is still pretty abstract. What you should remember at *this*
58 | point is that the type of an expression's elements is not enforced by Scheme,
59 | but that passing arguments of unsuitable type will cause errors during procedure
60 | application.
61 |
62 | #### Predicates
63 |
64 | Of course it's not a good idea to simply throw values at a procedure and wait for
65 | errors to occur or not. In Scheme it is therefore very common to check the type
66 | of a value before using it. As a response the program will either reject the
67 | value or select suitable code to be executed. This will be discussed in a later
68 | chapter on [conditionals](../conditionals.html).
69 |
70 | Scheme does not have a (regular) way of revealing the type of something directly
71 | (which is part of the open characteristic). The approach taken instead is
72 | something like asking “is this object behaving like a certain type, does it have
73 | the right properties?” This is achieved using *predicates*. Predicates are
74 | procedures that take an object and return *true* if the object matches a certain
75 | definition or *false* otherwise. By convention the name of a predicate has a
76 | trailing question mark, so for example `number?` checks if a given value is a
77 | number etc.
78 |
79 | ```
80 | guile> (string? "I'm a string")
81 | #t
82 |
83 | guile> (integer? 4.2)
84 | #f
85 |
86 | guile> (boolean? #f)
87 | #t
88 |
89 | guile> (boolean? "true")
90 | #f
91 | ```
92 |
93 | We will come back to the topic of predicates after having discussed writing
94 | procedures, for now we will continue with the discussion of a number of basic
95 | data types.
96 |
97 | If at some point you might want to get more in-depth information about simple
98 | data types you should consult the
99 | [reference](https://www.gnu.org/software/guile/manual/html_node/Simple-Data-Types.html#Simple-Data-Types)
100 | in the Guile manual.
101 |
--------------------------------------------------------------------------------
/scheme/docs/lists/filtering.md:
--------------------------------------------------------------------------------
1 | # Searching and Filtering Lists
2 |
3 | Often it is necessary to choose elements from list based on certain criteria, or
4 | in other words: to search and filter lists. As lists are the core of Scheme as
5 | a LISP language there are of course readily available tools for that purpose.
6 |
7 | ## Searching for Elements in a List
8 |
9 | To determine if an element is present in a list Scheme provides the triple
10 |
11 | * `memq`
12 | * `memv`
13 | * `member`
14 |
15 | each representing one of the three [equality](../equality.html) modes. The functions are called as
16 |
17 | ```
18 | ()
19 | e.g.
20 | (memv 3 '(1 2 3 4 5))
21 | ```
22 |
23 | Colloquially you could translate this into “check if `3` is a member of the list
24 | `'(1 2 3 4 5)`” - which it is -, but actually the function works somewhat
25 | differently. From the introduction to [data types](../data-types.index.html)
26 | you may recall that for that type of question one uses *predicates*, procedures
27 | that return `#t` or `#f` according to the result of some test. But predicate
28 | names by convention have a trailing question mark, which `memq`, `memv` and
29 | `member` do not have. This is not an inconsistency but rather indicates that the
30 | function does *not* return `#t` or `#f`. Instead it returns *the remainder of
31 | the list, starting with the first matched element, or `#f` if the element is not
32 | found in the list*. The result of the above example would therefore be the list
33 | `(3 4 5)`.
34 |
35 | The fact that `member` and friends return either `#f` or a “true value” can be
36 | exploited to create elegant solutions in
37 | [conditionals](../conditionals/index.html).
38 |
39 | ## Filtering Lists
40 |
41 | Sometimes it is necessary to produce a list resulting of all elements in a given
42 | list that match (or do not match) given criteria. This can be achieved through
43 | applying `filter` or `delete` to a list
44 |
45 | #### filter
46 |
47 | ```
48 | (filter )
49 | ```
50 |
51 | `filter` applies `` to each element of `` and creates a new
52 | list consisting of each element satisfying the predicate. `` can be
53 | any procedure taking exactly one argument and returning a value. The predicate
54 | is “satisfied” whenever it returns a “true” value, that is anything except `#f`.
55 |
56 | I will make this clearer through an example. The easiest case is applying a
57 | type predicate, keeping all elements that match a certain type:
58 |
59 | ```
60 | guile> (filter number? '(1 2 "d" 'e 4 '(2 . 3) 5))
61 | (1 2 4 5)
62 | ```
63 |
64 | In this case `filter` applies the predicate `number?` to each element of the
65 | list `'(1 2 "d" 'e 4 '(2 . 3) 5)` and constructs the resulting list from all
66 | numbers in this list. Note that the pair `'(2 . 3)` is *not* a number although
67 | it consists of only numbers.
68 |
69 | In this basic form `filter` is somewhat limited because it can only be used with
70 | procedures accepting a single argument, i.e. “predicates”. Although there are
71 | other procedures that match this requirement it is rarely useful to use them in
72 | a `filter` expression. When interested in things like “all list elements that
73 | are numbers greater than 7” or “all list elements are pairs of numbers where the
74 | `car` is greater than the `cdr`” you will want to use custom procedures, which
75 | you'll learn to write in [Defining Procedures](../scheme/procedures/index.html).
76 |
77 | #### delete and delete-duplicates
78 |
79 | `delete` is somewhat like the opposite of `filter` in so far as it returns a
80 | copy of a list with all elements that *do not* match the given criteria. The
81 | difference is that the match is not determined through a *predicate* but by
82 | comparing the elements with `equal?`.
83 |
84 | ```
85 | guile>(delete 3 '(1 2 3 4 5 4 3 2))
86 | (1 2 4 5 4 2)
87 | ```
88 |
89 | The resulting list is the original list with all elements deleted that are
90 | “equal” to `3`.
91 |
92 | `delete` has its companion procedures `delq` and `delv` which use `eq?` and
93 | `eqv?` as comparison predicate.
94 |
95 | A related procedure is `delete-duplicates`, which returns a copy of the original
96 | list, stripped off any duplicate elements. The comparison is performed using
97 | `equal?`, so for example strings with the same content are deleted as well:
98 |
99 | ```
100 | guile> (delete-duplicates '("a" 2 3 "a" b 3))
101 | ("a" 2 3 b)
102 | ```
103 |
--------------------------------------------------------------------------------
/scheme/docs/lists/accessing.md:
--------------------------------------------------------------------------------
1 | # Accessing List Elements
2 |
3 | In addition to the basic procedures `car` and `cdr` Scheme provides a number of
4 | higher-level ways to access the different list items individually.
5 |
6 | ### Number of Elements of a List
7 |
8 | Often it is necessary to know the length, respectively the number of elements of
9 | a list. This is determined by the `length` procedure:
10 |
11 | ```
12 | guile> (length '(a b c d))
13 | 4
14 | ```
15 |
16 | Note that this expects a *proper list* to work, applying `length` to an improper
17 | list or a pair will result in an error.
18 |
19 | ### Indexed access
20 |
21 | It is possible to access the n-th element of a list using the `list-ref`
22 | procedure, which is passed first the list and then the requested index as
23 | arguments:
24 |
25 | ```
26 | guile> (list-ref '(a b c d) 3)
27 | d
28 | guile> (list-ref '(a b c d) 4)
29 | standard input:7:1: In procedure list-ref in expression (list-ref (quote #) 4):
30 | standard input:7:1: Argument 2 out of range: 4
31 | ABORT: (out-of-range)
32 | ```
33 |
34 | There are two things to note about this: The index is “zero-based”, that means
35 | that the fourth list entry will have the index 3. And it will result in an error
36 | when you try to access a non-existent index as in the second example. The
37 | highest possible index is *one lower than the length of the list*. So if the
38 | list has four elements as in our example the highest index is *3*.
39 |
40 | In order to avoid this kind of error you can make use of the `length` procedure,
41 | once you have learned about conditionals and iteration constructs later in this
42 | book. As an example that works already now you can use it to access the last
43 | element of a list:
44 |
45 | ```
46 | guile>(define lst '(1 2 3 4))
47 | guile>lst
48 | (1 2 3 4)
49 | guile>
50 | (list-ref
51 | lst
52 | (- (length lst) 1))
53 | 4
54 | ```
55 |
56 | In this example we calculate the index of the last element by subtracting one
57 | from the length of the list.
58 |
59 | ### first/second Access
60 |
61 | Guile defines a number of convenience accessor methods to retrieve list elements
62 | by their position specified in English words instead of the number:
63 |
64 | ```
65 | guile> (define lst '(1 2 3 4 5))
66 | guile> (first lst)
67 | 1
68 | guile> (second lst)
69 | 2
70 | guile> (fifth lst)
71 | 5
72 | ```
73 |
74 | Such procedures are defined for the first ten elements of a list (i.e. `first`
75 | through `tenth`). Note that “first” here really means the first, so `(first
76 | lst)` is equivalent to `(list-ref lst 0)`.
77 |
78 | In addition there is the `last` procedure that always retrieves the last element
79 | of the list, regardless of its index. As `list-ref` these functions implictly
80 | retrieve the `car` of an element. So unlike accessing elements through the `car`
81 | and `cdr` functions it is not necessary anymore to explicitly unfold the value
82 | using `car`. But unexpected results may occur when the list is an improper
83 | list. Please investigate the result of the following expressions yourself - if
84 | you have difficulties with that please refer to the explanation about [list
85 | structure](../data-types/lists-and-pairs/structure.html).
86 |
87 | ```
88 | guile> (last '(1 2 3 4 5))
89 | 5
90 | guile> (last '(1 2 3 4 . 5))
91 | 4
92 | ```
93 |
94 | ### Accessing Parts of a List
95 |
96 | Sometimes it's necessary to retrieve parts of a list, for example all elements
97 | starting with the third or up to the fourth. For this the procedures
98 | `list-tail` and `list-head` are provided.
99 |
100 | ```
101 | guile>(define lst '(1 2 3 4 5 6))
102 | (list-tail lst 2)
103 | (3 4 5 6)
104 | ```
105 |
106 | `list-tail` takes the list and the starting index as arguments. So in this
107 | example the list elements starting with index 2 are retrieved. Colloquially one
108 | can also say the arguments specifies the number of elements to be skipped.
109 |
110 | ```
111 | guile>(define lst '(1 2 3 4 5 6))
112 | (list-head lst 2)
113 | (1 2)
114 | ```
115 |
116 | With `list-head` the index argument specifies the index *to which but not
117 | including* the list elements are retrieved. However, again this can
118 | colloquially be expressed much clearer as the “number of retrieved elements”.
119 |
120 | If an actual sub-list is required the procedures can be stacked/nested:
121 |
122 | ```
123 | guile> (list-head (list-tail lst 2) 2)
124 | (3 4)
125 | ```
126 |
127 | First the `list-tail` expression is evaluated, resulting in the list `(3 4 5
128 | 6)`, then this is passed to `list-head`.
129 |
--------------------------------------------------------------------------------
/introduction/docs/language.md:
--------------------------------------------------------------------------------
1 | # Learning the Language
2 |
3 | The first and of course most fundamental challenge in learning Scheme in
4 | LilyPond is - Scheme itself.
5 |
6 | Learners who are not used to functional programming tend to find Scheme
7 | confusing, with the most prominent aspect being the overwhelming number of
8 | parens *(“parens” is a shortname for “parentheses” and is often used colloquially
9 | in computer literature although it's dubious if that term can be considered
10 | proper English. However, as it “flows” much better while the proper term is
11 | comparably awkward I will stick to the shortened form throughout this book)*.
12 | Cryptic error messages triggered by the slightest parenthesizing error are not
13 | likely to make the learning curve more pleasing. In my experience *evaluating
14 | expressions*, as explained in detail in a [later
15 | chapter](../scheme/expressions.html), is the first and most important concept
16 | that has to be thoroughly understood. Once that has been digested, everything
17 | else will be much easier to comprehend. I will try to make this learning
18 | process as smooth as possbile in the [main bookpart](../scheme/index.html) about
19 | Scheme.
20 |
21 | But there is another substantial cause for confusion, and while this book can't
22 | *eliminate* it the mere *knowlegde* of its existence will be of great help.
23 | Concretely, knowing that you're not alone will make you feel significantly less
24 | dumb and helpless. I'm talking about the fact that any Scheme keyword or
25 | function can have a number of different origins.
26 |
27 | Most likely you will encounter existing Scheme code either by looking into
28 | arbitrary files or when investigating code that someone shared with you.
29 | Probably code shared in response to requests on the mailing lists is the single
30 | most common opportunity to get in initial touch with Scheme. The next natural
31 | step - after having managed to get such code to run at all - is usually the
32 | desire to modify that code in order to avoid having to ask the kind donor again.
33 | And this is where users are typically faced with incomprehensible heaps of code -
34 | and parens. Lacking the basic understanding of the fundamental ideas usually
35 | makes it unlikely to successfully change anything in the code. Figuring out
36 | what is going on in the code is made pretty complicated because there is no
37 | single place to look up the names, and web searches are generally not very
38 | helpful either.
39 |
40 | What makes finding information about any given name or construct so difficult is
41 | that it can be defined in many different contexts:
42 |
43 | * *Core Scheme *
44 | These are the easiest cases. But not every core feature is supported by each
45 | Scheme implementation.
46 | * *Guile* (i.e. the actual Scheme implementation)
47 | Of course Guile is the reference for which Scheme elements are available in
48 | LilyPond
49 | * *Guile modules*
50 | Not everything a Scheme system provides is available by default. Guile offers
51 | a huge number of modules that have to be included for its functionality to be
52 | accessible. LilyPond includes a number of such Guile modules automatically,
53 | but code that you see may depend on additional modules. As a consequence code
54 | that works in one context may trigger `unknown escaped string` errors in others.
55 | * *LilyPond*
56 | LilyPond itself defines a large number of Scheme functions and keywords.
57 | Searching the net for these as “Scheme” keywords will probably fail
58 | * *User code*
59 | Many names you encounter in Scheme code are functions or variables defined
60 | elsewhere in the file or in a user-provided library. In a way this is a clear
61 | case but experience tells that these names cause a whole lot of additional
62 | confusion if you can't really discern the previous four items either.
63 |
64 | When looking at existing Scheme code you'll likely encounter *all* of these in
65 | one place, and this can be pretty confusing - in a way it feels like a system of
66 | equations with *at least* one variable too much. There is no once-and-for-all
67 | solution to this issue, but I can encourage you to keep calm and try to slowly
68 | disentangle everything step by step. And to ask. Probably it's not that you
69 | are too stupid for it, it's more likely that you're trapped in the described
70 | situation. So feel free to ask on the mailing lists, and try not to be
71 | satisfied by a solution that “just works” but ask until you have understood the
72 | underlying principle.
73 |
74 | The bookpart about [Scheme](../scheme/index.html) will cover Scheme concepts on
75 | their own, but always from the perspective of LilyPond.
76 |
--------------------------------------------------------------------------------
/scheme/docs/music-function-primer.md:
--------------------------------------------------------------------------------
1 | # Music Function Primer
2 |
3 | This chapter will give you some building blocks that you can use to try out the
4 | Scheme features discussed in the current bookpart. They are provided “as-is”,
5 | and you should be aware that you are not expected to really understand them at
6 | this point. I am talking about `music-`, `scheme-` and `void-` functions, which
7 | are discussed in-depth in a [dedicated
8 | chapter](lilypond/functions/music-scheme-void.html). In this chapter I will only
9 | give you a brief overview, and you can use these functions to experiment with
10 | the Scheme concepts discussed in the remainder of this bookpart.
11 |
12 | Music-, scheme- and void-functions are expressions just like anything else in
13 | Scheme. In light of the previous chapter you can say that music functions
14 | evaluate to a “music expression”, scheme functions evaluate to any Scheme value,
15 | and a void function's value is `#`. That is, wherever you can
16 | write music (and overrides are “music” too) you can instead write a music
17 | function, wherever you can use a Scheme value (for example assigning values to
18 | overrides) you can instead write a scheme function, and void functions can be
19 | used whenever no return value is needed but something has got to be *done*.
20 |
21 | All three forms basically look the same, and I will demonstrate this with a
22 | scheme function as an example:
23 |
24 | ```lilypond
25 | mySchemeFunction =
26 | #(define-scheme-function (argument-name)
27 | (string?)
28 | ; function body
29 | )
30 | ```
31 |
32 | We use a variable name and assign it a (music) function. Following the keyword
33 | `define-scheme-function` is a list of parameter names (in the example just one),
34 | which is then followed by a list of *predicates* (see [data
35 | types](data-types/index.html)). For each parameter there must be one predicate
36 | specifying the expected data type, in this case `string?`.
37 |
38 | The function body can consist of an arbitrary number of expressions, where the
39 | last one specifies the return value (which is then substituted in the LilyPond
40 | document).
41 |
42 | You may have seen such functions where the parameter list started with
43 | (literally) `parser location`. This is not necessary anymore in LilyPond
44 | releases starting with the current 2.19 development line. The current stable
45 | release 2.18.2 still requires this, but this is a topic that I won't discuss
46 | anymore in this book.
47 |
48 | ### Scheme Functions
49 |
50 | As we've seen Scheme functions are created using the `define-scheme-function`
51 | keyword. They evaluate the Scheme value (of arbitrary type) that the last
52 | expression in its body evaluates to, and this value is then used in the LilyPond
53 | document:
54 |
55 | ```lilypond
56 | mySchemeFunction =
57 | #(define-scheme-function (name)
58 | (string?)
59 | (string-append name " | " name)
60 | )
61 |
62 | \header {
63 | title = \mySchemeFunction "Doubled Title"
64 | }
65 | ```
66 |
67 | This will call the scheme function and assign `Doubled Title | Doubled Title` to
68 | the `title` paper variable.
69 |
70 | ### Music Functions
71 |
72 | Music functions are created using the `define-music-function` keyword. Instead
73 | of arbitrary Scheme values they are expected to return a music expression, so
74 | the last expression in the body must be “music”. The easiest way to achieve this
75 | is to switch back to LilyPond mode using `#{ #}`. If it is necessary to access
76 | Scheme values from within that one has to - again - use the `#` hash sign:
77 |
78 | ```lilypond
79 | myMusicFunction =
80 | #(define-music-function (color)
81 | (color?)
82 | #{
83 | \override NoteHead.color = #color
84 | \override Stem.color = #color
85 | \override Flag.color = #color
86 | #})
87 |
88 | {
89 | c'4
90 | \myMusicFunction #red
91 | d'8
92 | }
93 | ```
94 |
95 | The `#{ #}` is *one* Scheme expression, but as in any LilyPond music expression
96 | it can have many consecutive elements like the overrides in this example.
97 |
98 | ### Void Functions
99 |
100 | Void functions are created using the `define-void-function` keyword. Regardless
101 | of the value of the last expression in their body they do *not* return anything
102 | and can therefore be used virtually anywhere in a LilyPond file. Void functions
103 | are used when something has to be done or modified but we don't make use of the
104 | return value:
105 |
106 | ```lilypond
107 | myVoidFunction =
108 | #(define-void-function (a-value)
109 | (number?)
110 | (display (* 2 a-value)))
111 |
112 | \myVoidFunction 4
113 | ```
114 |
--------------------------------------------------------------------------------
/scheme/mkdocs.yml:
--------------------------------------------------------------------------------
1 | # Common stuff
2 |
3 | theme:
4 | name: 'material'
5 | palette:
6 | primary: 'Blue'
7 | accent: 'Blue'
8 | feature:
9 | tabs: true
10 | markdown_extensions:
11 | - codehilite:
12 | guess_lang: false
13 | - admonition
14 | - toc:
15 | permalink: true
16 | use_directory_urls: false
17 | extra:
18 | search:
19 | tokenizer: '[\s\-\.]+'
20 | social:
21 | - type: 'github'
22 | link: 'https://github.com/openlilylib'
23 | - type: 'wordpress'
24 | link: 'http://lilypondblog.org'
25 | plugins:
26 | - search
27 | - minify:
28 | minify_html: true
29 | - git-revision-date-localized
30 | use_directory_urls: false
31 | repo_url: https://github.com/uliska/lilyponds-scheme/
32 | site_dir: '../site/scheme'
33 | edit_uri: edit/master/scheme/docs
34 | site_name: Scheme (in LilyPond)
35 | nav:
36 | - Introduction:
37 | - Home: '../introduction/index.html'
38 | - 'Scheme':
39 | - Home: 'index.md'
40 | - Introduction:
41 | - "Everything's an Expression": 'expressions.md'
42 | - 'Including Scheme in LilyPond': 'including.md'
43 | - 'Music Function Primer': 'music-function-primer.md'
44 | - 'Concepts':
45 | - 'Intro': 'concepts.md'
46 | - 'Data Types':
47 | - 'Simple Data Types':
48 | - 'Intro': 'data-types/README.md'
49 | - 'Numbers': 'data-types/numbers.md'
50 | - 'Booleans': 'data-types/booleans.md'
51 | - 'Strings': 'data-types/strings.md'
52 | - 'Symbols': 'data-types/symbols.md'
53 | - 'Compound Data Types':
54 | - 'Intro': 'data-types/compound.md'
55 | - 'Lists and Pairs':
56 | - 'Intro': 'data-types/lists-and-pairs/README.md'
57 | - 'Creating Pairs': 'data-types/lists-and-pairs/creating-pairs.md'
58 | - 'Accessing Pairs': 'data-types/lists-and-pairs/accessing-pairs.md'
59 | - 'Creating Lists': 'data-types/lists-and-pairs/creating-lists.md'
60 | - 'List Structure': 'data-types/lists-and-pairs/structure.md'
61 | - 'Accessing Lists': 'data-types/lists-and-pairs/accessing-lists.md'
62 | - 'Pairs vs. Lists': 'data-types/lists-and-pairs/list-pair-comparison.md'
63 | - 'Vectors': 'data-types/vectors.md'
64 | - 'Custom Types': 'data-types/custom.md'
65 | - 'Equality and Equivalence': 'equality.md'
66 | - 'Quoting':
67 | - 'Intro': 'quoting/README.md'
68 | - 'Preventing Evaluation': 'quoting/preventing-evaluation.md'
69 | - 'Creating Lists and Pairs': 'quoting/lists-and-pairs.md'
70 | - 'Unquoting': 'quoting/unquoting.md'
71 | - 'Binding Variables':
72 | - 'Intro': 'binding/README.md'
73 | - 'Top-level Bindings': 'binding/top-level.md'
74 | - 'Local Bindings': 'binding/local.md'
75 | - 'Let': 'binding/let.md'
76 | - 'Parenthesizing Errors': 'binding/paren-errors.md'
77 | - 'let* and letrec': 'binding/letstar.md'
78 | - 'Conditionals':
79 | - 'Intro': 'conditionals/README.md'
80 | - 'if': 'conditionals/if.md'
81 | - 'cond': 'conditionals/cond.md'
82 | - 'case': 'conditionals/case.md'
83 | - 'not/and/or': 'conditionals/logical.md'
84 | - 'Working With Lists':
85 | - 'Intro': 'lists/README.md'
86 | - 'List Operations':
87 | - 'Accessing List Elements': 'lists/accessing.md'
88 | - 'Extending and Reversing Lists': 'lists/extend-reverse.md'
89 | - 'Filtering Lists': 'lists/filtering.md'
90 | - 'Modifying Lists': 'lists/modifying.md'
91 | - 'Iteration Over Lists': 'lists/iteration.md'
92 | - 'Association Lists':
93 | - 'Intro': 'alists/README.md'
94 | - 'Lookup in Alists': 'alists/retrieving.md'
95 | - 'Modifying Alists': 'alists/modifying.md'
96 | - 'Iteration and Loops':
97 | - 'Intro': 'loops/README.md'
98 | - 'map': 'loops/map.md'
99 | - 'for-each': 'loops/for-each.md'
100 | - 'List Recursion': 'loops/recursion.md'
101 | - 'Programming Loops': 'loops/do-while.md'
102 | - 'Procedures':
103 | - 'Defining Procedures': 'procedures/README.md'
104 | - 'lambda Expressions': 'procedures/lambda.md'
105 | - 'lambda Signatures': 'procedures/lambda-signatures.md'
106 | - 'Binding Procedures': 'procedures/binding.md'
107 | - 'Predicates': 'procedures/predicates.md'
108 | - 'Parameter Types': 'procedures/parameter-types.md'
109 | - 'Scheme in LilyPond':
110 | - Home: '../lilypond/index.html'
111 | - 'LilyPond Internals':
112 | - Home: '../internals/index.html'
113 |
--------------------------------------------------------------------------------
/scheme/docs/alists/README.md:
--------------------------------------------------------------------------------
1 | # Association Lists
2 |
3 | Now that we've become familiar with lists and pairs we can investigate a special
4 | incarnation of them: *association lists*, or *alists*. These are lists that
5 | associate *keys* with *values* and allow the retrieval of values by their keys,
6 | which is the same behaviour as what *dictionaries* do in other languages such as
7 | e.g. Python. Alists are for example used to store all the properties in
8 | LilyPond's objects.
9 |
10 | Technically a Scheme alist is not some predefined type, but it should be seen
11 | the other way round: a list whose elements are pair representing a key-value
12 | relationship is considered an association list.
13 |
14 | ## Inspecting alist Structure
15 |
16 | In order to save some typing we start a session with defining an association list:
17 |
18 | ```
19 | guile>
20 | (define my-alist
21 | '(
22 | (color1 . red)
23 | (color2 . green)
24 | (color3 . blue)
25 | )
26 | )
27 | guile> my-alist
28 | ((color1 . red) (color2 . green) (color3 . blue))
29 | ```
30 |
31 | This is not the commonly used Scheme layout but intends to give a better idea of
32 | the structure. Normally the expression would be written in a more condensed
33 | manner (note particularly that all the trailing parens are lined up at the end
34 | of the last line), for example:
35 |
36 | ```
37 | guile>
38 | (define my-alist
39 | '((color1 . red)
40 | (color2 . green)
41 | (color3 . blue)))
42 | ```
43 |
44 | Inside the `define` I created a list with three elements using the `'()` syntax,
45 | and each of these elements is a pair associating a name for a color with a
46 | concrete color. This is a regular list of pairs, but one can say it is an
47 | association list because of that specific structure. As it *is* a regular list
48 | you can access its elements with the usual methods applicable to lists and
49 | pairs:
50 |
51 | ```
52 | guile> (car my-alist)
53 | (color1 . red)
54 |
55 | guile> (cadr my-alist)
56 | (color2 . green)
57 |
58 | guile> (first my-alist)
59 | (color1 . red)
60 |
61 | guile> (cdar my-alist)
62 | red
63 | ```
64 |
65 | I strongly suggest you take the opportunity to practice by trying to retrieve
66 | every single element from this alist, taking specific care about extracting the
67 | elements from the last pair.
68 |
69 | ### Types and Quotes
70 |
71 | Of course the keys and values can have arbitrary types, as is the rule with
72 | Scheme pairs. But it is considered best practice to use *symbols* as keys,
73 | which has some advantages we won't discuss here. And this points us to an issue
74 | where we can start to see the practical use case for the different quoting
75 | methods we have discussed in the previous chapter.
76 |
77 | `my-alist` maps the *name* (symbol) `color1` to the *name* `red`. However, if
78 | we make use of such an association list we usually want to map the name `color1`
79 | to the *color* `red`. The real-world use case of this might be that we have
80 | defined a certain type of thing (e.g. the composer name) to be formatted using
81 | “color1” and have the user specify a concrete color for that stylesheet. Or we
82 | might highlight editorial additions with a color and want to set that to black
83 | when the score is compiled for publication.
84 |
85 | So we have to make sure that the *value* parts of the pairs have the right type,
86 | which is not possible using the syntax used above. But while all the options
87 | are available that we discussed in the *quoting* chapter I will only use the
88 | most common idiom here: *quasiquote* the whole list and *unquote* the values
89 | (note the backtick in front of the list's parenthesis):
90 |
91 | ```
92 | guile> (define my-new-alist
93 | `((color1 . ,red)
94 | (color2 . ,green)
95 | (color3 . ,blue)))
96 | guile> my-new-alist
97 | ((color1 1.0 0.0 0.0) (color2 0.0 1.0 0.0) (color3 0.0 0.0 1.0))
98 | ```
99 |
100 | If you are wondering why the three pairs look like lists instead of pairs you
101 | should go back and check out the “Digression” section in the chapter about
102 | [creating quoted lists and pairs](../quoting/lists-and-pairs.html).
103 |
104 | But of course we don't want to only create alists but to actually *do* something
105 | with them, which we'll discuss in the following chapters.
106 |
107 | As processing alists is so central to working with Scheme it is no wonder that a
108 | number of dedicated procedures exist for adding, updating, retrieving and
109 | removing entries from alists are available. They are not hard to understand in
110 | principle, but in my experience there are two issues one has to be very careful
111 | about: the seemingly arbitrary order of arguments that is expected by the
112 | different procedures, and the fact that some procedures modify the alists
113 | in-place while others just return new copies. This is something one has to
114 | learn very thoroughly - or be sure to always look it up when using the
115 | procedures.
116 |
--------------------------------------------------------------------------------
/scheme/docs/conditionals/if.md:
--------------------------------------------------------------------------------
1 | # `if`
2 |
3 | The `if` conditional is the most basic code switch in more or less any
4 | programming language. In Scheme it has the general form
5 |
6 | ```
7 | (if test consequent alternative)
8 | ```
9 |
10 | If the expression `test` evaluates to “a true value” then the subexpression
11 | `consequent` is evaluated, otherwise `alternative`, and the whole `if`
12 | expression evaluates to the value of the chosen subexpression. OK, let's
13 | clarify this with an example, but first of all we have to understand what “a
14 | true value” means.
15 |
16 | ### ”True Values”
17 |
18 | Scheme knows the literals `#t` for “true” and `#f` for “false”, which are
19 | returned by many comparing expressions and particularly all predicates:
20 |
21 | ```
22 | guile> (> 2 1)
23 | #t
24 |
25 | guile> (string=? "Yes" "No")
26 | #f
27 |
28 | guile> (number? 1)
29 | #t
30 |
31 | guile> (list? "I'm a list?")
32 | #f
33 | ```
34 |
35 | However, in Guile Scheme *every object except `#f`* is considered to have “a
36 | true value”. So the following expressions *all* have “a true value”:
37 |
38 | ```
39 | "Foo"
40 | 'bar
41 | '(1 . 2)
42 | '()
43 | ```
44 |
45 | That means that whenever the expression `test` evaluates to *anything except
46 | `#f`* then `consequent` is evaluated, otherwise `alternative`.
47 |
48 | ### Evaluating `if` expressions
49 |
50 | So here is the first concrete example
51 |
52 | ```
53 | guile>
54 | (if (> 2 1)
55 | "Greater"
56 | "Smaller")
57 | "Greater"
58 |
59 | guile>
60 | (if (> 1 2)
61 | "Greater"
62 | "Smaller")
63 | "Smaller"
64 | ```
65 |
66 | In the first case the test is the expression `(> 2 1)` which evaluates to `#t`
67 | (2 *is* greater than 1), therefore the `consequent` subexpression is evaluated.
68 | In this case it is the self-evaluating string `"Greater"`, but it could as well
69 | be a complex expression or a symbol referring to a variable. This string then
70 | becomes the value of the whole `if` expression, and therefore this is printed as
71 | the result.
72 |
73 | In the second case the test expression evaluates to `#f`, therefore the whole
74 | expression evaluates to `"Smaller"`.
75 |
76 | The most important thing to understand here is that the subexpressions
77 | *evaluate* to a value and don't necessarily *do* anything, and that the same is
78 | true for the whole `if` expression. This is what I meant with the different
79 | paradigm: in Scheme an `if` expression should be phrased colloquially as
80 | “depending on the result of the test this evaluates to one or the other” instead
81 | of “depending on the test do this or that”. This is best demonstrated in a local
82 | binding (which is also a common use case for conditionals):
83 |
84 | ```lilypond
85 | #(display
86 | (let* ((rand (random 100))
87 | (state (if (even? rand)
88 | "even"
89 | "odd")))
90 | (format "The random number ~a is ~a" rand state)))
91 | ```
92 |
93 | We have a `let*` expression at the core of this example. It establishes two
94 | bindings, first a random integer and then its “state”. The value bound to the
95 | `state` name is the result of an `if` expression, namely one of the strings
96 | `“even”` or `“odd”`, depending on the result of the application of the `even?`
97 | procedure. The *body* of the `let*` expression is the invocation of the
98 | `format` procedure which evaluates to a string. Therefore the value of the
99 | whole `let*` expression is the value of the `format` expression, which is then
100 | passed to the `display` procedure, which prints for example `The random number
101 | 61 is odd` to the console.
102 |
103 | ### Special Cases
104 |
105 | #### Unspecified Values
106 |
107 | The example discussed above is the default case for `if` expressions, but there
108 | are a number of special cases you should know about - because they can be both
109 | confusing and useful. The first topic to discuss is the value of the
110 | subexpressions.
111 |
112 | Depending on the test one subexpression will be evaluated, and its value becomes
113 | the value of the `if` expression. However, expressions do not necessarily
114 | evaluate to a value but can also be ``:
115 |
116 | ```
117 | guile>
118 | (if #t
119 | (display "true")
120 | (display "false"))
121 | ```
122 |
123 | The subexpression `(display "true")` will print something to the console but
124 | doesn't evaluate to anything, and consequently the whole expression *also* has
125 | an unspecified value.
126 |
127 | #### No alternative expression
128 |
129 | The alternative expression can be omitted in an `if` expression, making it `(if
130 | test consequent)`. This will work, but when the test fails (i.e. the
131 | alternative expression is requested to be evaluated) the value of the `if`
132 | expression will be unspecified. This may be acceptable or not, depending on the
133 | context. For example, if the subexpression is used to *do* something instead of
134 | *returning* a value there's no problem at all.
135 |
--------------------------------------------------------------------------------
/scheme/docs/alists/retrieving.md:
--------------------------------------------------------------------------------
1 | # Looking Up Values from Association Lists
2 |
3 | Retrieving a value from an alist means looking up the key and returning the
4 | corresponding value. In our previous alist `my-new-alist` we want to get the
5 | `green` variable for the key `color2`.
6 |
7 | As the alists are regular lists we could go ahead and figure out a way to
8 | iterate over the list, comparing each element's `car` with the given key and if
9 | we find something return the corresponding `cdr`. You are not ready to do that
10 | yet, but fortunately this isn't necessary anyway. As association lists are so
11 | fundamental that Guile provides a number of specific procedures that can be used
12 | directly.
13 |
14 | ### Guile's alist Retrieval Procedures
15 |
16 | Guile's procedures are documented in the
17 | [reference](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Retrieving-Alist-Entries.html#Retrieving-Alist-Entries),
18 | but looking at that page might be quite confusing at this moment.
19 |
20 | There are two basic forms of procedures, and both come in three variants (and
21 | additionally everything is doubled for C and Scheme). The three variants differ
22 | in the method they use for determining a matching key, which Guile calls the
23 | “level of equality”. This is a discussion I would like to spare you for now,
24 | and you can keep in mind that as long as you stick to *symbols* as alist keys
25 | you should use the “q” variants of the procedures, `assq` and `assq-ref`. If at
26 | one point you should need other types as alist keys you have to get familiar
27 | with Scheme's concept of equality and Guile's/LilyPond's implementation of it
28 | (see [Equality and Equivalence](https://scheme-book.ursliska.de/scheme/equality.html)).
29 |
30 | #### Different Return Targets
31 |
32 | `assq` and `assq-ref` differ in what they return for the match: `assq` returns
33 | the `(key . value)` pair for a match while `assq-ref` returns just the value.
34 | Both return `#f` if the requested key is not present in the alist. Please note
35 | the annoying detail that the order of arguments is reversed: `assq` expects
36 | first the *key* while `assq-ref` wants the *alist* first:
37 |
38 | ```
39 | guile> (assq 'color2 my-new-alist)
40 | (color2 0.0 1.0 0.0)
41 |
42 | guile> (assq-ref my-new-alist 'color2)
43 | (0.0 1.0 0.0)
44 |
45 | guile> (assq 'color4 my-new-alist)
46 | #f
47 |
48 | guile> (assq-ref my-new-alist 'color4)
49 | #f
50 | ```
51 |
52 | So which procedure should be used then, or which one in which situation?
53 | Generally it is more common that you want to use the *value* rather than the
54 | key-value pair, so this seems to indicate using `assq-ref` preferably. But
55 | while this is *often* true there is an important caveat: the behaviour with
56 | non-existent keys. As seen both procedures return `#f` if the key is not
57 | present in the alist, and in our example with the colors this probably doesn't
58 | cause any problems. However, the issue becomes crucial when `#f` is a valid
59 | value in the alist.
60 |
61 | ```
62 | guile> (define bool-alist
63 | '((subdivide . #t)
64 | (use-color . #f)))
65 |
66 | guile> (assq-ref bool-alist 'use-color)
67 | #f
68 |
69 | guile> (assq-ref bool-alist 'use-colors)
70 | #f
71 | ```
72 |
73 | Both invocations return `#f`, but only in one case this refers to the actual
74 | *value* of the entry, while in the other it is the result of the key not being
75 | present.
76 |
77 | Please don't think this is only used to catch typing errors - as this example
78 | might suggest. It is very common to process alists where it is not known which
79 | keys are present. In such cases you *have* to use `assq` and unfold the
80 | resulting pair yourself:
81 |
82 | ```
83 | guile> (assq 'use-color bool-alist)
84 | (use-color . #f)
85 |
86 | guile> (assq 'use-colors bool-alist)
87 | #f
88 |
89 | guile> (cdr (assq 'subdivide bool-alist))
90 | #t
91 | ```
92 |
93 | The pair with `#f` as its `cdr` indicates an actual *false* value while the
94 | plain `#f` refers to a missing key. Unpacking the `cdr` of the result is a
95 | minor hassle, but there still is an issue that you can't handle at the moment:
96 | when the return value is `#f` (i.e. the key is not present) you can't extract
97 | the `cdr` from that (just try out `(cdr #f)`). In order to properly handle the
98 | situation you will have to wait a little longer until you have digested
99 | [conditionals](../conditionals.html).
100 |
101 | #### Caveat: About the Uniqueness of alist Keys
102 |
103 | Both `assq` and `assq-ref` return the value for *the first* occurence of the key
104 | in the alist. This is important because Scheme has no inherent way to guarantee
105 | that keys in alists are unique. If you think of the fact that alists are
106 | regular lists with a specific form then this is pretty clear - how *should*
107 | there a way for enforcing uniqueness?
108 |
109 | In the next chapter you will see how one can take care of uniqueness when adding
110 | entries to an alist, but as long as you can't directly control an alist you have
111 | to expect duplicate keys.
112 |
113 | ```
114 | guile> (define al
115 | '((col1 . 1)
116 | (col2 . 2)
117 | (col1 . 3)))
118 | guile> (assq 'col1 al)
119 | (col1 . 1)
120 | ```
121 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/custom.md:
--------------------------------------------------------------------------------
1 | # Custom Data Types
2 |
3 | Now that we've discussed some of the basic data types it is important to
4 | understand that Scheme can be substantially extended with arbitrary “data
5 | types”. As we have learnt earlier Scheme is very open about types, and
6 | therefore creating data types in Scheme is not like defining classes of objects
7 | with their properties and methods. Instead one writes *predicates* (see [data
8 | types](index.html#predicates)), basically providing a way to check if a given
9 | object matches the criteria for being “of a given type”.
10 |
11 | There is a large number of predicates available beyond the basic Scheme data
12 | types, and it is sometimes difficult to trace where a given data type is
13 | originating. Predicates can be defined in
14 |
15 | * Scheme itself,
16 | * Guile's Scheme implementation,
17 | * LilyPond, or
18 | * Custom (user/library) code
19 |
20 | You may now want to have a look at the extensive [list of
21 | predicates](http://lilypond.org/doc/v2.20/Documentation/notation/predefined-type-predicates)
22 | in LilyPond's documentation. To get our head around the idea of custom data
23 | types we will have a closer look at one data type that is defined by LilyPond:
24 | `color?`.
25 |
26 | #### Dissecting a Custom Data Type
27 |
28 | Applying a color to a score item is achieved by overriding its `color` property.
29 | (For more details about coloring please refer to the respective pages in
30 | LilyPond's [Learning
31 | Manual](http://lilypond.org/doc/v2.20/Documentation/learning/visibility-and-color-of-objects#the-color-property)
32 | and the [Notation
33 | Reference](http://lilypond.org/doc/v2.20/Documentation/notation/inside-the-staff#coloring-objects).)
34 |
35 | ```lilypond
36 | \override NoteHead.color = #red
37 | ```
38 |
39 | The hash sign switches to Scheme, and `red` is given as a symbol referring to a
40 | variable. Using the Scheme REPL we can investigate what this variable evaluates
41 | to:
42 |
43 | ```
44 | guile>red
45 | (1.0 0.0 0.0)
46 | ```
47 |
48 | `red` evaluates to a list of three floating-point numbers. If you know
49 | something about colors and guess that the three numbers represent the RGB values
50 | within a range of `0` and `1` you are right. If you want you can do more
51 | experiments by inspecting other colors in the REPL, e.g. `blue`, `green`,
52 | `yellow` or `magenta`.
53 |
54 | We can use the predicate `color?` to check if a given value is a color.
55 |
56 | ```
57 | guile> (color? red)
58 | #t
59 |
60 | guile> (color? '(1.0 0.0 0.0))
61 | #t
62 | ```
63 |
64 | It is not surprising to see that `red` is a `color`, but we also see that we can
65 | pass a literal value to the predicate. Experimenting with a number of values we
66 | can get closer to understanding what `color?` expects:
67 |
68 | ```
69 | guile> (color? 'my-symbol)
70 | #f
71 |
72 | guile> (color? '(1 0 1))
73 | #t
74 |
75 | guile> (color? '(1 0 0.5))
76 | #t
77 |
78 | guile> (color? '(2/3 1 0.2))
79 | #t
80 |
81 | guile> (color? '(3/2 1 1))
82 | #f
83 |
84 | guile> (color? '(0 1 0 1))
85 | #f
86 | ```
87 |
88 | Obviously a color is a color when it consists of a list of (exactly) three real
89 | numbers in the range of `0 =< n =< 1`. The numbers can be written as integers,
90 | fractions or reals, as long as they are within the proper range. In a [later
91 | chapter](../predicates.html) we will have a closer look at how `color?` is
92 | defined, which will confirm this assumption.
93 |
94 |
95 |
96 | ---
97 |
98 | The manual suggest another way of specifying colors from the list of X11 colors:
99 |
100 | ```lilypond
101 | \override NoteHead.color = #(x11-color 'LimeGreen)
102 | ```
103 |
104 | Let's check this as well in the shell:
105 |
106 | ```
107 | guile> (x11-color 'LimeGreen)
108 | (0.196078431372549 0.803921568627451 0.196078431372549)
109 |
110 | guile> (color? (x11-color 'LimeGreen))
111 | #t
112 | ```
113 |
114 | This time we call a procedure `x11-color` with the symbol `'LimeGreen`, and
115 | again it returns a list of three floating point numbers, which “is” a color.
116 |
117 | ---
118 |
119 | Now that we know what a color *is* we can try out to use custom colors created
120 | ad-hoc:
121 |
122 | ```lilypond
123 | {
124 | \override NoteHead.color = #'(0.7 0.3 0.8)
125 | c''4 c''
126 | }
127 |
128 | {
129 | \override NoteHead.color = #'(3/2 0.3 1)
130 | c''4 c''
131 | }
132 |
133 | ```
134 |
135 | Not surprisingly only the first example works as well and colors the noteheads
136 | in a nice violet. The second object violates the requirements of `color?` as
137 | the first number is greater than 1. As a result LilyPond prints a warning to
138 | the console and ignores the override: `warning: type check for 'color' failed;
139 | value '(3/2 0.3 1)' must be of type 'color'`.
140 |
141 | Obviously it is possible to use anything as a color property that evaluates to
142 | something satisfying the `color?` predicate, whether it is a predefined color
143 | variable, an ad-hoc list or a call to a custom procedure. At the same time the
144 | type check (which is actively performed by LilyPond) acts as a safety net: it
145 | prints a warning and tries to continue the compilation, and so it prevents the
146 | program to crash upon erroneous user input.
147 |
148 | ---
149 |
150 | So in this chapter you have learned about the characteristics of data types and
151 | predicates. They allow to specify how data has to be formed in order to be
152 | successfully processable by the program. Guile makes use of that feature to
153 | extend Scheme's functionality, and LilyPond does so as well, so in real-world
154 | code you may encounter a large number of different data types.
155 |
--------------------------------------------------------------------------------
/scheme/docs/alists/modifying.md:
--------------------------------------------------------------------------------
1 | # Modifying alists
2 |
3 | As seen in the previous chapter Scheme provides commands to retrieve elements
4 | from association lists although this could also be done using regular list
5 | operations. The same is true for adding and setting elements in alists. While
6 | it would surely be a good exercise to go through the process in detail you are
7 | still lacking some basics, in particular [conditionals](../conditionals.html),
8 | so we're sticking to Scheme's dedicated procedures (which you'll be using in
9 | general anyway).
10 |
11 | ## Adding an Entry
12 |
13 | There is one procedure that simply adds an entry to an association list:
14 |
15 | ```
16 | acons
17 | ```
18 |
19 | (as a shortname for “cons an alist”). This creates a pair of the given key and
20 | value and “conses” this pair to the alist, returning a new alist with the new
21 | key prepended:
22 |
23 | ```
24 | guile> (define bool-alist
25 | '((subdivide . #t)
26 | (use-color . #f)))
27 |
28 | guile> bool-alist
29 | ((subdivide . #t) (use-color . #f))
30 |
31 | guile> (acons 'debug #f bool-alist)
32 | ((debug . #f) (subdivide . #t) (use-color . #f))
33 |
34 | guile> bool-alist
35 | ((subdivide . #t) (use-color . #f))
36 | ```
37 |
38 | From the last expression you can see that the original alist is not modified by
39 | this, instead a copy of the combined alist is returned. So if we want to keep
40 | the new alist for further use we have to bind it to some other variable (which
41 | we'll see in more detail in [Binding](../binding.html)) or use the following
42 | syntax to assign the result to the original variable:
43 |
44 | ```
45 | guile> (set! bool-alist
46 | (acons 'debug #f bool-alist))
47 |
48 | guile> bool-alist
49 | ((debug . #f) (subdivide . #t) (use-color . #f))
50 | ```
51 |
52 | As said above `acons` simply prepends a new pair, without checking for existing
53 | elements with the same key. When you now try to retrieve the entry for such a
54 | duplicate entry `assq` will return the *first* pair with the matching key:
55 |
56 | ```
57 | guile> (set! bool-alist
58 | (acons 'subdivide #f bool-alist))
59 | guile> bool-alist
60 | ((subdivide . #f) (debug . #f) (subdivide . #t) (use-color . #f))
61 |
62 | guile> (assq 'subdivide bool-alist)
63 | (subdivide . #f)
64 | ```
65 |
66 | As it is rather uncommon to have association lists with non-unique keys Scheme
67 | also provides a procedure to *add or update* a list element:
68 |
69 |
70 | ## Adding or Updating List Elements
71 |
72 | Scheme provides a set of three procedures to *add or update* entries in an
73 | alist. As with the procedures retrieving elements from alists the three
74 | variants refer to three levels of equality that are applied for matching the
75 | given pair to potentially existing elements. If the keys in the alist are
76 | symbols the procedure to use is
77 |
78 | ```
79 | assq-set!
80 | ```
81 |
82 | otherwise you may have to use `assv-set!` or `assoc-set!` and - again -
83 | familiarize yourself with the different levels of equality in Scheme. (Again:
84 | please note the different order of arguments as compared to `acons`.)
85 |
86 | The procedure first checks if the alist already contains an entry with the given
87 | key. If it does it replaces the value for that key, so the original alist is
88 | updated:
89 |
90 | ```
91 | guile> (assq-set! bool-alist 'debug #t)
92 | ((subdivide . #f) (debug . #t) (subdivide . #t) (use-color . #f))
93 |
94 | guile> bool-alist
95 | ((subdivide . #f) (debug . #t) (subdivide . #t) (use-color . #f))
96 | ```
97 |
98 | When the procedure does *not* find the key already present it prepends a new
99 | element, just as `acons` does:
100 |
101 | ```
102 | guile> (assq-set! bool-alist 'color red)
103 | ((color 1.0 0.0 0.0) (subdivide . #f) (debug . #t) (subdivide . #t) (use-color . #f))
104 |
105 | guile> bool-alist
106 | ((subdivide . #f) (debug . #t) (subdivide . #t) (use-color . #f))
107 | ```
108 |
109 | But please note that - again as with `acons` in this case the original alist is
110 | *not* updated and a new copy returned instead. So again you have to self-assign
111 | the updated list:
112 |
113 | ```
114 | guile> (set! bool-alist
115 | (assq-set! bool-alist 'color red))
116 |
117 | guile> bool-alist
118 | ((color 1.0 0.0 0.0) (subdivide . #f) (debug . #t) (subdivide . #t) (use-color . #f))
119 | ```
120 |
121 | ---
122 |
123 | More details and examples can be found on the [reference
124 | page](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Adding-or-Setting-Alist-Entries.html#Adding-or-Setting-Alist-Entries).
125 |
126 | ## Removing Entries from an alist
127 |
128 | The missing third part is how to remove existing elements from alists.
129 | Probably you won't be surprised by now that this can be achieved using the
130 | procedure
131 |
132 | ```
133 | assq-remove!
134 | ```
135 |
136 | and its companions `assv-remove!` and `assoc-remove!`. You should understand
137 | that what `assq-remove!` actually does is making sure the given key isn't
138 | present in the returned alist. So if you give it a non-existent key the
139 | procedure simply does nothing, without any further notification:
140 |
141 | ```
142 | guile> (assq-remove! bool-alist 'subdivide)
143 | ((color 0.0 1.0 0.0) (debug . #t) (subdivide . #t) (use-color . #f))
144 |
145 | guile> bool-alist
146 | ((color 0.0 1.0 0.0) (debug . #t) (subdivide . #t) (use-color . #f))
147 |
148 | (assq-remove! bool-alist 'some-other-key)
149 | ((color 1.0 0.0 0.0) (debug . #t) (subdivide . #t) (use-color . #f))
150 | ```
151 |
152 | Please note that *this time* the procedure *does* modify the alist directly.
153 |
--------------------------------------------------------------------------------
/scheme/docs/procedures/lambda.md:
--------------------------------------------------------------------------------
1 | # The `lambda` Expression
2 |
3 | As said in the previous introduction `lambda` is an expression that creates - or
4 | *evaluates to* - a procedure. It has the general form
5 |
6 | ```
7 | (lambda )
8 | ```
9 |
10 | `` is where the *arguments* are specified that the procedure will be
11 | applied to. There are three forms for this specification, and I will discuss
12 | the differences in the next chapter. In this chapter we're using the most common
13 | form.
14 |
15 | `` is an arbitrary number of expressions that is evaluated in
16 | sequence. As usual the value of the last expression will become the value of
17 | the procedure as a whole. But let's consider this with an example:
18 |
19 | ### Creating a procedure
20 |
21 | ```
22 | guile> (lambda (x) (+ x x))
23 | #
24 | ```
25 |
26 | The printed result (remember that the Scheme console immediately prints the
27 | *value* of the expression typed in) gives us three informations: first that it
28 | is a *procedure* that we've created, second that it does *not* have a name (the
29 | `#f`) and finally the expected argument list. What it *doesn't* tell us is how
30 | the procedure creation works. In order to investigate this we reformat the
31 | expression:
32 |
33 | ```
34 | (lambda
35 | (x)
36 | (+ x x)
37 | )
38 | ```
39 |
40 | The first argument to `lambda` is `(x)`. This tells the parser that the
41 | procedure will accept exactly one argument, and this argument will be visible by
42 | the name of `x` in the body of the procedure. When the formals are written as a
43 | list like here then each element of the list represents the name of one actual
44 | parameter the procedure expects.
45 |
46 | The body of the procedure consists of the single expression `(+ x x)` which
47 | simply takes the argument `x` and adds it to itself. The result of this
48 | “duplication” will become the value of the whole procedure.
49 |
50 | #### Parameter types
51 |
52 | Here we can see something in action that has been mentioned much earlier in the
53 | introduction to [data types](../index.html): Scheme does *not* impose any
54 | restriction on the data type that is passed to the procedure, in fact a value of
55 | arbitrary type may be locally *bound* to the name `x`. But as we use `x` in the
56 | expression `(+ x x)` it is clear that only types can be accepted which the `+`
57 | operation can be applied to. Scheme doesn't “guard” procedures against
58 | unsuitable parameters through type-checking, which has its pros and cons. The
59 | problem can be that possible errors occur within the procedure and not at its
60 | interface, which can make them harder to pinpoint. On the other hand this opens
61 | a lot of potential for “polymorphism”, that is the possibility to write a single
62 | interface that behaves differently depending on the type of arguments that are
63 | passed into it. We will discuss this aspect in a [later
64 | chapter](parameter-types.html).
65 |
66 | ### *Using* the Procedure
67 |
68 | Now we have created a procedure, but it doesn't *do* anything yet, so how can we
69 | make use of it? Correct, by *applying* it. Our expression *is* a procedure
70 | expecting one argument, so we can use it like one: `(procedure arg1)`. Usually
71 | when applying a procedure we refer to it by its *name*, but that name doesn't do
72 | anything else than *evaluating to* the procedure itself, so for Scheme it
73 | doesn't make a difference if we use the name or its definition:
74 |
75 | ```
76 | guile>
77 | (
78 | (lambda (x) (+ x x))
79 | 12
80 | )
81 | 24
82 | ```
83 |
84 | We have an enclosing pair of parens to denote the *procedure application*, then
85 | the definition of the procedure in the first position, followed by a number as
86 | the single argument. The expression correctly evaluates to 24, which
87 | corresponds to 12 + 12. You should clearly see that this whole `lambda`
88 | expression is in the place where we'd normally place a procedure name, like
89 |
90 | ```
91 | guile>
92 | (
93 | random
94 | 12
95 | )
96 | 7
97 | ```
98 |
99 | Of course it rarely makes sense to create a procedure just for a single
100 | application, but for now we'll stick to that approach and dedicate a full
101 | chapter to the different ways of binding and reusing procedures.
102 |
103 | ### Multiple Paramters and Expressions
104 |
105 | Our first procedure accepted a single argument, and its body also consisted of a
106 | single expression. But of course multiple arguments and expressions can be
107 | handled:
108 |
109 | ```
110 | guile>
111 | (lambda (x y)
112 | (display (format "X: ~a\n" x))
113 | (display (format "Y: ~a\n" y))
114 | (+ x y))
115 | #
116 | ```
117 |
118 | This procedure will accept two parameters, which will be visible by the names
119 | `x` and `y` in the procedure body. This time the body evaluates three
120 | expressions in sequence: the first two expressions print the input arguments to
121 | the console while the third and last one evaluates the sum of the parameters and
122 | returns that as the whole procedure's value.
123 |
124 | We can apply this procedure the same way as the previous one, although it starts
125 | to get awkward doing that in the Scheme REPL that doesn't forgive any typing
126 | errors:
127 |
128 | ```
129 | guile>
130 | ((lambda (x y)
131 | (display (format "X: ~a\n" x))
132 | (display (format "Y: ~a\n" y))
133 | (+ x y))
134 | 9
135 | 12)
136 | X: 9
137 | Y: 12
138 | 21
139 | ```
140 |
141 | In the last three lines we can see the printout from the `display` procedure and
142 | finally the *value* of the expression. *(You may make a mental note of the
143 | characteristic double paren at the opening of this expression.)*
144 |
--------------------------------------------------------------------------------
/scheme/docs/data-types/strings.md:
--------------------------------------------------------------------------------
1 | # Strings
2 |
3 | [Strings](https://en.wikipedia.org/wiki/String_%28computer_science%29) are
4 | sequences of characters and more or less handle what we see as *text* in
5 | documents. From the perspective of data processing and programming languages
6 | dealing with strings is surprisingly complex, and working with strings is a
7 | fundamental task also when you're writing Scheme in LilyPond. Guile provides a
8 | large number of functions for string processing, but we'll only cover a few
9 | specific aspects in this “data types” introduction. You can find all details
10 | about Scheme's string processing in the [Guile
11 | manual](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Strings.html#Strings).
12 |
13 | ### Writing Strings
14 |
15 | In Scheme strings are always written using *double* quotes. Other languages
16 | understand single and double quotes interchangeably or with subtly different
17 | meanings, but single quotes are reserved for a completely different purpose in
18 | Scheme:
19 |
20 | ```
21 | guile> "Hello"
22 | "Hello"
23 |
24 | guile> Hello
25 | ERROR: Unbound variable: Hello
26 | ABORT: (unbound-variable)
27 |
28 | guile> 'Hello'
29 | Hello'
30 | ```
31 |
32 | The first example enters a *string* that evaluates to itself - strings are
33 | self-evaluating, literals, constants in Scheme. The second example interprets
34 | the input as a name for a variable that has not been defined yet. And the final
35 | example interprets the input as a “quoted symbol”, with the trailing single
36 | quote characteristically being part of the symbol. You will read more about
37 | both cases in [symbols](symbols.html) and [quoting](../quoting.html).
38 |
39 | As you have seen in the section about [including Scheme in
40 | LilyPond](../including.html) LilyPond's parser treats strings specially and
41 | doesn't require an explicit switch to Scheme mode through `#`. For all strings
42 | that don't contain any special characters and that are single words you don't
43 | even have to use quotation marks. As said the first three of the follwoing
44 | assignments are equivalent while for the last one the quotation marks are
45 | mandatory:
46 |
47 | ```lilypond
48 | \header {
49 | title = #"MyPiece"
50 | title = "MyPiece"
51 | title = MyPiece
52 | title = "My Piece"
53 | }
54 | ```
55 |
56 |
57 | ### Escaping Special Characters
58 |
59 | There are a number of special characters that can't directly be inserted in
60 | strings, although Guile/LilyPond supports Unicode out-of-the-box. Inserting
61 | such non-standard characters is done using “escaping”: the parser sees an
62 | *escape character* and treats the immediately following content as a special
63 | object. In Scheme - just like in many other languages - this escape character
64 | is the `\` backslash.
65 |
66 | #### Quotation Marks
67 |
68 | The most obvious character that has to be escaped is the double quote itself -
69 | as the parser would interpret this as the *end* of the string by default:
70 |
71 | ```lilypond
72 | \header {
73 | title = "My \"Escape\" to Character Land"
74 | subtitle = "Where things can go "terribly" wrong"
75 | }
76 | ```
77 |
78 | In this example the title is escaped correctly while in the second example the
79 | quotes break the string variable, which you can already see from the syntax
80 | highlighting. LilyPond will in this case produce a pretty confusing error
81 | message but will at least point you to the offending line of the input file.
82 |
83 | *Note:* this is only true for straight double quotes. From a typographical
84 | *perspective it is often better to use typographical (or "curly") quotes anyway
85 | *(e.g. `“English”`, `„Deutsch“` or `«Français»`). These don't need escaping.
86 |
87 | #### The backslash
88 |
89 | So if the backslash is used to indicate an escape character how can a backslash
90 | be used as a character in text? Well, in a way that's self-explaining: through
91 | escaping it. To print a backslash you have to escape it - with a backslash:
92 |
93 | ```lilypond
94 | \markup "This explains the \\markup command."
95 | ```
96 |
97 | #### Arbitrary Escaped Characters
98 |
99 | There is a list of other special ASCII characters in the
100 | [reference](https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/String-Syntax.html#String-Syntax)
101 | from which you're most likely to come across the *newline* `\n` and the
102 | *tabulator* `\t` escape sequences.
103 |
104 | However, there's a last item we want to discuss here: arbitrary special
105 | characters. The reference page linked just above states that using the `\x`
106 | escape sequence it is possible to address characters numerically. But while
107 | this only works for the very limited set of ASCII characters and doesn't support
108 | Unicode in general, this isn't generally possible for use in LilyPond strings.
109 | There are cases where it is possible while others don't work, but it can be said
110 | that it is generally not recommended. Instead there are two options to
111 | include special characters, apart from the option of directly including the
112 | special characters in the input files - if all participating modules support
113 | that.
114 |
115 | It is possible to encode special characters using their Unicode code point
116 | either as hexadecimal or as decimal numbers. Alternatively LilyPond provides a
117 | number of ASCII escape sequences which can be made available from within a
118 | `\paper` block:
119 |
120 | ```lilypond
121 | \paper {
122 | #(include-special-characters)
123 | }
124 | ```
125 |
126 | Both options as well as a list of escape sequences (which are modeled after HTML
127 | escape sequences) can be found in LilyPond's
128 | [documentation](http://lilypond.org/doc/v2.19/Documentation/source/Documentation/notation/special-characters)
129 |
--------------------------------------------------------------------------------
/scheme/docs/conditionals/logical.md:
--------------------------------------------------------------------------------
1 | # Logical Operators: `not/and/or`
2 |
3 | Often conditional switches are more complex than a simple true/false decision.
4 | Sometimes it is more convenient to ask if something is *false* than if it's
5 | *true*, and regularly multiple conditions have to be considered in relation. To
6 | achieve this Scheme offers the procedures `not`, `and` and `or`.
7 |
8 | ### `not`
9 |
10 | `not` is basically the inversion of a test: it returns `#t` if the expression it
11 | tests evaluates to `#f` and to `#f` in all other cases.
12 |
13 | ```
14 | guile> (not #f)
15 | #t
16 |
17 | guile> (not #t)
18 | #f
19 |
20 | guile> (not '(1 2 3))
21 | #f
22 |
23 | guile> (not (< 2 1))
24 | #t
25 | ```
26 |
27 | The first two expressions are clear, `not` simply inverts the boolean literals.
28 | The third example shows that *any* object has a “true value” and is inverted to
29 | `#f`. The final example demonstrates that the value passed to `not` can (of
30 | course) be a complete expression which in this case evaluates to `#f`, which is
31 | then inverted by the `not`.
32 |
33 | ### `and`
34 |
35 | `and` takes any number of subexpressions and evaluates them one after another
36 | until any one evaluates to `#f`. In this case the `and` expression evaluates to
37 | `#f` as well. If *all* subexpressions evaluate to a true value the `and`
38 | returns the value of the last subexpression. This is an important point: `and`
39 | does *not* evaluate to `#t` or `#f` as one might expect, instead it evaluates to
40 | `#f` or an arbitrary value. You have to take that into account when you need to
41 | *use* that value:
42 |
43 | ```
44 | guile>
45 | (and
46 | #t
47 | (> 2 1)
48 | (odd? 2)
49 | "Hi")
50 | #f
51 | ```
52 |
53 | This expression holds four subexpressions that are tested sequentially:
54 |
55 | * `#t` is obviously a true value
56 | * `(> 2 1)` evaluates to `#t` as 2 *is* greater than 1
57 | * `(odd? 2)` evaluates to `#f` as 2 is *not* an odd number
58 | * "Hi" *would* be considered a true value, but it isn't tested anymore because
59 | `and` has exited already upon the previous subexpression.
60 |
61 | ```
62 | guile>
63 | (and
64 | '(1 . 2)
65 | (list? '())
66 | #t
67 | '(1 2 3))
68 | (1 2 3)
69 | ```
70 |
71 | In this `and` expression *all* subexpressions have true values, therefore the
72 | whole expression evaluates to the value of the last subexpression, the list `(1
73 | 2 3)`. So this is where you must *not* expect `#t` but rather *any*
74 | true value.
75 |
76 | ### `or`
77 |
78 | `or` behaves very similarly to `and`, except that it returns a subexpression's
79 | value as soon as that returns a true value. Only if none of the subexpressions
80 | return true values the `or` expression returns `#f`. And as with `and` you have
81 | to expect “a true value” and not `#t` for the successful subexpression.
82 |
83 | In the case of `or` this can be used very straightforwardly to provide
84 | fallthrough values: check for a number of tests, and if all fail return the
85 | fallback value as the last subexpression. For example we can easily rewrite the
86 | test from the previous chapter using `or`:
87 |
88 | ```lilypond
89 | colors =
90 | #`((col-red . ,red)
91 | (col-blue . ,blue)
92 | (col-yellow . ,yellow))
93 |
94 | #(display
95 | (or
96 | (assq 'col-lime colors)
97 | (assq 'col-darkblue colors)
98 | (assq 'col-red colors)
99 | (cons 'black black)))
100 | ```
101 |
102 | ## Nesting of Logical expressions
103 |
104 | When more than one condition have to be nested dealing with “operator
105 | precedence” is a confusing issue in many languages: which conditionals are
106 | evaluated first, do we therefore have to group them with brackets, etc.?
107 | Scheme's approach to this topic is very straightforward, and once you get the
108 | fundamental idea it is no magic anymore: Each conditional expression tests one
109 | single value, and that value can be the result of another logic expression.
110 | Period. From there you can create arbitrary levels of nesting.
111 |
112 | What does the expression `(not (and #t #f))` return and why? We have a `not`
113 | which will invert the boolean state of the value it is applied to. That value
114 | is the expression `(and #t #f)`, which will evaluate to `#f`. So the first
115 | evaluation step is to evaluate the inner expression, which leads to `(not #f)`,
116 | which eventually results in `#t`.
117 |
118 | Let's inspect a more complex expression:
119 |
120 | ```
121 | (or (not (> 2 1)) (and #t '() (> 4 5)) "Hehe")
122 | ```
123 |
124 | This is an `or` expression with three subexpressions: `(not (> 2 1))`, `(and #t '() (>
125 | 4 5))` and `"Hehe"`. `or` will evaluate each of these subexpressions from left
126 | to right, and once *any* subexpression eavaluates to anything other than `#f` it
127 | will return that subexpression's value. So let's retrace that one by one:
128 |
129 | ```
130 | (not (> 2 1))
131 | (not #t )
132 | #f
133 | ```
134 |
135 | The first subexpression evaluates to `#f` so we have to continue. The second
136 | subexpression is an `and` expression which itself has multiple subexpressions:
137 | `#t`, `'()` and `(> 4 5)`:
138 |
139 | ```
140 | #t
141 | #t ; a true value
142 |
143 | '()
144 | () ; a true value
145 |
146 | (> 4 5)
147 | #f
148 | ```
149 |
150 | The first two subexpressions of the `and` have true values, but the last one is
151 | `#f`, therefore the whole `and` subexpression evaluates to `#f`, and we have to
152 | continue with the last subexpression, `"Hehe"`. This subexpression has a true
153 | value, so finally our `or` returns that one and can be considered successful.
154 |
155 | As a conclusion, nested logical expressions in Scheme are just like any other
156 | nested expressions: they have to be evaluated one by one, from inside to outside
157 | and in the case of `and` and `or` from left to right, and so everything can be
158 | resolved unambiguously.
159 |
--------------------------------------------------------------------------------
/scheme/docs/binding/let.md:
--------------------------------------------------------------------------------
1 | # Local Binding with `let`
2 |
3 | The basic form for local bindings is `let`, which we'll explore in most detail.
4 | The companion procedures `let*` and `letrec` can then be shown quite concisely.
5 | As an example we'll implement a color damper that damps the RGB components of a
6 | color by a given factor. In order to benefit from color highlighting and easier
7 | editing we will do that in LilyPond files and not on the Scheme REPL.
8 |
9 | The typical use case for `let` expressions is within procedures where we would
10 | get the original data from the procedure arguments. But for the sake of our
11 | example we simply create a global variable that we can then reference:
12 |
13 | ```lilypond
14 | % Create a pair with a color and a damping factor
15 | #(define props (cons yellow 1.3))
16 | ```
17 |
18 | `props` is now `((1.0 1.0 0.0) . 1.3)`, a pair with a list for the yellow color
19 | and a number for the damping factor. What we need to do with it is pretty
20 | simple: just create a new list with three elements where each element is the
21 | corresponding element from the `car` of `props` divided by the factor stored in
22 | the `cdr` of `props`. In order to later display the value (and to practice) we
23 | bind the resulting list to a top-level variable defined in LilyPond syntax:
24 |
25 | ```lilypond
26 | dampedYellow =
27 | #(list
28 | (/ (first (car props)) (cdr props))
29 | (/ (second (car props)) (cdr props))
30 | (/ (third (car props)) (cdr props)))
31 |
32 | #(display dampedYellow)
33 | ```
34 |
35 | which will print `(0.769230769230769 0.769230769230769 0.0)` to the console.
36 | (You could also use that variable to override a `color` property of a grob, by
37 | the way.)
38 |
39 | So what's the problem with that? It's the redundancy of the calls to `car` and
40 | `cdr`, three times for each. Each time we need the color or the damping factor
41 | we have to access the original variable and extract the data from it. In the
42 | case of `car` and `cdr` this is not a real issue but in real-world code one will
43 | have expressions that are considerably more complicated to write *and*
44 | computationally more expensive.
45 |
46 | The solution is to create local bindings of the values of `(car props)` and
47 | `(cdr props)` and then refer to these bindings within the body of the
48 | expression. This is done with the `let` expression that takes the general form
49 |
50 | ```
51 | (let () exp1 exp2 ...)
52 | ```
53 |
54 | or, displayed in a more hierarchical manner:
55 |
56 | ```
57 | (let
58 | (
59 |
60 |
61 | ...
62 | )
63 |
64 |
65 | ...
66 | )
67 | ```
68 |
69 | The `let` expression has two parts, the *bindings* and the *body*, where each
70 | part must have *at least* one entry. The bindings are enclosed by parens as a
71 | whole, and each binding has the form `(name value)` where `name` is a symbol
72 | (the “name” of the local binding) and `value` any Scheme value. While the value
73 | could be of any type including literal values the whole point of it is to bind
74 | the results of complex expressions to simple names.
75 |
76 | In our example we create two bindings, one for the color and one for the damping
77 | factors, which looks like this:
78 |
79 | ```
80 | (let
81 | (
82 | (color (car props))
83 | (damping (cdr props))
84 | )
85 |
86 |
87 | ...
88 | )
89 | ```
90 |
91 | Now we have two “local variables”, `color` and `damping` that are visible and
92 | accessible from within the *body* of the `let` expression.
93 |
94 | This body of a `let` expression is an arbitrary number of expressions that is
95 | evaluated in sequence. Note that - different from the bindings - there is *no*
96 | extra layer of parens around the body. The value of the *final* expression will
97 | become the value of the `let` expression as a whole. In our example we only
98 | have *one* expression, the `list` creation. But instead of repeatedly calling
99 | `car` and `cdr` we can now use the local variables directly.
100 |
101 | As this `list` expression is the only (and therefore last) in the body the whole
102 | `let` expression evaluates to the created list, and this value (with the damped
103 | color) is bound to the top-level variable:
104 |
105 | ```lilypond
106 | dampedYellowWithLet =
107 | #(let
108 | (
109 | (color (car props))
110 | (damping (cdr props))
111 | )
112 | (list
113 | (/ (first color) damping)
114 | (/ (second color) damping)
115 | (/ (third color) damping)
116 | )
117 | )
118 |
119 | #(display dampedYellowWithLet)
120 | ```
121 |
122 | which will print the same result as before.
123 |
124 | The indentation of the previous example was pretty unidiomatic and intended to
125 | exemplify how we constructed the expression step by step. Usually one would use
126 | a more condensed way, for example
127 |
128 | ```lilypond
129 | dampedYellowWithLet =
130 | #(let ((color (car props))
131 | (damping (cdr props)))
132 | (list
133 | (/ (first color) damping)
134 | (/ (second color) damping)
135 | (/ (third color) damping)))
136 | ```
137 |
138 | You may think that this expression is considerably more complex than our
139 | initial, direct application of `list`. But as mentioned the `car` and `cdr`
140 | expressions are comparably simple, and the “complexity ratio” will change
141 | dramatically with more complex expressions.
142 |
143 | The nesting and parenthesizing levels in that code look daunting, but indeed
144 | they are the result of a completely consequent structure, and (in theory)
145 | there's no room for misunderstandings. However, the frustrating truth is that
146 | in practice (for the beginner) it *is* a miracle how and where to place the
147 | parens, and the error messages aren't really encouraging, to say the least.
148 | Therefore I have written a dedicated chapter discussing the typical error
149 | conditions we tend to produce.
150 |
--------------------------------------------------------------------------------
/scheme/docs/conditionals/cond.md:
--------------------------------------------------------------------------------
1 | # `cond`
2 |
3 | The `cond` conditional is used when there are more than two options to handle.
4 | All the considerations about “true values” and the evaluation of subexpressions
5 | discussed in the previous chapter about `if` apply here as well, so if anything
6 | is unclear please refer to that chapter.
7 |
8 | The general form of a `cond` expression is
9 |
10 | ```
11 | (cond
12 | (clause1)
13 | (clause2)
14 | ...
15 | )
16 | ```
17 |
18 | Each *clause* starts with a test, and if the test succeeds the clause is
19 | evaluated and its value returned. The last clause may have the keyword `else`
20 | instead of a test, and if none of the previous tests succeeds this final else
21 | clause is evaluated.
22 |
23 | ### Different Forms of clauses
24 |
25 | I just wrote that the clauses are evaluated if their test succeeds, but that's a
26 | little bit sloppy. Actually there are three different forms of valid clauses,
27 | and the evaluation is different in each. The point was mainly that the first
28 | successful test determines which clause is responsible for the return value.
29 |
30 | #### The Most Common Form
31 |
32 | The most common form for each clause is
33 |
34 | ```
35 | (test exp1 exp2 ...)
36 | ```
37 |
38 | In this case one or more expressions are evaluated and the value of the last
39 | expression is returned as the value of the `cond` expression:
40 |
41 | ```lilypond
42 | #(display
43 | (let ((rand (random 100)))
44 | (cond
45 | ((> rand 50)
46 | (display rand)
47 | (newline)
48 | "Random number is greater than 50")
49 | ((< rand 50)
50 | (display rand)
51 | (newline)
52 | "Random number is smaller than 50")
53 | (else
54 | (display rand)
55 | (newline)
56 | "Random number equals 50"))))
57 | ```
58 |
59 | First we generate a random integer and locally bind it to `rand`. In the `cond`
60 | expression we have three cases, expressed by two tests and an else clause. In
61 | each clause three expressions are evaluated, and the third - a literal string -
62 | is returned as the value of the `cond` expression, which is passed along as the
63 | value of the `let` expression as well. Note that the `cond` expression itself
64 | is surrounded by parens as well as each individual clause, but the expressions
65 | *within* the clauses are not.
66 |
67 | #### Test Only
68 |
69 | Another form for the clauses is
70 |
71 | ```
72 | (test)
73 | ```
74 |
75 | If a clause is expressed in this way a successful test will directly return its
76 | value, without evaluating further expressions. This is where the concept of
77 | “true values” comes into play: if the test returns a value that is considered
78 | “true” we can directly use it. In the chapter about [retrieval from
79 | alists](../alists/retrieving.html) we learned about the `assq` procedure that will
80 | return either a key-value pair from an association list or `#f` if the given key
81 | is not present in the alist. This way we can directly return the resulting
82 | entry or pass control along to the next clause. The following example creates
83 | an alist of colors and then tries to retrieve a color through a `cond`
84 | expression (in real life we would get the alist from “somewhere” so we don't
85 | know which keys it contains):
86 |
87 | ```lilypond
88 | colors =
89 | #`((col-red . ,red)
90 | (col-blue . ,blue)
91 | (col-yellow . ,yellow))
92 |
93 | #(display
94 | (cond
95 | ((assq 'col-lime colors))
96 | ((assq 'col-darkblue colors))
97 | ((assq 'col-red colors))
98 | (else `(col-black . ,black))))
99 | ```
100 |
101 | `assq` will return `#f` for the first two tests because the given keys are not
102 | in the `colors` alist. However, the third test gives a match with the
103 | `'col-red` key, therefore the `assq` expression evaluates to the pair `(col-red
104 | 1.0 0.0 0.0)`. Since this is a “true” value it is returned as the value of the
105 | `cond` expression and consequently printed to the console. If none of the tests
106 | would succeed the `else` clause would create a pair with the same structure as
107 | the pairs returned by the other clauses, so anyone *using* the return value
108 | would surely get valid data.
109 |
110 | #### Apply a Procedure to the Test Result
111 |
112 | A final form for the clauses is
113 |
114 | ```
115 | (test => proc)
116 | ```
117 |
118 | In this case `proc` should be a procedure that takes exactly one argument. If
119 | the test returns a true value `proc` will be applied to this result. We can use
120 | this form to improve our previous example so that it only returns the actual
121 | color part of the alist entry:
122 |
123 | ```lilypond
124 | #(display
125 | (cond
126 | ((assq 'col-lime colors) => cdr)
127 | ((assq 'col-darkblue colors) => cdr)
128 | ((assq 'col-red colors) => cdr)
129 | (else black)))
130 | ```
131 |
132 | We perform the same test as before, but when it returns the pair this pair will
133 | be passed to the procedure `cdr` which will directly extract the second part of
134 | the pair. The `else` clause has been adjusted accordingly.
135 |
136 | This form is actually a very nice form of ”syntactic sugar” because it greatly
137 | simplifies that task. Of course we could get the same result - the color part
138 | extracted from the pair - with the other forms as well, but in an unnecessarily
139 | complicated way. The relevant clause could for example be written like this:
140 |
141 | ```lilypond
142 | ((assq 'col-red colors)
143 | (cdr (assq 'col-red colors)))
144 | ```
145 |
146 | Once we know that we're at the right key we can retrieve the value again and
147 | pass it along to `car`, which seems pretty inefficient. So we can avoid using
148 | `assq` twice by hooking in a local binding:
149 |
150 | ```lilypond
151 | ((let ((result (assq 'col-red colors)))
152 | (if result
153 | (cdr result)
154 | #f)))
155 | ```
156 |
157 | Basically this makes use of the previous form, as the `let` expression evaluates
158 | to either the color or to `#f`. Apart from that hint I leave it to you to
159 | dissect this expression as an exercise to repeat the topic of local binding.
160 | But honestly, `((assq 'col-red colors) => cdr)` is much more elegant, isn't it?
161 |
--------------------------------------------------------------------------------
/scheme/docs/including.md:
--------------------------------------------------------------------------------
1 | # Including Scheme in LilyPond
2 |
3 | The first thing to understand is how - on a very basic level - Scheme code can
4 | be used in LilyPond documents. So this is what we will first investigate.
5 |
6 | *Note: With LilyPond 2.19.22 some *substantial* simplifications have been
7 | introduced in how Scheme can be integrated in LilyPond code. In case of doubt
8 | this book will strongly prefer the *new* syntax and exclusively explain this.*
9 |
10 | ## Switching Between LilyPond and Scheme
11 |
12 | In order to insert code in a different language the parser must discern between
13 | the two layers, which it does through the `#` sign that marks the transition
14 | from LilyPond to Scheme. Concretely, whenever the parser encounters this marker
15 | it will interpret the *immediately following code* as a *Scheme expression*.
16 |
17 | So to insert any Scheme expression into a LilyPond document you have to prepend
18 | it with `#`. The best way to understand this is to see it in action. More or
19 | less *any* LilyPond user will already have assigned a Scheme value to an
20 | override:
21 |
22 | ```lilypond
23 | {
24 | \once \override DynamicText.extra-offset = #'(2 . 1)
25 | }
26 | ```
27 |
28 | The `#` tells LilyPond's parser to parse one complete Scheme expression, which
29 | happens to be the *pair* `'(2 . 1)` (a later [chapter](data-types/index.html)
30 | will go into more details about Scheme's data types.)
31 |
32 | #### Exceptions
33 |
34 | LilyPond very much “thinks” like Scheme, and all input will internally be
35 | converted to Scheme. Therefore some data types can be entered literally,
36 | without explicitly switching to Scheme, and the following number assignments are
37 | equivalent:
38 |
39 | ```lilypond
40 | {
41 | \once \override Stem.length = #7.5
42 | \once \override Stem.length = 7.5
43 | }
44 | ```
45 |
46 | This feels very natural, but it can cause some confusion once one starts
47 | thinking about it. The point is that it is actually the *LilyPond* parser that
48 | performs this transparent conversion.
49 |
50 | The same is true for strings *(TODO: should it be explained what a ”string”
51 | is?)* that can additionally be written with or without double quotes (*NOTE:*
52 | LilyPond/Scheme strings *have* to use *double* quotes, as single quotes have a
53 | completely different meaning). Again, the following assignments are equivalent:
54 |
55 | ```lilypond
56 | \header {
57 | title = #"MyPiece"
58 | title = "MyPiece"
59 | title = MyPiece
60 | }
61 | ```
62 |
63 | The first one is the “regular” Scheme syntax: switching to Scheme mode, then
64 | writing a proper string with quotes. The other ones are simplifications made
65 | possible through LilyPond's parser. But in all three cases the variable
66 | `title` now refers to the *string* `MyPiece`. *Note:* the third version is only
67 | possible with single words. Something like `"My Piece"` *must* be enclosed in
68 | the quotes.
69 |
70 | There are a few other data types where this is possible, but we will discuss
71 | them at a later point. For now you should only keep in mind that you have to
72 | use `#` to switch to Scheme syntax - but not *always*.
73 |
74 | #### Displaying Scheme Values
75 |
76 | Sometimes it is necessary, and for learning it is often enlightening, to print
77 | some Scheme values to the console. To start with, there are two ways to do so,
78 | using Scheme's `display` procedure or LilyPond's `ly:message` family of
79 | functions:
80 |
81 | ```lilypond
82 | myVariable = "This is a variable"
83 |
84 | #(display myVariable)
85 | #(ly:message myVariable)
86 | ```
87 |
88 | There are some notable differences between the commands:
89 |
90 | * `display` can show *any* value while `ly:message` only processes strings
91 | (but this can be circumvented using the `format` procedure)
92 | * `display` will not produce a newline, so that should always be done manually
93 | (through `#(newline)`)
94 | * `ly:message` will print immediately while `display` only acts after parsing
95 | has been finished.
96 |
97 | We will regularly use these methods for demonstrating parts of our code in the
98 | subsequent chapters.
99 |
100 | #### LilyPond and Scheme variables
101 |
102 | Another thing to note is that LilyPond variables are interchangeable with Scheme
103 | variables in LilyPond input files. Variables can be defined using either
104 | syntax:
105 |
106 | ```lilypond
107 | % define a variable using LilyPond syntax
108 | bpmA = 60
109 |
110 | % define a variable using Scheme syntax
111 | #(define bpmB 72)
112 | ```
113 |
114 | We have two variables, `bpmA` and `bpmB`, one of which has been entered as a
115 | LilyPond variable, the other as a Scheme variable (as an exercise you can think about
116 | this expression in the light of what you learnt in the previous chapter). But
117 | internally they are now the same kind of variable and can be accessed in the
118 | same way:
119 |
120 | ```lilypond
121 | {
122 | % assign a tempo using a literal value
123 | \tempo 8 = 54
124 | R1
125 |
126 | % assign tempos using the variables with LilyPond syntax
127 | \tempo 8 = \bpmA
128 | R1
129 |
130 | \tempo 8 = \bpmB
131 | R1
132 | }
133 | ```
134 |
135 | However, as they are stored as Scheme variables internally we can also refer to
136 | them using the Scheme syntax (i.e. switching to Scheme with `#` but *not*
137 | enclosing them in parens, as these variables are constants or self-evaluating
138 | expressions):
139 |
140 | ```lilypond
141 | {
142 | % assign tempos by referencing variables using Scheme
143 | \tempo 8 = #bpmA
144 | R1
145 |
146 | \tempo 8 = #bpmB
147 | R1
148 | }
149 | ```
150 |
151 | Each of these ways to access the variables will work interchangeably, and it
152 | depends on the context which one should be used. This flexibility may seem
153 | confusing but it helps if you strictly remember that *all* values and variables
154 | are maintained as Scheme structures internally and that setting and accessing
155 | them can always be done through Scheme or LilyPond syntax.
156 |
157 |
158 |
--------------------------------------------------------------------------------
/scheme/docs/procedures/binding.md:
--------------------------------------------------------------------------------
1 | # Binding Procedures
2 |
3 | Procedures are *objects* like everything else in Scheme, and therefore
4 | procedures can be *bound* to names just like any other variable. Not all
5 | programming languages support this handling of procedures as [first-class
6 | functions](https://en.wikipedia.org/wiki/First-class_function). This typical
7 | concept of *functional programming* languages allows to pass functions as
8 | arguments to and return them from functions. And just as with other objects we
9 | can bind procedures locally or globally.
10 |
11 |
12 | ### Top-level Binding of Procedures
13 |
14 | When a procedure has been bound to a global name it can be used from anywhere in
15 | the program, just like the built-in procedures or those provided by LilyPond.
16 | Basically we do exactly the same as with other
17 | [top-level](../binding/top-level.html) bindings of variables:
18 |
19 | ```
20 | (define