Re: New hosting for Urs Liska's Scheme WIP book

2022-11-04 Thread Jean Abou Samra

Le 04/11/2022 à 14:43, David Kastrup a écrit :

Jean Abou Samra  writes:



P.S. The Internals Reference gives a (quite technical) explanation of
make-relative:

https://lilypond.org/doc/v2.23/Documentation/internals/scheme-functions

That description is a bunch of incomprehensible gobbledegook unsuitable
for figuring out anything you don't know already.



For the record, this discussion led to
https://gitlab.com/lilypond/lilypond/-/merge_requests/1711
and
https://gitlab.com/lilypond/lilypond/-/merge_requests/1712

Best,
Jean




OpenPGP_signature
Description: OpenPGP digital signature


Re: New hosting for Urs Liska's Scheme WIP book

2022-11-04 Thread Jean Abou Samra

Le 04/11/2022 à 15:20, David Kastrup a écrit :

Ok, I'll give the doc text another try, but the documentation block in
the manual starts with:

 Macro: make-relative …

which is missing the input arguments from

 (define-syntax-rule-public (make-relative (variables ...) reference music)

Is that fixable in some manner?  If necessary, creating a
LilyPond-specific version of define-syntax-rule-public ?




Guile doesn't give us the arguments from the header of a
define-syntax-rule, at least not in the same way it does
for procedures.

$ ~/lilies/2.23.80/bin/lilypond scheme-sandbox
GNU LilyPond 2.23.80 (running Guile 2.2)
[...]
scheme@(#{ g101}#)> (use-modules (ice-9 session))
scheme@(#{ g101}#)> (procedure-arguments (macro-transformer (module-ref 
(current-module) 'make-relative)))
$1 = ((required x) (optional) (keyword) (allow-other-keys? . #f) (rest . 
#f))



It says there is a single argument "x" to the syntax transformer,
which is indeed true considering that it is a procedure taking
a single syntax object. Essentially,

(define-syntax-rule (name )
  )

expands to

(define-syntax name
  (lambda (x)
    (syntax-case x ()
  ((_ )
   (syntax )

The lambda ends up having "x" as its only argument. I don't believe
Guile retains the info of what  is as some sort of metadata on
the lambda.

Of course, you could change the definition of
define-syntax-rule-public in lily.scm from

(define-syntax-rule (define-syntax-rule-public (name . args) . rest)
  (begin
    (define-syntax-rule (name . args) . rest)
    (export name)))

to

(define single-rule-macro-signature (make-object-property))

(define-syntax-rule (define-syntax-rule-public (name . args) . rest)
  (begin
    (define-syntax-rule (name . args) . rest)
    (set! (single-rule-macro-signature (module-ref (current-module) 'name))
  'args)
    (export name)))


and then use that in the doc autogeneration.

That being said ... a quick git grep shows only one site, make-relative,
where this could be somewhat useful. In your shoes, I would not bother
doing this and just mention the signature in the docstring itself in
plain English.

Jean



OpenPGP_signature
Description: OpenPGP digital signature


Re: New hosting for Urs Liska's Scheme WIP book

2022-11-04 Thread David Kastrup
David Kastrup  writes:

> Jean Abou Samra  writes:
>
>> Le 04/11/2022 à 12:09, Jean Abou Samra a écrit :
>>> Also, you will have surprises with \relative because
>>> the note appears twice, with its octave marks. You
>>> can use make-relative to fix that.
>>
>> P.S. The Internals Reference gives a (quite technical) explanation of
>> make-relative:
>>
>> https://lilypond.org/doc/v2.23/Documentation/internals/scheme-functions
>
> That description is a bunch of incomprehensible gobbledegook unsuitable
> for figuring out anything you don't know already.
>
> Whoever wrote that...  Wait, that was me.
>
> Scheme function doc strings were not printed in the manuals back then
> but that is not much of a defense.  Maybe I need to try again.  Or
> someone else, assuming that anybody understands what this is supposed to
> do.

Ok, I'll give the doc text another try, but the documentation block in
the manual starts with:

Macro: make-relative …

which is missing the input arguments from

(define-syntax-rule-public (make-relative (variables ...) reference music)

Is that fixable in some manner?  If necessary, creating a
LilyPond-specific version of define-syntax-rule-public ?

-- 
David Kastrup



Re: New hosting for Urs Liska's Scheme WIP book

2022-11-04 Thread David Kastrup
Jean Abou Samra  writes:

> Le 04/11/2022 à 12:09, Jean Abou Samra a écrit :
>> Also, you will have surprises with \relative because
>> the note appears twice, with its octave marks. You
>> can use make-relative to fix that.
>
> P.S. The Internals Reference gives a (quite technical) explanation of
> make-relative:
>
> https://lilypond.org/doc/v2.23/Documentation/internals/scheme-functions

That description is a bunch of incomprehensible gobbledegook unsuitable
for figuring out anything you don't know already.

Whoever wrote that...  Wait, that was me.

Scheme function doc strings were not printed in the manuals back then
but that is not much of a defense.  Maybe I need to try again.  Or
someone else, assuming that anybody understands what this is supposed to
do.

-- 
David Kastrup



Re: New hosting for Urs Liska's Scheme WIP book

2022-11-04 Thread Jean Abou Samra

Le 04/11/2022 à 12:09, Jean Abou Samra a écrit :

Also, you will have surprises with \relative because
the note appears twice, with its octave marks. You
can use make-relative to fix that.


P.S. The Internals Reference gives a (quite technical) explanation of 
make-relative:


https://lilypond.org/doc/v2.23/Documentation/internals/scheme-functions



OpenPGP_signature
Description: OpenPGP digital signature


Re: New hosting for Urs Liska's Scheme WIP book

2022-11-04 Thread Jean Abou Samra

Le 04/11/2022 à 00:13, Karlin High a écrit :

Could a music function or something be shorthand for that? Let's see...

 



That page is pretty ideal. Here's the general form, what it contains, 
and how it can be used.




Well yes; however, the Scheme tutorials at hand are mostly about
the Scheme language itself, not so much about its integration with
LilyPond. In other words, they're kind of a substitute for this part
of the official documentation:

https://lilypond.org/doc/v2.23/Documentation/extending/introduction-to-scheme

That part is (from experience) mostly useless as a beginner. It
does not even mention let* !



I ended up with this:

%
\version "2.23.80"
uniTwo = #(define-music-function
   (uniNote)
   (ly:music?)
   #{
 << { \voiceOne #uniNote }
    \new Voice { \voiceTwo #uniNote }
 >> \oneVoice
   #})

{ c'4 \uniTwo e' g' }
%

I may end up replacing all the chords with the temporary-polyphony 
construct. And I may get told my \uniTwo function is very far from 
best practice.





Better use $uniNote for at least one of the two occurrences,
so as to make a copy of the note. Otherwise, you might
have surprises when applying music functions to the result,
because the note is shared. For example:

\version "2.23.80"
uniTwo = #(define-music-function
   (uniNote)
   (ly:music?)
   #{
 % Using $uniNote instead of #uniNote would fix the problem.
 << { \voiceOne #uniNote }
    \new Voice { \voiceTwo #uniNote }
 >> \oneVoice
   #})

% Transposition should yield G notes, but yields B flat notes
% as it is done twice, due to sharing.
\new Staff \transpose e' g' { \uniTwo e' \uniTwo e' }


Also, you will have surprises with \relative because
the note appears twice, with its octave marks. You
can use make-relative to fix that.

So, overall, better do:


\version "2.23.80"

uniTwo =
#(define-music-function (uniNote) (ly:music?)
   (make-relative
    (uniNote)
    uniNote
    #{
  << { \voiceOne $uniNote }
 \new Voice { \voiceTwo $uniNote }
  >> \oneVoice
    #}))

\new Staff \transpose e' g' \relative { \uniTwo e' \uniTwo e' }


Best,
Jean



OpenPGP_signature
Description: OpenPGP digital signature


Re: Trying to write a scheme function

2022-11-04 Thread Jean Abou Samra

Hi Valentin,

Just a small correction:

Le 04/11/2022 à 09:02, Valentin Petzel a écrit :

For checking equality we have three basic functions: eq?, eqv? and equal?. eq?
checks if we reference the same object, but fails for numbers and strings.
eqv? does the same, but with numbers and strings it compares the values.



You mean characters (not strings).

Also note that eq? is not even guaranteed to fail on numbers and
characters -- it's unspecified. For example, with Guile 2.2:

scheme@(guile-user)> (eq? (expt 2 10) (expt 2 10))
$1 = #t
scheme@(guile-user)> (eq? (expt 2 100) (expt 2 100))
$2 = #f

Cheers,
Jean



OpenPGP_signature
Description: OpenPGP digital signature


Re: Trying to write a scheme function

2022-11-04 Thread Valentin Petzel
Hello David,

There are two main problems with your code:

c, d, e,2 are *not* valid scheme expressions. If you wrap one of these 
expressions in #{ ... #} like this

#(display #{ c, #})

you’ll see that c, is parsed as *pitch*, while e,2 is parsed as music of type 
NoteEvent. These can also be directly constructed using scheme.

If you enter c, as music you get music of type NoteEvent, with the same 
duration as the previous note (this is done by the parser).

So really your way of matching if the user entered c, cannot really be done, 
you can only match if the entered pitch was c, or if the note has a specific 
duration.

The second big problem is the way how you check pitch equality. The (= ...) is 
a numeric comparison and should thus only be used for numbers.

For checking equality we have three basic functions: eq?, eqv? and equal?. eq? 
checks if we reference the same object, but fails for numbers and strings. 
eqv? does the same, but with numbers and strings it compares the values. 
equal? is like eqv? but also allows comparing collections like lists for 
(content) equality.

So in your case you want to check equality of pitch or duration by using 
equal?).

About using a music function: If your function is intended to always return 
music, then probably yes.

Cheers,
Valentin

Am Freitag, 4. November 2022, 01:18:44 CET schrieb dfro:
> Hello everyone,
> I would like to create a function that transforms one note to another
> using scheme's cond procedure. This is what I have working so far using
> an arg of type number?:
> 
> %start code
> \version "2.22.2"
> 
> tNote =
> #(define-scheme-function
>(note)
>(number?)
>(_i "Transform one note to another using cond")
>(cond ((= note 1) #{ { c } #})
>  ((= note 2) #{ { c' } #})
>  ((= note 3) #{ { c''2 } #})
>  (else #{ s #})
>  )
>)
> 
> 
> { \tNote 1 \tNote 5 \tNote 2 \tNote 3 }
> %end code
> 
> _
> 
> I want the type to be ly:music? and the cond procedure to evaluate a
> note rather than a number. The following code does not work (I get an
> 'Unbound variable" error), but I think it shows what I am trying to do:
> 
> %start code
> \version "2.22.2"
> 
> tNote =
> #(define-scheme-function
>(note)
>(ly:music?)
>(_i "Transform one note to another using cond")
>(cond ((= note c,) #{ { c } #})
>  ((= note d,) #{ { c' } #})
>  ((= note e,2) #{ { c''2 } #})
>  (else #{ s #})
>  )
>)
> 
> 
> { \tNote c, \tNote f \tNote d, \tNote e,2 }
> %end code
> 
> _
> 
> Should I be creating a music function rather than a scheme function?
> 
> Any thoughts on how to get this working and why it works? Thanks for any
> help and for the mailing list.
> 
> Peace,
> David



signature.asc
Description: This is a digitally signed message part.