Guitar capo code in scheme

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Guitar capo code in scheme

Wols Lists
Finally dragged myself back to it. Looking at Neil's sample code, it
looked like it modified the formatters, which I didn't want to do ... so
I've created the shim.

So chord-name-engraver.cc will need to be modified (ll127) to call my
shim rather than the chordNameFunction. I've called the shim
capo-handler and defined it in chord-name.scm. I quite deliberately
haven't done a patch quite yet, because my scheming is "monkey see
monkey do" and I shall be VERY surprised if it doesn't need some fixing...

Anyways, shim function follows ...

(define-public (capo-handler pitches bass inversion context)
  (chord-function (ly:context-property context 'chordNameFunction #f))
  (capo-pitch (ly:context-property context 'capoPitch #f))
;; if there's no capo pitch or no chord
  (if
    (or (not (capo-pitch) not (chord)))
;; call the chordNameFunction as of old
    (chord-function pitches bass inversion context)
;; else transpose the pitches and do the chord twice
    ((new-pitches
        (map (lambda (p)
          (ly:pitch-transpose p capo-pitch))
      pitches))
      (new-bass
        (and (ly:pitch? bass)
          (ly:pitch-transpose bass capo-pitch)))
      (new-inversion
        (and (ly:pitch? inversion)
          (ly:pitch-transpose inversion
      capo-pitch)))

      (capo-markup (make-parenthesize-markup (chord-function new-pitches
new-bass new-inversion context)))
      (markup (chord-function pitches bass  inversion context))

      (capo-vertical (ly:context-property context 'capoVertical #f))
      (if (capo-vertical)
        (make-column-markup (list markup capo-markup))
        (make-line-markup (list markup (make-hspace-markup 1) capo-markup))
      )
    )
  )
)

I've got (not (chord)), which Carl said he thought was actually encoded
as a rest, but I haven't got a clue how to test for it ...

I've done the code a bit differently from Neil's sample patch too.
Basically, if the capo is irrelevant, it detects that at the start and
simply drops straight into the chord formatter.

Otherwise, it transposes its arguments, calls the chord formatter twice,
and checks capoVertical to see whether the two chords are to be printed
one after the other, or one above the other.

I've assumed "context" is the engraver so I can extract things like the
chord formatter, the pitch to transpose, etc from it. If I've guessed
wrong, then that'll need a rework too :-)

Anyways, does this look okay? I haven't done any scheme sillies? How do
I test for a rest? And if you think this looks sensible, I'll modify
chord-name-engraver to call it and test it tomorrow - it's midnight and
time for bed here now.

Thanks,
Wol

---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Carl Sorensen



On 7/19/11 5:47 PM, "Wols Lists" <[hidden email]> wrote:

> Finally dragged myself back to it. Looking at Neil's sample code, it
> looked like it modified the formatters, which I didn't want to do ... so
> I've created the shim.
>
> So chord-name-engraver.cc will need to be modified (ll127) to call my
> shim rather than the chordNameFunction. I've called the shim
> capo-handler and defined it in chord-name.scm. I quite deliberately
> haven't done a patch quite yet, because my scheming is "monkey see
> monkey do" and I shall be VERY surprised if it doesn't need some fixing...
>
> Anyways, shim function follows ...
>
> (define-public (capo-handler pitches bass inversion context)

  This needs to be in a let block.

    (let ((chord-function ....)
          (capo-pitch ...))
       (if (not capo-pitch)
...
>   (chord-function (ly:context-property context 'chordNameFunction #f))
>   (capo-pitch (ly:context-property context 'capoPitch #f))
> ;; if there's no capo pitch or no chord
>   (if
>     (or (not (capo-pitch) not (chord)))

The test is not correct.  Also, it should be on the same line as the if:

   (if (not capo-pitch)

> ;; call the chordNameFunction as of old
>     (chord-function pitches bass inversion context)
> ;; else transpose the pitches and do the chord twice

The code below needs to be in a let block:
    (let ((new-pitches....

>     ((new-pitches
>         (map (lambda (p)
>           (ly:pitch-transpose p capo-pitch))
>       pitches))
>       (new-bass
>         (and (ly:pitch? bass)
>           (ly:pitch-transpose bass capo-pitch)))
>       (new-inversion
>         (and (ly:pitch? inversion)
>           (ly:pitch-transpose inversion
>       capo-pitch)))
>
>       (capo-markup (make-parenthesize-markup (chord-function new-pitches
> new-bass new-inversion context)))
>       (markup (chord-function pitches bass  inversion context))
>
>       (capo-vertical (ly:context-property context 'capoVertical #f))

This will be the end of your let block definitions, so it will need another
)

>       (if (capo-vertical)
>         (make-column-markup (list markup capo-markup))
>         (make-line-markup (list markup (make-hspace-markup 1) capo-markup))

Style -- never ever ever leave a right parenthesis by itself on a line.

>       )
>     )
>   )
> )
>
> I've got (not (chord)), which Carl said he thought was actually encoded
> as a rest, but I haven't got a clue how to test for it ...

You don't need to test for it.  The shim function will be called at line 128
of lily/chord-name-engraver.cc.  This code is never executed if it's a rest
event (see lines 79-85).
>
> I've done the code a bit differently from Neil's sample patch too.
> Basically, if the capo is irrelevant, it detects that at the start and
> simply drops straight into the chord formatter.
>

Great!  Details like this are not too important to us.  You're free to do
the code the way you'd like to.  We're more concerned about the
architecture.

> Otherwise, it transposes its arguments, calls the chord formatter twice,
> and checks capoVertical to see whether the two chords are to be printed
> one after the other, or one above the other.
>
> I've assumed "context" is the engraver so I can extract things like the
> chord formatter, the pitch to transpose, etc from it. If I've guessed
> wrong, then that'll need a rework too :-)

"context" isn't the engraver.  context is the context in which the music
function is being evaluated.  context is where you get the properties
chordNameFunction and capoPitch.

So you've done it right, but the terminology was off a bit.

>
> Anyways, does this look okay? I haven't done any scheme sillies? How do
> I test for a rest? And if you think this looks sensible, I'll modify
> chord-name-engraver to call it and test it tomorrow - it's midnight and
> time for bed here now.

With the exceptions I've noted above, it looks great!  I think this will do
exactly what you want done, and it will satisfy my concerns and Neil's
concerns.  Great job!

Thanks,

Carl


---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Wols Lists
On 20/07/11 01:05, Carl Sorensen wrote:
>
>
> With the exceptions I've noted above, it looks great!  I think this will do
> exactly what you want done, and it will satisfy my concerns and Neil's
> concerns.  Great job!
>
Okay, I've tried to follow what you've said, and make the appropriate
changes. Patches attached. But it won't run :-( and I'm pretty certain
I've messed up the "let(" syntax.

I've looked at the scheme tutor "structure and interpretation..." and
while I sort of understand what's going on, I haven't quite got it yet.

Anyways, here's the code:

(define-public (capo-handler pitches bass inversion context)
  (let (chord-function (ly:context-property context 'chordNameFunction #f))
    (capo-pitch (ly:context-property context 'capoPitch #f))
    (if  (not (capo-pitch))                 ;; if there's no capo pitch
or no chord
      (chord-function pitches bass inversion context)     ;; call the
chordNameFunction as of old
      (let ((new-pitches                                       ;; else
transpose the pitches and do the chord twice
            (map (lambda (p)
              (ly:pitch-transpose p capo-pitch))
          pitches))
          (new-bass
            (and (ly:pitch? bass)
              (ly:pitch-transpose bass capo-pitch)))
          (new-inversion
            (and (ly:pitch? inversion)
              (ly:pitch-transpose inversion
          capo-pitch)))

          (capo-markup (make-parenthesize-markup (chord-function
new-pitches new-bass new-inversion context)))
          (markup (chord-function pitches bass  inversion context))

          (capo-vertical (ly:context-property context 'capoVertical #f))
          (if (capo-vertical)
            (make-column-markup (list markup capo-markup))
            (make-line-markup (list markup (make-hspace-markup 1)
capo-markup))))))))

And the error:

anthony@ashdown ~/gitstuff/music/Hymnal/Choruses $ lilypond
HeGaveMeBeautyForAshes.ly
GNU LilyPond 2.15.6
Processing `HeGaveMeBeautyForAshes.ly'
Parsing...
Interpreting music... ERROR: In procedure memoization:
ERROR: In file "/usr/local/share/lilypond/2.15.6/scm/chord-name.scm",
line 173: Bad binding chord-function in expression (let (chord-function
(ly:context-property context (quote chordNameFunction) #f)) (capo-pitch
(ly:context-property context (quote capoPitch) #f)) (if (not
(capo-pitch)) (chord-function pitches bass inversion context) (let
((new-pitches (map (lambda # #) pitches)) (new-bass (and (ly:pitch?
bass) (ly:pitch-transpose bass capo-pitch))) (new-inversion (and
(ly:pitch? inversion) (ly:pitch-transpose inversion capo-pitch)))
(capo-markup (make-parenthesize-markup (chord-function new-pitches
new-bass new-inversion context))) (markup (chord-function pitches bass
inversion context)) (capo-vertical (ly:context-property context (quote
capoVertical) #f)) (if (capo-vertical) (make-column-markup (list markup
capo-markup)) (make-line-markup (list markup # capo-markup))))))).
anthony@ashdown ~/gitstuff/music/Hymnal/Choruses $

Cheers,
Wol

0001-Add-capo-handler-function-for-guitar-chords.patch (1K) Download Attachment
0002-Add-capo-properties-to-define-context-properties.patch (1K) Download Attachment
0003-Modify-chord-name-engraver-to-call-capo-handler.patch (948 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Marc Hohl
Am 20.07.2011 23:18, schrieb Wols Lists:

> On 20/07/11 01:05, Carl Sorensen wrote:
>>
>> With the exceptions I've noted above, it looks great!  I think this will do
>> exactly what you want done, and it will satisfy my concerns and Neil's
>> concerns.  Great job!
>>
> Okay, I've tried to follow what you've said, and make the appropriate
> changes. Patches attached. But it won't run :-( and I'm pretty certain
> I've messed up the "let(" syntax.
>
> I've looked at the scheme tutor "structure and interpretation..." and
> while I sort of understand what's going on, I haven't quite got it yet.
>
> Anyways, here's the code:
>
> (define-public (capo-handler pitches bass inversion context)
>    (let (chord-function (ly:context-property context 'chordNameFunction #f))
At a quick glace, I think here is the error:

let must be followed by two parentheses:

(let ((foo ( ... ))
         (bar ( ... ))

         ...function calls follow here... ))

>      (capo-pitch (ly:context-property context 'capoPitch #f))
And here ends the variable block, add another ")" in the line above.

I didn't test it, though.

HTH,

Marc

>      (if  (not (capo-pitch))                 ;; if there's no capo pitch
> or no chord
>        (chord-function pitches bass inversion context)     ;; call the
> chordNameFunction as of old
>        (let ((new-pitches                                       ;; else
> transpose the pitches and do the chord twice
>              (map (lambda (p)
>                (ly:pitch-transpose p capo-pitch))
>            pitches))
>            (new-bass
>              (and (ly:pitch? bass)
>                (ly:pitch-transpose bass capo-pitch)))
>            (new-inversion
>              (and (ly:pitch? inversion)
>                (ly:pitch-transpose inversion
>            capo-pitch)))
>
>            (capo-markup (make-parenthesize-markup (chord-function
> new-pitches new-bass new-inversion context)))
>            (markup (chord-function pitches bass  inversion context))
>
>            (capo-vertical (ly:context-property context 'capoVertical #f))
>            (if (capo-vertical)
>              (make-column-markup (list markup capo-markup))
>              (make-line-markup (list markup (make-hspace-markup 1)
> capo-markup))))))))
>
> And the error:
>
> anthony@ashdown ~/gitstuff/music/Hymnal/Choruses $ lilypond
> HeGaveMeBeautyForAshes.ly
> GNU LilyPond 2.15.6
> Processing `HeGaveMeBeautyForAshes.ly'
> Parsing...
> Interpreting music... ERROR: In procedure memoization:
> ERROR: In file "/usr/local/share/lilypond/2.15.6/scm/chord-name.scm",
> line 173: Bad binding chord-function in expression (let (chord-function
> (ly:context-property context (quote chordNameFunction) #f)) (capo-pitch
> (ly:context-property context (quote capoPitch) #f)) (if (not
> (capo-pitch)) (chord-function pitches bass inversion context) (let
> ((new-pitches (map (lambda # #) pitches)) (new-bass (and (ly:pitch?
> bass) (ly:pitch-transpose bass capo-pitch))) (new-inversion (and
> (ly:pitch? inversion) (ly:pitch-transpose inversion capo-pitch)))
> (capo-markup (make-parenthesize-markup (chord-function new-pitches
> new-bass new-inversion context))) (markup (chord-function pitches bass
> inversion context)) (capo-vertical (ly:context-property context (quote
> capoVertical) #f)) (if (capo-vertical) (make-column-markup (list markup
> capo-markup)) (make-line-markup (list markup # capo-markup))))))).
> anthony@ashdown ~/gitstuff/music/Hymnal/Choruses $
>
> Cheers,
> Wol


---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Wols Lists
On 21/07/11 06:23, Marc Hohl wrote:

> Am 20.07.2011 23:18, schrieb Wols Lists:
>> On 20/07/11 01:05, Carl Sorensen wrote:
>>>
>>> With the exceptions I've noted above, it looks great!  I think this
>>> will do
>>> exactly what you want done, and it will satisfy my concerns and Neil's
>>> concerns.  Great job!
>>>
>> Okay, I've tried to follow what you've said, and make the appropriate
>> changes. Patches attached. But it won't run :-( and I'm pretty certain
>> I've messed up the "let(" syntax.
>>
>> I've looked at the scheme tutor "structure and interpretation..." and
>> while I sort of understand what's going on, I haven't quite got it yet.
>>
>> Anyways, here's the code:
>>
>> (define-public (capo-handler pitches bass inversion context)
>>    (let (chord-function (ly:context-property context
>> 'chordNameFunction #f))
> At a quick glace, I think here is the error:
>
> let must be followed by two parentheses:
>
> (let ((foo ( ... ))
>         (bar ( ... ))
>
>         ...function calls follow here... ))
>
>>      (capo-pitch (ly:context-property context 'capoPitch #f))
> And here ends the variable block, add another ")" in the line above.
>
> I didn't test it, though.
>
> HTH,
>
> Marc

Unfortunately, I think I picked that up :-(

What I posted was my first draft, which I committed to my git because I
was reasonably happy. I've actually tried a bunch of variants, but
seeing as they all blew up with the same error, I didn't bother
committing them. As far as I can tell, the error is simply saying "I
can't compile this procedure, there's a problem", which makes my life
difficult because I can't see what's wrong and the error gives me no
clues ...

As I understand the syntax of let - and I know this is not formatted
"nicely", but to make things clear, it's

(let
        ( ;; variable declaration block
                (variable value)
                (variable value)
        )
        (
                (statement ...)
        )
)

I know that's not what's in my published code, but I would have tried
that after I committed my version, and as I say, nothing I tried made
any difference to the error message :-(

Cheers,
Wol

---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Carl Sorensen



On 7/21/11 4:45 AM, "Wols Lists" <[hidden email]> wrote:

> On 21/07/11 06:23, Marc Hohl wrote:
>> Am 20.07.2011 23:18, schrieb Wols Lists:
>>> On 20/07/11 01:05, Carl Sorensen wrote:
>>>>
>>>> With the exceptions I've noted above, it looks great!  I think this
>>>> will do
>>>> exactly what you want done, and it will satisfy my concerns and Neil's
>>>> concerns.  Great job!
>>>>
>>> Okay, I've tried to follow what you've said, and make the appropriate
>>> changes. Patches attached. But it won't run :-( and I'm pretty certain
>>> I've messed up the "let(" syntax.
>>>
>>> I've looked at the scheme tutor "structure and interpretation..." and
>>> while I sort of understand what's going on, I haven't quite got it yet.
>>>
>>> Anyways, here's the code:
>>>
>>> (define-public (capo-handler pitches bass inversion context)
>>>    (let (chord-function (ly:context-property context
>>> 'chordNameFunction #f))
>> At a quick glace, I think here is the error:
>>
>> let must be followed by two parentheses:
>>
>> (let ((foo ( ... ))
>>         (bar ( ... ))
>>
>>         ...function calls follow here... ))
>>
>>>      (capo-pitch (ly:context-property context 'capoPitch #f))
>> And here ends the variable block, add another ")" in the line above.
>>
>> I didn't test it, though.
>>
>> HTH,
>>
>> Marc
>
> Unfortunately, I think I picked that up :-(
>
> What I posted was my first draft, which I committed to my git because I
> was reasonably happy. I've actually tried a bunch of variants, but
> seeing as they all blew up with the same error, I didn't bother
> committing them. As far as I can tell, the error is simply saying "I
> can't compile this procedure, there's a problem", which makes my life
> difficult because I can't see what's wrong and the error gives me no
> clues ...
>
> As I understand the syntax of let - and I know this is not formatted
> "nicely", but to make things clear, it's
>
> (let
>         ( ;; variable declaration block
>                 (variable value)
>                 (variable value)
>         )
>         (

You can't just glue statements together in a list.  You either have to leave
out the parentheses:

  (statement 1)
  (statement 2)
  (statement 3)) ; end of let block

or you can combine them in a begin block

   (begin
      (statement 1)
      (statement 2)
      (statement 3)); end of begin
); end of let

HTH,

Carl


---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Jan Warchol
In reply to this post by Wols Lists
Sorry for the late answer! I was flooded by e-mails recently and i'm
afraid i choose wrong order of answering... :(

2011/7/20 Wols Lists <[hidden email]>:
> On 20/07/11 01:05, Carl Sorensen wrote:
>>
>>
>> With the exceptions I've noted above, it looks great!  I think this will do
>> exactly what you want done, and it will satisfy my concerns and Neil's
>> concerns.  Great job!
>>
> Okay, I've tried to follow what you've said, and make the appropriate
> changes. Patches attached.

I understand that they are separate form what you've sent previously?
In other words, i should apply them on a clean master?

> But it won't run :-( and I'm pretty certain
> I've messed up the "let(" syntax.
>
> the error:
>
> anthony@ashdown ~/gitstuff/music/Hymnal/Choruses $ lilypond
> HeGaveMeBeautyForAshes.ly
> GNU LilyPond 2.15.6
> Processing `HeGaveMeBeautyForAshes.ly'
> Parsing...
> Interpreting music... ERROR: In procedure memoization:
> ERROR: In file "/usr/local/share/lilypond/2.15.6/scm/chord-name.scm",
> line 173: Bad binding chord-function in expression (let (chord-function
> (ly:context-property context (quote chordNameFunction) #f)) (capo-pitch
> (ly:context-property context (quote capoPitch) #f)) (if (not
> (capo-pitch)) (chord-function pitches bass inversion context) (let
> ((new-pitches (map (lambda # #) pitches)) (new-bass (and (ly:pitch?
> bass) (ly:pitch-transpose bass capo-pitch))) (new-inversion (and
> (ly:pitch? inversion) (ly:pitch-transpose inversion capo-pitch)))
> (capo-markup (make-parenthesize-markup (chord-function new-pitches
> new-bass new-inversion context))) (markup (chord-function pitches bass
> inversion context)) (capo-vertical (ly:context-property context (quote
> capoVertical) #f)) (if (capo-vertical) (make-column-markup (list markup
> capo-markup)) (make-line-markup (list markup # capo-markup))))))).
> anthony@ashdown ~/gitstuff/music/Hymnal/Choruses $

I get it too...
I tried inserting random parentheses, but it didn't work.

I've uploaded your new patch set to Rietveld
(http://codereview.appspot.com/4800051), hopefully it will help in
pinpointing the problem with Scheme syntax.
My apologies for delay!

thanks for your work!
Janek

---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Wols Lists
On 25/07/11 22:28, Jan Warchoł wrote:

> I get it too...
> I tried inserting random parentheses, but it didn't work.
>
> I've uploaded your new patch set to Rietveld
> (http://codereview.appspot.com/4800051), hopefully it will help in
> pinpointing the problem with Scheme syntax.
> My apologies for delay!
>
> thanks for your work!
> Janek
>
Thanks.

As always, the problem is finding time, I'm planning to delete most of
the code and put it back line by line - taking a sort of "divide and
conquer" to try and work out what's wrong. I just need a bit of time
when I don't have the wife and grandkids after me :-)

Cheers,
Wol

---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Carl Sorensen



On 7/25/11 3:34 PM, "Wols Lists" <[hidden email]> wrote:

> On 25/07/11 22:28, Jan Warchoł wrote:
>> I get it too...
>> I tried inserting random parentheses, but it didn't work.

Random parentheses *never* work in Scheme; they only cause more problems.

In C++ it's possible to add parentheses without causing problems; in Scheme
every time you add a parenthesis you create a new evaluation.  In fact,
several of Wol's problems were extra parentheses.

>>
>> I've uploaded your new patch set to Rietveld
>> (http://codereview.appspot.com/4800051), hopefully it will help in
>> pinpointing the problem with Scheme syntax.
>> My apologies for delay!
>>
>> thanks for your work!
>> Janek
>>
> Thanks.
>
> As always, the problem is finding time, I'm planning to delete most of
> the code and put it back line by line - taking a sort of "divide and
> conquer" to try and work out what's wrong. I just need a bit of time
> when I don't have the wife and grandkids after me :-)
Did my revised patch not get to you?  It works.  Please don't try to go
through line-by-line!  That would be a frustrating experience and a poor use
of your limited time.

I've reattached the patch to this email.  It should apply to master.

Thanks,

Carl


0001-Add-capo-chord-names.patch (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Jan Warchol
W dniu 25 lipca 2011 23:45 użytkownik Carl Sorensen
<[hidden email]> napisał:

>
> On 7/25/11 3:34 PM, "Wols Lists" <[hidden email]> wrote:
>
>> On 25/07/11 22:28, Jan Warchoł wrote:
>>> I get it too...
>>> I tried inserting random parentheses, but it didn't work.
>
> Random parentheses *never* work in Scheme; they only cause more problems.
>
> In C++ it's possible to add parentheses without causing problems; in Scheme
> every time you add a parenthesis you create a new evaluation.

I know...  I'm not Schematic enough.  I just wanted to try anything,
thought that maybe i'd save Wol some time by sheer luck :)

>>> I've uploaded your new patch set to Rietveld
>>> (http://codereview.appspot.com/4800051), hopefully it will help in
>>> pinpointing the problem with Scheme syntax.
>>> My apologies for delay!
>>>
>>> thanks for your work!
>>> Janek
>>>
>> Thanks.
>>
>> As always, the problem is finding time, I'm planning to delete most of
>> the code and put it back line by line - taking a sort of "divide and
>> conquer" to try and work out what's wrong. I just need a bit of time
>> when I don't have the wife and grandkids after me :-)
>
> Did my revised patch not get to you?  It works.

No, i didn't get it at all!  I don't see it in frog archives neither.

> Please don't try to go
> through line-by-line!  That would be a frustrating experience and a poor use
> of your limited time.
>
> I've reattached the patch to this email.  It should apply to master.

It does and i see no errors, everything fine!  Updated Rietveld.
Thanks Carl, you are great as usual!
Janek

---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Wols Lists
In reply to this post by Carl Sorensen
On 25/07/11 22:45, Carl Sorensen wrote:
> Did my revised patch not get to you?  It works.  Please don't try to go
> through line-by-line!  That would be a frustrating experience and a poor use
> of your limited time.

I remember your commented version of my code, which I tried to apply.
That was what went all wrong :-)

I don't remember receiving a proper patch. I do need to study it,
however, because part of the reason for me doing it is to learn some
Scheme :-)
>
> I've reattached the patch to this email.  It should apply to master.
>

Thanks, I'll play with it as soon as I get a chance. But if it works,
I'm quite happy for it to go into lilypond now as it stands ...

> Thanks,
>
> Carl
>
Cheers,
Wol

---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Carl Sorensen
In reply to this post by Wols Lists
On 7/25/11 6:16 PM, "Wols Lists" <[hidden email]> wrote:

> On 25/07/11 23:16, Carl Sorensen wrote:

>>
>> One -- you were missing an opening paragraph after one of the let
>> statements.
>
> Sounds a bit like PL/1 :-)

Oops, I meant parenthesis.  Getting senile is tough!

>>
>> Two -- you needed a let* instead of a let
>
> I noticed Neil used a let*, and wondered about that ... what is a let*,
> and what's the difference between that and a let?

let* is like let, but in let* a variable that is defined can be used later
on.

So

(let ((var1 10)
      (var2 (+ var1 10)))

will throw an error for "undefined variable var1"

but

(let* ((var1 10)
       (var2 (+ var1 10)))

will set the value of var1 to 10 and var2 to 20.


>>
>> So in C, you can add extra parentheses.  In Scheme, you can't.
>
> Ah. And it is pretty much standard, in C and Fortran, to enclose your
> conditional in parentheses (indeed, in Fortran, I think you have to...)

Yes, that's true.  When working in Scheme, don't think of parentheses as
grouping operators, like in FORTRAN or C.  Parentheses in Scheme bound
expressions; the first element in a parenthesis-bounded expression *must* be
an evaluatable symbol (e.g. a procedure or an operator).

> Ta muchly,

No problem.  I remember the first days of trying to wade through Guile and
LilyPond.  It can be challenging....


Carl


---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Wols Lists
On 26/07/11 08:24, Carl Sorensen wrote:

> let* is like let, but in let* a variable that is defined can be used later
> on.
>
> So
>
> (let ((var1 10)
>       (var2 (+ var1 10)))
>
> will throw an error for "undefined variable var1"
>
> but
>
> (let* ((var1 10)
>        (var2 (+ var1 10)))
>
> will set the value of var1 to 10 and var2 to 20.
>
Do you mean let* will allow you to use the variable further down the
variable definition section?

Because I presume let will allow you to use the variable later on in the
statement section, or what's the point of defining it?

That's what your example seems to show ...

Cheers,
Wol

---
----
Join the Frogs!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Guitar capo code in scheme

Carl Sorensen



On 7/26/11 11:07 AM, "Wols Lists" <[hidden email]> wrote:

> On 26/07/11 08:24, Carl Sorensen wrote:
>> let* is like let, but in let* a variable that is defined can be used later
>> on.
>>
>> So
>>
>> (let ((var1 10)
>>       (var2 (+ var1 10)))
>>
>> will throw an error for "undefined variable var1"
>>
>> but
>>
>> (let* ((var1 10)
>>        (var2 (+ var1 10)))
>>
>> will set the value of var1 to 10 and var2 to 20.
>>
> Do you mean let* will allow you to use the variable further down the
> variable definition section?

Yes, precisely.  I'm sorry I was unclear.

Here's the definition from the Guile docs.

<http://www.gnu.org/software/guile/manual/html_node/Local-Bindings.html#Loca
l-Bindings>

Thanks,

Carl


---
----
Join the Frogs!

Loading...