unicode as valid naming symbols

Chris Angelico rosuav at gmail.com
Tue Apr 1 06:39:06 EDT 2014


On Tue, Apr 1, 2014 at 8:58 PM, Ian Kelly <ian.g.kelly at gmail.com> wrote:
> Setting aside the fact that C doesn't have anonymous functions, I'll
> approximate it as best I can:
>
> static int n = 3;
>
> int f()
> {
>     return n;
> }
>
> int main()
> {
>     n = 7;
>     return f();
> }
>
> C: 10
> Scheme: 20

And the less trivial the example, the more difference you'll see. This
is Scheme inside LilyPond, a little translator that lets me input
lyrics in a tidy way that can then be turned into something that works
well with both MIDI Karaoke and printed score:

#(define (bang2slashn lst) (
    cond ((null? lst) 0)
    (else (begin
        (if (equal? (ly:music-property (car lst) 'name) 'LyricEvent)
(let ((txt (ly:music-property (car lst) 'text)))
            (if (equal? (string-ref txt 0) #\!) (begin
            ; Debugging display
            ; (display (ly:music-property (car lst) 'name)) (display "
- ") (display txt) (newline)
            ; Prepend a newline instead of the exclamation mark -
works for both MIDI Karaoke and page layout
            (ly:music-set-property! (car lst) 'text (string-append
"\n" (substring txt 1 (string-length txt))))
        ))))
        (bang2slashn (ly:music-property (car lst) 'elements))
        (bang2slashn (cdr lst))
    ))
))
% Call the above recursive function
lyr=#(define-music-function (parser location lyrics) (ly:music?)
    (bang2slashn (ly:music-property lyrics 'elements))
    lyrics
)

Now, this was written by a non-Scheme programmer, so it's not going to
be optimal code, but I doubt it's going to lose a huge number of
parentheses. Not counting the commented-out debugging line, that's 41
pairs of them in a short but non-trivial piece of code. Translating it
to C isn't easy, in the same way that it's hard to explain how to do
client-side web form validation in Lua; but here's an attempt. It
assumes a broadly C-like structure to LilyPond (eg that the elements
are passed as a structure; they are a tree already, as you can see by
the double-recursive function above), which is of course not the case,
but here goes:

void bang2slashn(struct element *lst)
{
    while (lst)
    {
        if (!strcmp(lst->name, "LyricEvent"))
        {
            char *text = music_property(lst, "text");
            /* Okay, C doesn't have string manipulation, so I cheat here */
            /* If this were C++ or Pike, some notation nearer to the
original would work */
            if (*text == '!') music_set_property(lst, "text", "\n" + text[1..]);
        }
        bang2slashn(lst->elements);
        lst = lst->next;
    }
}

DEFINE_MUSIC_FUNCTION(PARSER_LOCATION_LYRICS, bang2slashn);


That's nine pair parens, three braces, and one square. I assume a lot
about the supposed C-like interface to LilyPond, but I think anyone
who knows both C and Scheme would agree that I haven't been
horrendously unfair in the translation. (Though I will accept an
alternate implementation of the Scheme version. If you can cut it down
to just 26 pair parens, you'll achieve the 2:1 ratio that Ian
mentioned. And if you can cut it down to 13 pairs, you've equalled my
count.) The only way to have the C figure come up approximately equal
is to count a semicolon as if it were a pair of parens - Scheme has an
extra set of parens doing the job of separating one function call from
another. But that adds only another 5, bringing C up to a total of 18
(plus a few more if I used functions to do my string manipulation, so
let's say about 20-25) where Scheme is still at roughly twice that.

ChrisA



More information about the Python-list mailing list