2018-11-10

The Thing

Danish: You look like you're going to spend your life having one epiphany after another, always thinking you've finally figured out what's holding you back, and how you can finally be productive and creative and turn your life around. But nothing will ever change. That cycle of mediocrity isn't due to some obstacle. It's who you are. The thing standing in the way of your dreams is; that the person having them is you.

Danish really has my number.

2018-07-19

Tclook

I seem to have created a basic tool to inspect TclOO objects and classes (etc).

https://github.com/hoodiecrow/Tclook

2018-04-10

Just like a woman


I mean, it's uncanny. Trying to distinguish that from an actual female author's writing would be like finding a needle in a haystack. If the needle is strongly magnetic. And has a blinking LED light and emits a small "beep" sound now and then. And there isn't very much hay.

More (Huffington Post)

2018-02-27

Feb 27

I was looking idly at http://yourbasic.org/golang/go-vs-java/, and my fingers started walking.

The most basic Tcl source for this I can think of is

proc Real c {lindex $c 0}
proc Imag c {lindex $c end}

proc Add {c d} {
    lmap c $c d $d {expr {$c + $d}}
}

proc String c {
    if {[lindex $c end] < 0} {
        format (%g%gi) {*}$c
    } else {
        format (%g+%gi) {*}$c
    }
}

set z {1 2}
String [Add $z $z]
But that's close to cheating. Let's at least make a class for it:
oo::class create Complex {
    variable re im
    constructor args {
        lassign $args re im
        if {$re != $re || $im != $im} {
            set msg {domain error: argument not in valid range}
            throw [list ARITH DOMAIN $msg] $msg
        }
    }
    method real {} {set re}
    method imag {} {set im}
    method add d {
        Complex new [expr {$re + [$d real]}] [expr {$im + [$d imag]}]
    }
    method string {} {
        if {$im < 0} {
            format (%g%gi) $re $im
        } else {
            format (%g+%gi) $re $im
        }
    }
}

set z [Complex new 1 2]
[$z add $z] string 
And that's it. Not a big deal. Unless you're working with Java, of course.

The biggest wart AFAICS is that Tcl doesn't allow implied conversions to string: everything has a string representation, but Tcl decides what it is. In the first code, this works in our favor, as the standard string representation (a string that is a list of two numbers) is identical to the model I used for complex numbers. Without calling String, the result of Add $z $z is 2 4, which is immediately useful both for printing and for further calculations.

In the second code, the string pseudo-representation is ::oo::Obj99 (or some other number), i.e. the name of the object command. The method string needs to be called explicitly to get a printable string that shows the data content.

Note that Tcl's expr command throws an exception with the message "domain error: argument not in valid range" instead of dumping a "NaN" message. You can still figure out that it was a NaN by looking at the message or by comparing the number to itself, as I'm doing here. I could have signalled the problem with the invocation "error NaN", but chose to emulate Tcl's handling instead.

2017-12-18

Ruby-style accessors in TclOO

A way to get Ruby-style accessors in TclOO. Inspired by code on the Tcl Wiki by “anonymous”, improved by Nathan Coulter. This code has been posted to the Wiki as well.

Accessors let you declare instance variables and getter and/or setter methods for them at the same time. The attr_reader and attr_accessor commands declare one or more variables and also methods for them with the same name, which return the current value of the variable. The attr_writer and attr_accessor commands declare one or more variables and also methods for them with the same name with an appended =, which take a value argument and set the variable to that value. So attr_accessor foo bar  declares the variables foo and bar , the getter methods foo and bar , and the setter methods foo= and bar=

namespace eval oo::define {
    proc attr {access args} {
        set class [lindex [info level -1] 1]
        ::oo::define $class variable {*}$args
        if {"reader" in $access} {
            foreach name $args {
                ::oo::define $class method $name {} \
                    [format {set %s} $name]
            }
        }
        if {"writer" in $access} {
            foreach name $args {
                ::oo::define $class method $name= v \
                    [format {set %s $v} $name]
            }
        }
    }
     
    interp alias {} attr_reader {} ::oo::define::attr reader
    interp alias {} attr_writer {} ::oo::define::attr writer
    interp alias {} attr_accessor {} ::oo::define::attr {reader writer}
}

2017-12-17

Defining a callback in Tcl

I have posted this text on the Tcl wiki as well.

Tcl uses the callback protocol for everything from higher-order functions to event-driven programming. As with so many other things Tcl, callbacks are fairly straightforward. Still, some explanation can be useful.

What is a callback?

A callback is "executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at a given time" ([1], [2]).

In some cases, as when a -command option is passed to lsort, the receiving command (see below) immediately executes the code (blocking, or synchronous, callback). More commonly, a callback is specified in an after, bind, trace, I/O handler, or widget -command option, etc, and called when appropriate (event-oriented, deferred, or asynchronous, callback). A deferred callback must be able to execute even if the context where it was defined has since been destroyed.

2016-08-22

The structure of water

This is a nice quote:
In my experience, the best programming languages for just writing programs are those which have "the structure of water" as a zen enthusiast I once knew explained it. They can be deformed infinitely, without stress, to fit the shape their environment requires.
So, yes, I really and truly do prefer a multiparadigm language with a reasonably small, general working vocabulary, that doesn't make design choices for me. I like languages where object-oriented and functional programming (and imperative, and stream-oriented, and data-directed, etc) are all Things You Can Do rather than being The Only Way The Language Works.

Looking back on my own programming career, I find that the languages I have liked best (Lisp, C, Tcl) are very much like this description. The languages I have tried and given up on (Perl, Java, Python, C++) are more or less the opposite (Perl and C++ were designed to fit any user, but grew to be unwieldy and demanding).

2015-09-03

Hello, world!

The classic first demonstration program.

pack [button .b -text "Hello, world!" -command exit]

In a Tcl/Tk shell such as wish, this program creates a window and places a plain, unstyled button on it. The text on the button is "Hello, world!" and when you click the button, the program exits.

If you just want to print the text inside the shell, try

puts "Hello, world!"

2015-09-01

Writing sequentially

The challenge is as follows.

1) Pick out code5, the second part of the last word on the last line of this data file:

line1 1 2 3 4 5 end-code1-line
line2 2 2 3 4 5 end-code2-line
line3 3 2 3 4 5 end-code3-line
line4 4 2 3 4 5 end-code4-line
line5 5 2 3 4 5 end-code5-line

2) Do so by executing commands written sequentially ("pipelining" the data from one command to the next).

What we need to do is to read the data from the file, remove ("trim") whitespace from the beginning and end of it, split it into lines, pick the last line, split it into words, pick the last word, split it at the dashes, choose the second element of it.

The most natural way to solve this in Tcl is something like

package require fileutil

set data [string trim [::fileutil::cat lines.txt]]
set line [lindex [split $data \n] end]
set word [lindex [split $line] end]
lindex [split $word -] 1

This is not written in sequential order. The first command to be executed on each line is the one in the innermost brackets, then the command in the enclosing set of brackets, and so on.

The same code in sequential order looks like this:

package require fileutil

set v lines.txt
set v [::fileutil::cat $v]
set v [string trim $v]
set v [split $v \n]
set v [lindex $v end]
set v [split $v]
set v [lindex $v end]
set v [split $v -]
lindex $v 1

This works, but this is Tcl. We can abstract away a lot of detail here.

One idea is to enumerate the commands to be applied to the data and execute them in a loop:

proc seq {v cmds} {
    foreach cmd $cmds {
        set v [{*}$cmd $v]
    }
    set v
}

seq lines.txt {::fileutil::cat {string trim}}

But that only works as far as the string trim. The next command, to split the lines, requires a second argument.

We can solve that by creating command aliases:

interp alias {} lines {} apply {v {split $v \n}}
interp alias {} words {} split
interp alias {} last {} apply {v {lindex $v end}}

One of those, words, is unnecessary since that invocation doesn't need any further argument. It makes the code a bit clearer, though.

The other aliases work by rewriting invocations: the invocation last {a b c} is rewritten as lindex {a b c} end and so on.

Now we can perform the processing as far as seq lines.txt {::fileutil::cat {string trim} lines last words last}. The last two commands could have been aliased the same way, but let's be a bit more creative. If we define the convention that a command that contains the character / has an attached argument, we can let our code do the same rewriting as the aliases do.

proc seq {v cmds} {
    foreach cmd $cmds {
        if {[string match */* $cmd]} {
            set cmd [list apply [list v [regsub / $cmd { $v }]]]
        }
        set v [{*}$cmd $v]
    }
    set v
}

The if looks a little busy, but it's actually quite straightforward. The condition is that if $cmd contains a slash character somewhere (the asterisks state that there may be, but doesn't have to be, characters before and after the slash). Then a regsub command replaces that slash with the text { $v }, i.e. space, dollar, v, space. The resulting string is wrapped in a list with the text v as first element, and then that is wrapped in a list with apply as first element. The result becomes the rewritten command: if we had lindex/end, we now have {apply {v {lindex $v end}}}, which can be executed by set v [{*}$cmd $v].

And we can finally write the procedure sequentially. Compare with the second program above.

seq lines.txt {
    ::fileutil::cat
    {string trim}
    lines
    last
    words
    last
    split/-
    lindex/1
}

2015-08-18

Han säger NEJ till Pride

This post is about Swedish theo-politics and therefore in Swedish.

Jag skrev en kommentar till den här bloggposten, men den fastnade, tydligen för evigt, i granskningen. Uppenbarligen tyckte Skredsvik att det var bekvämare att få beröm av likasinnade än att hantera kritik. Så jag postar min kommentar här i stället:

Ja, Pride handlar i grund och botten om sexualitet. Sexualitet är något som är viktigt för alla, men de människor vars sexualitet är i linje med den gällande sexualmoralen tror att de inte är lika "sexfixerade" som de som står utanför den, därför att de aldrig behövt kämpa med att acceptera sig själva och kämpa mot samhällets fördomar för att få uttrycka och leva ut den sexualitet de har.

Pride finns till för att de människor som inte är heterosexuellt monogama ska få uppleva samma glädje och stolthet över att de är som de är som heterosexuellt monogama ständigt får. Pride vill bekräfta dessa människor på motsvarande sätt som vår kultur hela tiden bekräftar kärleken mellan man och kvinna.

Pride är inte till för att värna om och lyfta upp kärleken till Jesus, som du efterlyser, för den kärleken handlar inte om sexualitet utan om en självvald fixering. Pride behöver inte ens värna om eller lyfta fram kärleken mellan man och kvinna, för den kärleken har sin Pride-parad varenda dag på året.

Du får gärna för mig säga nej till Pride, och om du kommer med vettig kritik mot Pride så är det välkommet: konstruktiv kritik är alltid bra. Men den här bloggposten går längre än så. Du är extremt noggrann i dina formuleringar för att inte framstå som fördomsfull och oärlig, men lyckas inte helt.

Du skriver att stödet från "politiker, tidningar, kyrkoledare, tv-bolag osv" handlar om att "följ[a] efter i strömmen och [...] vänd[a] kappan efter vinden". Du försöker alltså få det att framstå som om alla dessa saknar både rationella skäl till att stödja Pride och den moraliska hållning som annars skulle få dem att ta avstånd från Pride. Det är ganska magstarkt att framhäva dig själv som klokare och mer moraliskt högtstående än samtliga dessa.

Du skriver att de som "har en annan syn på sexualitet än majoriteten blir ofta anklagade för att vara bakåtsträvande, hatiska, homofober, och allt möjligt" och framställer dig alltså som en förtryckt sexuell minoritet. Jag gissar att du är vad som idag kallas "cis-het-mono", alltså att du lever i samma kön som du är född i och praktiserar heterosexuell, monogamisk sexualitet. Detta innebär att du ingår i en majoritet, inte en minoritet. Att en stor del av denna majoritet idag har insett att det är fel att förtrycka HBTQ+-minoriteten innebär fortfarande inte att du plötsligt hamnat i en sexuell minoritet.

Du skriver att många menar att det "inte går att vara kritisk mot Pride och samtidigt värna om alla människors lika värde". OK, det är en åsikt som man kan ha, men den bygger inte på fakta: självklart kan man vara kritisk mot Pride och ändå vara engagerad i människors lika värde. "Kan det bli mer fel?" frågar du retoriskt. Ja, det kan bli mycket mer fel. T ex kan det bli fel på det sättet att du försöker göra Pride-rörelsen ansvarig för vad "många" säger om dem.

Du skriver att pga man har äktenskapssynen att "äktenskapet är för en man och en kvinna" så kan man i Sverige "få stå ut med hån, förtal, lögner och alla möjliga ogrundade anklagelser". Detta är djupt oärligt. Ingen överhuvudtaget förhindrar dig att ha en sådan äktenskapssyn, och ingenting drabbar dig på grund av att du har den eller ens pläderar för den. Det är när du försöker förhindra andra att frångå den äktenskapssynen som du riskerar att drabbas av, enligt min mening, ganska rimlig kritik.

Jag orkar inte bemöta allt ditt hat, jag väljer ut ett ord att påpeka: "översexualiserad". Ett klassiskt hatord som använts i många sammanhang, bl a mot svarta människor längre tillbaka i tiden. När det används mot HBTQ+-människor är det för att underkänna deras sexualitet, att säga att Görans kärlek till Lasse inte är en verklig, sund kärlek, utan att det handlar om att de är "översexualiserade" och på det viset börjat älska någon de inte borde älska.

När du skriver att "[a]ll kärlek är tydligen inte godkänd av Pride. Vissa människors kärlek är tydligen inte lika mycket värd som andras kärlek" är det ganska uppenbart att du applicerar dina egna värderingar på dem. Pride varken godkänner eller underkänner kärlek, och Pride värderar inte olika sorters kärlek mot varandra. Däremot läser man mellan raderna att enbart en sorts kärlek är godkänd i dina ögon, och att andra sorters kärlek är mindre värd. Är du beredd att bevisa att jag har fel, och skriva en bloggpost där du visar att du står för att alla former av kärlek är "godkända" och lika mycket värda?

2015-08-17

Ordered numeric sequences

I wrote an answer on Stackoverflow, but I think the question is going to go away soon, so I'll post an edited version of my answer here.

The question was about how to find out whether digits in a sequence were in ascending (increasing) order or in descending (decreasing order). The sequence 1 2 3 is in increasing order, and so is 11 5, but this order is non-strict, i.e. the same digit may appear more than once if there are no other digits in between.

One can use mathematical comparison operators to check whether sequences of digits are in order:

foreach n {12345 54321 35214} {
    set ns [split $n {}]
    if {[::tcl::mathop::<= {*}$ns]} {
        puts "$n is in ascending order"
    } elseif {[::tcl::mathop::>= {*}$ns]} {
        puts "$n is in descending order"
    } else {
        puts "$n is neither in ascending or descending order"
    }
}

The command ::tcl::mathop::<= (which also implements the <= operator in expr) can take an arbitrary number of values, preferably numeric, and returns 1 if those values are in non-strict ascending order. It can be called directly on some values:

::tcl::mathop::<= 1 2 3 4 5
# -> 1

If the values are in a list it needs to be expanded first:

set a {1 2 3 4 5}
# -> 1 2 3 4 5
::tcl::mathop::<= {*}$a
# -> 1

If the values are packed in a string it needs to be split into a list and then expanded:

set a 12345
# -> 12345
::tcl::mathop::<= {*}[split $a {}]
# -> 1

The call to <= can be made a little less cumbersome by adding its namespace to the places where the interpreter looks for commands:

namespace path ::tcl::mathop
<= 1 2 3 4 5

Documentation: foreachiflistmathopnamespaceputssetsplit{*}

2015-01-21

Verbosity

I read a blog post today, A Short Story About Verbosity, about writing a tech book. The publisher had asked the writer to go for at least 600 pages. I was reminded of a joke I used to make back when I was teaching C and C++. I would plop down the 272-page The C Programming Language on the desk and say "This is an exhaustive description of C". Then I'd let the ~980-page "The C++ Programming Language" fall with a sickening thud and say "This is the bare minimum you need to understand C++". (Don't worry, I didn't leave them with that: there are shortcuts into C++, and I did my best to point them out.)

Many times you can't really avoid verbosity in a tech book. In the best case, this is because the subject is extensive. In the worst case, it's because the subject is humongous.

I still hope to be able to take my programming book from plans to reality one day. Whatever it becomes, it won't be thick. I'd be surprised if it's more than 300 pages. If I can't say what I want to say in less pages than that, maybe I shouldn't bother. That might mean that no publisher will be interested, but there are other ways.

2014-02-05

De Gustibus

In the late 1990s I used Perl a lot, but then I discovered other languages that suited my tastes and needs better, particularily Tcl.

Today I was searching for something and Google served me a page from perlmonks where a question about Tcl/Tk vs Perl/Tk was asked. The OP commented on the "horrible ugliness" of Tcl, and someone posted a Perl/Tk snippet as some kind of example of sensible Perl code:

#!/usr/bin/perl

use strict;
use Tk;

my $mw = MainWindow->new;

$mw->Button(-text => 'First Button',
            -command => sub { print "You hit the First Button.\n" }
            )->pack;

$mw->Button(-text => 'Second Button',
            -command => \&second_sub,
            )->pack;

$mw->Button(-text => 'QUIT',
            -command => \&exit,
            )->pack;

MainLoop;

sub second_sub
{
    print "The Second Button invokes a Named Subroutine.\n";
    return;
}

For comparison, here's the equivalent Tcl code:

pack [button .b1 -text "First Button" \
    -command { puts "You hit the First Button" }]
pack [button .b2 -text "Second Button" -command secondProc]
pack [button .b3 -text "QUIT" -command exit]

proc secondProc {} {
    puts "The Second Button invokes a Named Subroutine"
}
It is a strange thing that some people find the almost sublime clarity, conciseness, and (yes, I would say:) beauty of Tcl "horribly ugly" while accepting the labyrinthine and bizarre syntax of Perl as usable.

2013-05-17

Hallelujah -- Adventures in LilyPond 5: Lyrics and a twist

Finally, adding words

To complete the lead sheet, I add the lyrics for the song.  It's quite straightforward.  The only things I need to remember is to 1) set the input mode to \lyricmode to distinguish from note input, 2) to split up syllables, and 3) to add double underscores to extend syllables:

firstVerseWords = \lyricmode {
    I heard there was a sec -- ret chord
    that Da -- vid played and it pleased the Lord,
    but you don't real -- ly care for mu -- sic, do ya?
    It goes like this: the fourth, the fifth,
    the mi -- nor fall, the ma -- jor lift.
    The baff -- led king com -- po -- sing Hal -- le -- lu -- jah
}

    \lyricmode {
        O __ O __ A __
    }

So!  I'm done with the song (this is the point in time when I wrote the latest blog post: I've been blogging in parallell with working on the song).  Print it out and distribute it to the choir members, and...

Crash and burn

Remember that I used two different sets of notes as source material?  And that I selected a verse (the last one) that I didn't have any notes for?  Turns out that I made a couple of minor mistakes merging the notes, causing errors in rhythm that were possible to sing past with only brief hiccups during rehearsal.  I'm usually quite meticulous; three errors in transcription in a 39-measure song is quite a negative record for me.  Oops.

Worse, in one measure I thought I needed to have a 4-8-8-8-8-4-8-4. rhythm to the lyrics "even though it all went wrong, I'll".  And boy, did it all go wrong.  The piano stopped, the choir leader went WHAT.  I had tried to sing through the notes as I went along, but in this place I must have sung something else than what I put down as notes, because this is unsingable.  The choir leader quickly saw that a plain 4-8-4-8-4-8-4-8 rhythm worked and went through with the rehearsals, but I was mortified to say the least.

This project was my pride and joy: how could I have been so sloppy?  Well, I did spend a lot of time comparing notes, but I made the basic mistake of comparing with an early version of my own notes(!), so some early errors were preserved to the end.  I kept meaning to go back and compare with the notes my choir leader had given me to work from, but I never did: hence the small mistakes.

The big mistake was caused by trying to do something I hadn't really done before: joining new lyrics with existing music.  Cohen's lyrics are sometimes quirky when it comes to rhythm and I had already discovered that I needed to be flexible.  For most of the verse, I managed to get it right, but in this one measure, I overdid it and failed badly.

The moral of this would seem to be: "don't get cocky".  I was ambitious and enthusiastic, which are nice things to be but perhaps conducive to being speedy and careless.  I kept thinking I was working on something New and Improved, so I was less inclined than usual to look back to the prior art, and even prepared to do some experimenting on my own.  Ah well, lesson learned I hope.

"And even though it all went wrong, I'll stand before the Lord of Song, with nothing on my tongue but Hallelujah"...




2013-05-13

Hallelujah -- Adventures in LilyPond 4: Notes

Adding music

I define three commands: \sopMusic, \altoMusic, and \bassMusic, to collect and transpose the notes for the different voices.  They are similar and very simple.

sopMusic = \transpose g a {
    \relative c' {
        \global

        \firstVerse
        \refrS

        \secondVerseS
        \refrS

        \thirdVerseS
        \refrS

        \bar "|."
    }
}


The \global command could alternatively be inserted before the \relative block; it doesn't really matter which.  Notes can be entered as absolute (no special command needed) or relative (inside a \relative block): in this case I choose to enter the notes relative to middle c (c').  At the end of the song, I insert a double bar line.

The commands \firstVerse, \refrS, \secondVerseS and so on are defined earlier and contain different parts of the notes (in this case the (unison) notes for the first verse, the soprano notes for the refrain, and the soprano notes for the second verse).  It isn't strictly necessary to break up the notes like this, but I find that it 1) becomes more readable and 2) makes it possible to reuse snippets (such as the notes for the first verse in all three voices)

Note collisions

When adding notes in more than one voice to a staff, sometimes notes from different voices need to be set in the same place because they are at the same pitch at the same time in the song.  LilyPond detects these collisions and either merges the notes together, or moves them apart if they can't be merged.  Example (the double backspace is shorthand for voice partition):

\relative c'' <<
    { a2. b4 a1 }
    \\
    { a2. g4 a1 }

>>


The first A notes can be merged, the B and G notes don't collide, and the final A notes collide but can't be merged, so they are moved apart:
To me the second measure looks very confusing.  One solution is to replace one of the colliding notes with a spacer rest:

\relative c'' <<
    { a2. b4 s1 }
    \\
    { a2. g4 a1 }

>>

This works, but now the notes for the first voice have been tampered with and information is lost.  Lyrics can't be connected to the voice, and the voice can't be moved to its own staff.

Another solution is to tell LilyPond to ignore collisions and just engrave the notes on top of each other:

\relative c'' <<
    \override NoteColumn #'ignore-collision = ##t
    { a2. b4 a1 }
    \\
    { a2. g4 a1 }

>>

This creates new problems, such as turning the first note into some kind of double-dotted monstrosity:
The cleanest and best solution is to switch off collision detection just for that specific note:

\relative c'' <<
    { a2. b4

      \once \override NoteColumn #'ignore-collision = ##t
      a1 }
    \\
    { a2. g4 a1 }
>>

This problem occurs in a few places in the ``Hallelujah'' notes, for instance in the first verse.  I define a command for switching collision detection off temporarily, partly to make it less intrusive, and partly because I can then invoke the same command in the other relevant places:

ignore = \once \override NoteColumn #'ignore-collision = ##t

firstVerse = {
    \partial 8 d8 |
    d4 d8 d4 d8 e8 e e4. d8   | d4 d8 d d d e4 e8 e4 e8   |
    e4 e8 e4 e8 e4 d8 d4 c8   | d8 \ignore d1 r4 d8       |
    d4 d8 d4 d8 e4 e8 fis4 d8 | g8 g8 g4. g8 g8 g8 a4. a8 |
    a4 a8 a4 a8 b4 b b8 a     | a4. g2
}


By the way, LilyPond doesn't care that much about whitespace and aligning bar checks, it's just me being pedantic.  Yes, bar checks.  LilyPond calculates the extent of measures and puts in bar lines by itself without needing any specification in the source.  However, by inserting bar checks (|) where I think a measure should end the notes become more readable (I can count bars to get to a specific place in the source) and I will get a warning from LilyPond if my bar placing doesn't add up correctly (which either means I just counted wrong or, worse, that I've messed up a duration somewhere).

Also note the fis in the next measure.  LilyPond by default uses the Dutch language convention for naming accidentals: -is for sharps and -es for flats.  You can choose between twelve different languages with different note/accidentals naming standards, but I've always used the default one.  For one thing, if I used Swedish naming, the B notes would be H notes, and that's just plain wrong.  (Unless you're J. S. Bach and you want to spell your name in chords.)    


The DRY principle

In programming, the DRY principle ("Don't Repeat Yourself") is a powerful tool used to avoid contradictions.  The principle asserts that every piece of knowledge must have a single representation.  Applying this to LilyPond, this means it's good practice to detect duplicate ranges of notes and bring them together into a single command, which is then invoked in every place where the duplicate notes are used.  For example, both the soprano and the alto voices use the same notes for the first half of their respective second verses.  Instead of having the same notes in both the definitions of \secondVerseS and \secondVerseA, I use the following:

secondVerseFirstHalfSA = {
    r4. d'8 |
    d4 d4. d8 e4 e8 e4 d8  | d4 d8 d4 d8 e4 e8 e4 e8 |
    e4 e8 e4 e8 e4 d8 d c4 | d8 \ignore d1 r4 d8     |
}

secondVerseS = {
    \secondVerseFirstHalfSA
    % ...
}

secondVerseA = {
    \secondVerseFirstHalfSA

    % ... 
}

This means that whatever happens, this particular piece of music will be consistent.  If one voice is correct, the other will also be correct.

Now, in the soprano voice, the second halves of the second and third verses are almost identical: only half a measure in the middle differs.  Maybe this shouldn't bother me, but it does, so by Knuth I will solve it.  I can't use a command to define the relevant notes, but I can use a substitution function:

secondAndThirdVerseSecondHalfS =
#(define-music-function
     (parser location notes)
     (ly:music?)
   #{
    d4 d8 d d d e4 e8 fis4. | g4 g8 g4 g8 #notes |
    a4 a8 a4 a8 b4 b b8 a   | a4. g2
   #})


This function contains the duplicate notes, with a placeholder (#notes) for the differing notes.  It can be used like this:

secondVerseS = {
    \secondVerseFirstHalfSA
    \secondAndThirdVerseSecondHalfS { g8 g a a4 a16 a }
}


Edit: Nnnope.  In the end I had to make some more changes to the second half of the third verse (more about this in part 5), so the secondAndThirdVerseSecondHalfS function isn't viable any more.  The concept is still sound, though.

To be concluded.

2013-05-11

Hallelujah -- Adventures in LilyPond 3: Chords

The definition of global

By convention, LilyPond source files define the command \global, which is then used to insert, well, globally relevant constants at the appropriate places.  In practice, this is typically the key and time signature.  Because I made the basic mistake of writing the music in the key of G, I'll specify G major and rely on the \transpose command to correct it later.

global = {
    \key g \major
    \time 12/8
}


The \global command is then called in each of the \sopMusic, \altoMusic, and \bassMusic definitions.

LilyPond version

Another convention is to add the LilyPond version statement at the top of the source file.  In fact, LilyPond will warn you if you don't.  In theory, this will protect your work if you run a very old source file through the LilyPond compiler, by reverting to old interpretations if the current ones have changed since then.  This is in contrast to say, POV-Ray, where I'm told old source files simply stop working with newer versions of the program.

\version "2.16.2"

I've never had any version problems with LilyPond, but then I always do add the version statement (mostly because I hate warnings).

The chords

With those things out of the way, I could start writing the source for the lead sheet.  Chords first, the backbone of the song.

verseChords = \chordmode {
    g2. e:m g e:m
    c2. d g d
    g2. c4. d e2.:m c4. d
    d2. b:7 e:m e:m
}

refrChords = \chordmode {
    c2. c e:m e:m
    c2. c g d g
}


The command \chordmode tells LilyPond not to try to read the following as notes, which is the default input format, but as chords.  Each of the verses use the same chord sequence, as do the refrains, but I don't have to repeat the chords for each verse/refrain.  By the magic of LilyPond definitions I can define two commands that contain verse chords and refrain chords, and later use the commands three times each.  I believe it's hard to do that in a WYSIWYG music editor.

Most of the chords have a half-measure (6 eights) duration, or the equivalent of a dotted half-note (written as 2. after the chord name).  In a couple of cases the cords have a quarter-measure (3 eights) duration, written as 4. (a dotted quarternote), and in some places a chord lasts for a full measure.  I could have written that as chordname1., but instead I doubled the chords (e.g. e:m e:m).  There is a special syntax for repeating chords, e:m q, which I, for no good reason, don't use here.  I might in the future (it's an old syntax which was gone for a couple of versions and then reintroduced).

So, let's put the chord definitions together and transpose them to A:

theChords = \transpose g a {
    \set chordChanges = ##t

    \chordmode { s8 }
    \verseChords
    \refrChords

    \chordmode { d2. }
    \verseChords
    \refrChords

    \chordmode { d2. }
    \verseChords
    \refrChords
}


Note that I have some additional chords here: a spacer (invisible) chord for the pickup measure in the beginning of the song, and a half-measure D chord joining each refrain to the following verse.  Also, by setting the chordChanges property to true (##t), I instruct LilyPond to leave out chord names except where they change or at the beginning of a new line.  This is very handy and should be the default if you ask me.

Once \theChords is defined, all the chords for the song are put together in a neat package, ready to be dropped into the score.  They are also transposed from G major to A without any brainwork on my part (even I could go from G to A, but LilyPond will happily do transpositions that are much harder).

The lyrics mention four (I, IV, V, vi) of the five chords used as they occur in the song (the fifth one being a III7 chord that is used only once in each verse):

"It [I]goes like this: the [IV]fourth, the [V]fifth, the [vi]minor fall, the [IV]major [V]lift"

One of us, Mr Cohen.  One of us.

To be continued.

2013-05-09

Hallelujah -- Adventures in LilyPond 2: Fundamentals

The following are some of the issues that came up when putting ``Hallelujah'' together (and are fairly typical for writing music with LilyPond).


Paper size, margins and number of pages

Like many choirs, we use A4 paper copied with recto pages on the left and verso pages on the right (i.e. the inner margin becomes the outer), so we can read two-paged music from a two-page spread.  A4 size is standard in LilyPond, so I don't have to set that.  Setting the margins is easy using a \paper block:

\paper {
    two-sided = ##t
    inner-margin = 10 \mm
    outer-margin = 20 \mm
}

 

If the music spans over a single page or more than two pages, the following is more generally useful (even if it leaves only a barely wide enough margin for the holes, and a slightly too big margin on the opposite paper edge):

\paper {
    left-margin = 15 \mm
    right-margin = 15 \mm
}


With these settings, ``Hallelujah'' becomes a little over two pages in length, but by reducing the music size a bit it will fit on two pages.  It's a little bit confusing (to me, at least) how this actually is supposed to be specified, but I've found that setting fontSize in a global or \score-local \layout block will do the job (the notes and symbols are glyphs in a font, not graphical objects per se).

\layout {
    \set fontSize = #-2
}


(The ``tiny'' font (-2) is a fairly small font, but still readable.  I wouldn't select any smaller number.)

Note the inconsistency in syntax (\set vs no \set): LilyPond sometimes can't quite make up its mind about syntax.  It's still better than Visual Basic :)

Keeping score


LilyPond is very relaxed about input format.  Simply writing


\relative c' { c d e f g }

\addlyrics { Foo bar baz qux blarg }
 


will give you the music

But if you want to get anything done, you'll want to be as strict and structured as you can and write the notes ``top-down'', i.e. start with a score and add distinct parts of content to it.  The basic template for a SAB arrangement, with chords and with the sopranos and the altos singing the same lyrics, is as follows (a more complete and generic SATB template can be found in the LilyPond documentation here):

\score {
    \new ChoirStaff <<
        \new ChordNames { \theChords }
        \new Staff = "women" <<
            \new Voice = "sopranos" {
                \voiceOne << \sopMusic >>
            }
            \new Voice = "altos" {
                \voiceTwo << \altoMusic >>
            }
        >>
        \new Lyrics = "altos"
        \new Staff = "men" <<
            \clef bass
            \new Voice = "basses" {
                \voiceTwo << \bassMusic >>
            }
        >>
        \new Lyrics = "basses"
        \context Lyrics = "altos" \lyricsto "altos" \sopaltWords
        \context Lyrics = "basses" \lyricsto "basses" \bassWords
    >>
}


Basically, the parts enclosed by << ... >> happen in parallel, while the parts enclosed in { ... } happen in sequence.  The template defines a score as having a choir staff with a line for chord names, a staff with two voices (stems going in different directions) a line for lyrics, another staff with a single voice, and finally another line for lyrics.  This aggregate will automatically be broken up into and repeated over as many systems as are needed.

In this score, \theChords, \sopMusic, \altoMusic, \bassMusic, \sopaltWords, and \bassWords are references to things (notes, lyrics etc) defined elsewhere.

To be continued.

Edit: took out references to \global.  They will reappear in the next part.

2013-05-03

Hallelujah -- Adventures in LilyPond

I really like writing music. Not composing, that's probably beyond my capacity, but creating new sheet music from scribbles or rearranging songs.

As usual, my favorite tool is a non-IDE, non-WYSIWYG program, in this case LilyPond (http://www.lilypond.org/). LilyPond allows me to use gVim (http://www.vim.org/) as editor and to think of the music as text, with the beautiful display of notes as a reward when the work is done. And LilyPond produces really pretty music, IMHO more so than most WYSIWYG tools I've seen so far.

Now, my choir leader asked me to put together a version (Yet Another) of Leonard Cohen's Hallelujah. What he had was SAB notes for five verses, all of them arranged differently. He wanted me to select three verses (and consequently to choose three of the verse arrangements).

The straightforward thing to do would have been to transcribe the existing notes into LilyPond notation and assemble the thing from there, but for some reason I decided to search for existing LilyPond notes for Hallelujah first. I did find some nice notes, but in G major instead of A major which we were going to use (the original is in C major), and in 6/8 time instead of 12/8 (which didn't matter much). It's very easy to transpose notes in LilyPond, but working with text notes in G major and proofreading in A major was a major bother (every note being off by one, as it were).

Because of this, it took me a lot longer than usual to get the notes and chords completely right. At the same time, I was trying to choose three verses that would make a satisfying whole. Jeff Buckley put together the most famous cover, using five verses (''I heard there was a secret chord'', ''Your faith was strong but you needed proof'', ''Baby I've been here before'', ''There was a time when you let me know'', ''Maybe there's a God above''). Cohen's lyrics have two more verses (''You say I took the name in vain'', ''I did my best, it wasn't much''). Basically, all of these verses are good, strong poetry. It's said Cohen wrote 80 verses, presumably not all top notch, before he managed to pare them down into a song.

''I heard there was a secret chord'' isn't one of the best verses, but it's hard to imagine the song without it, so I kept it as the initial verse. I took the unison women's voices arrangement and added men's voices to it, still in unison. The refrain would be the same for all three verses, a full SAB arrangement. For a second verse, I chose ''Baby I've been here before'' in a SA arrangement, without men's voices. The main reason for choosing this verse was the ''Love is not a victory march / It's a cold and it's a broken Hallelujah'' pair of lines. Now I had three or four verses left screaming for attention, but in the end ''I did my best, it wasn't much'' won out. I think it's a very satisfying ending to the song, which may be why most covers leave it out. The first half is sung by the men, with a SA ''O___ O___ A___'' backup. The second half of the verse is a full SAB arrangement: I considered letting the men sing all of it alone, but decided the climax should have as many voices as possible.

I really like this song. Both the music and the lyrics resonate with me on a fundamental level (I realize this isn't a unique sentiment, this being one of the world's most popular songs). Editing it into an arrangement for my choir was a bit of a dream come true. Even though I made labor-increasing mistakes in the beginning, it was very enjoyable and rewarding work.

I dedicate my work on this song to the memory of R.M.

2012-05-17

Binary and decimal

In a recent post, I described briefly how the binary numeric format fits well with the octal and hexadecimal formats.  However, we humans mainly use the decimal format to make calculations and express quantities.  Say we want a binary computer to actually work in decimal, storing quantities as decimal digits and using decimal calculations.  Is this possible?