Subject: scheme : récupérer la métrique

From: Daniel Cartron <[email-masked]>
Date: Mon, 27 Apr 2015 08:51:07 +0200

Bonjour,

Je me suis inspiré de extractMusic de Gilles et de code que m'a envoyé Nicolas 
pour écrire ce qui suit mais il ne se passe rien... Ce que je cherche à faire 
c'est mettre ces valeurs dans des variables globales pour les réutiliser dans 
d'autres fonctions.

getTimeSig = #(define-music-function (parser location music) (ly:music?)
 ""
(define beatLen 0)
(define beatStr 0)
(define beatNum 0)
  (music-map
    (lambda (evt)
      (cond (eq? (ly:music-property music 'name) 'TimeSignatureMusic)
        (let 
          (
            (beatLen (ly:music-property evt 'denominator #f))
            (beatStr (ly:music-property evt 'beat-structure #f))
            (beatNum (ly:music-property evt 'numerator #f))
          )
        )
      )
      evt
     )
     music
  )
)

music = \relative c' {
  \time 7/4
  a4 b c e d f
}

{\getTimeSig \music}

-- 
Cordialement, Daniel Cartron
« La terre étant ronde, les kilomètres devraient être ronds et non carrés. »
Ramon Gomez de la Serna

---

From: Olivier Miakinen <[email-masked]>
Date: Mon, 27 Apr 2015 09:14:02 +0200

Bonjour,

Je ne connais pas le scheme, mais j'ai pas mal pratiqué un dialecte du
lisp et ça me semble très proche. Je réponds comme si c'était du lisp,
les spécialistes me corrigeront.

> getTimeSig = #(define-music-function (parser location music) (ly:music?)

Ok, tu définis trois variables globales.

>       (cond (eq? (ly:music-property music 'name) 'TimeSignatureMusic)

Définition et utilisation de variables locales.

>             (beatNum (ly:music-property evt 'numerator #f))

Les variables *locales* beatLen, beatStr et beatNum existent ici.

Ici elles n'existent plus. Les variables globales du début redeviennent
visibles, avec leur valeur 0.

>      music

Pour modifier la valeur des variables globales, en lisp je ferais ceci :

      (when (eq? (ly:music-property music 'name) 'TimeSignatureMusic)
            (setq beatLen (ly:music-property evt 'denominator #f))
            (setq beatStr (ly:music-property evt 'beat-structure #f))
            (setq beatNum (ly:music-property evt 'numerator #f))
      )

Est-ce la même chose en scheme ?

---

From: Olivier Miakinen <[email-masked]>
Date: Mon, 27 Apr 2015 09:38:33 +0200

Ah, une autre remarque, toujours en supposant que c'est du lisp.
En passant du « cond » au « when » j'aurais dû supprimer une paire
de parenthèses. Si je ne l'ai pas fait, c'est que ton « cond » était
incorrect :

>             (beatNum (ly:music-property evt 'numerator #f))

Il aurait fallu :

      (cond
       (
        (eq? (ly:music-property music 'name) 'TimeSignatureMusic)
        (let
          (
            (beatLen (ly:music-property evt 'denominator #f))
            (beatStr (ly:music-property evt 'beat-structure #f))
            (beatNum (ly:music-property evt 'numerator #f))
          )
        )
       )
      )

-- 
Olivier Miakinen

---

From: PharoahS <[email-masked]>
Date: Mon, 27 Apr 2015 01:24:47 -0700 (MST)

En Scheme les fonctions ont souvent des noms differents et donner un code en
lisp a peu de chance de marcher en scheme
regardez ce tableau d'équivalences:
http://www.cs.utexas.edu/~novak/schemevscl.html
<http://www.cs.utexas.edu/~novak/schemevscl.html>  

--
View this message in context: http://lilypond-french-users.1298960.n2.nabble.com/scheme-recuperer-la-metrique-tp7582851p7582855.html
Sent from the LilyPond French Users mailing list archive at Nabble.com.

---

From: Daniel Cartron <[email-masked]>
Date: Mon, 27 Apr 2015 10:27:17 +0200

> lisp a peu de chance de marcher en scheme

Merci pour le tableau ça pourra me servir si je trouve une bonne idée dans un 
autre scheme que le guile mais en l'occurence c'est du code qui marche dans 
lilypond dont je suis parti, sauf que j'arrive pas à mettre l'info dans la 
fariable, on dirait que mon cond ne comprend pas ce que je veux...

-- 
Cordialement, Daniel Cartron
« Il vaut mieux mobiliser son intelligence sur des conneries que sa connerie 
sur des choses intelligentes. »
Devise Shadock

---

From: PharoahS <[email-masked]>
Date: Mon, 27 Apr 2015 02:28:39 -0700 (MST)

Quand dans guile tu fais
(define x 3)
tu as x = 3
puis (let ((x 33)) (+ x 1))
çà donne 34 mais quand tu tapes x çà donne toujours 3. C'est çà ton
probleme?
si tu veux mettre à jour x à 34
(set! x (let ((x 33)) (+ x 1))) va donner x = 34
bref set! met à jour et let copie

--
View this message in context: http://lilypond-french-users.1298960.n2.nabble.com/scheme-recuperer-la-metrique-tp7582851p7582857.html
Sent from the LilyPond French Users mailing list archive at Nabble.com.

---

From: Christophe Pochon <[email-masked]>
Date: Mon, 27 Apr 2015 11:42:42 +0200

Comme ça ça fonctionne :

%%%%%%%%%%%%%%%%

#(define beatLen 0)

#(define beatStr 0)

#(define beatNum 0)

#(define (parse-music mus)

; traitement commun

(display "-----------\n")

; traitement particulier

(let((name (ly:music-property mus 'name)))

(cond

((eq? name 'NoteEvent)

(display "NoteEvent\n")

)

((eq? name 'EventChord)

(display "Accord\n")

)

((eq? name 'GraceMusic)

(display "Grace\n")

)

((eq? name 'TimeSignatureMusic)

(display "TimeSignature\n")

(set! beatLen(ly:music-property mus 'denominator #f))

(set! beatStr (ly:music-property mus 'beat-structure #f))

(set! beatNum (ly:music-property mus 'numerator #f))

))

))

makeTab = #(define-music-function (parser location mus) (ly:music?)

(let ((notes (extract-named-music mus '(NoteEvent EventChord GraceMusic
TimeSignatureMusic))))

 (for-each parse-music notes)

mus

)

(display beatLen) (newline)

(display beatStr) (newline)

(display beatNum)

 )

music = \relative c' { \time 7/4 <c e>4 d \grace dis8 e2 }

{ \makeTab \music }

%%%%%%%%%%%%%%%

Christophe Pochon
http://www.christophe-pochon.com

Le 27 avril 2015 11:28, PharoahS <[email-masked]> a écrit :

> View this message in context:
> http://lilypond-french-users.1298960.n2.nabble.com/scheme-recuperer-la-metrique-tp7582851p7582857.html
> _______________________________________________
> liste de diffusion lilypond-user-fr
> [email-masked]
> https://lists.gnu.org/mailman/listinfo/lilypond-user-fr
>

---

From: Daniel Cartron <[email-masked]>
Date: Mon, 27 Apr 2015 11:52:23 +0200

> Comme ça ça fonctionne :

Aïe non :
La fonction music ne peut retourner #<unspecified>.

-- 
Cordialement, Daniel Cartron
« Un jeune enfant, sur son pot, s'efforçait.
  Moralité : Le petit poussait »
Alphonse Allais

---

From: "Olivier Miakinen" <[email-masked]>
Date: Mon, 27 Apr 2015 05:45:56 -0400

On Mon, 27 Apr 2015 10:27:17 +0200, Daniel Cartron répondait à PharoahS
>
>> En Scheme les fonctions ont souvent des noms differents et donner un code
>> en lisp a peu de chance de marcher en scheme

Selon le tableau, il faudrait donc écrire « set! » à la place de « setq ».
Mais qu'en est-il du « when » ?

> Merci pour le tableau ça pourra me servir si je trouve une bonne 
> idée dans un autre scheme que le guile mais en l'occurence c'est du 
> code qui marche dans lilypond dont je suis parti, sauf que j'arrive 
> pas à mettre l'info dans la variable, on dirait que mon cond ne 
> comprend pas ce que je veux...

Tu n'as pas eu mes deux réponses ? Il y avait semble-t-il deux
problèmes, l'un concernant la définition de variables locales qui
cachaient les variables globales, l'autre concernant la syntaxe
du « cond ».

-- 
Olivier Miakinen

---

From: Christophe Pochon <[email-masked]>
Date: Mon, 27 Apr 2015 12:11:59 +0200

Oui, c'était mes display de débuggage qui mettaient le bazar

comme ça c'est mieux :

%%%%%%%%%%%%%%

\version "2.19.15"

#(define beatLen 0)

#(define beatStr 0)

#(define beatNum 0)

; traitement commun

; traitement particulier

(cond

((eq? name 'NoteEvent)

(display "NoteEvent\n")

)

((eq? name 'EventChord)

(display "Accord\n")

)

((eq? name 'GraceMusic)

(display "Grace\n")

)

))

))

mus

)

 )

{ \makeTab \music }

%%%%%%%%%%%%%%%

Christophe Pochon

---

From: Gilles THIBAULT <[email-masked]>
Date: Mon, 27 Apr 2015 12:12:37 +0200

> getTimeSig = #(define-music-function (parser location music) (ly:music?)
Pour des variables "globales, il faut mettre les define en dehors de la 
fonction.

>       (cond (eq? (ly:music-property music 'name) 'TimeSignatureMusic)
Je suppose que c'est (ly:music-property evt 'name) que tu veux.

Un truc comme ça devrait marcher.

%%%%%%%%%%%%%%%%%%%%%%
#(define beatLen 0)
#(define beatStr 0)
#(define beatNum 0)

getTimeSig = #(define-music-function (parser location music) (ly:music?)
 ""
  (music-map
    (lambda (evt)
      (if (eq? (ly:music-property evt 'name) 'TimeSignatureMusic)
        (begin
          (set! beatLen (ly:music-property evt 'denominator #f))
          (set! beatStr (ly:music-property evt 'beat-structure #f))
          (set! beatNum (ly:music-property evt 'numerator #f))))
      evt)
     music))

displayBeatVariables = #(define-music-function (parser location music) 
(ly:music?)
 ""
  (format #t " beatLen : ~a\n beatStr : ~a\n beatNum : ~a\n" beatLen beatStr 
beatNum)
  music)

    %%%%%%%%%%%
music = \relative c' {
  \time 7/4
  a4 b c e d f
}

{ \displayBeatVariables \getTimeSig \music}

-- 
Gilles

---

From: Christophe Pochon <[email-masked]>
Date: Mon, 27 Apr 2015 12:16:20 +0200

Une version modifiée qui affiche la métrique en cours à chaque NoteEvent.
Ce qui prouve que les valeurs globales sont bien globales ;-)

%%%%%%%%%%%%%%

\version "2.19.15"

#(define beatLen 0)

#(define beatStr 0)

#(define beatNum 0)

; traitement commun

; traitement particulier

(cond

((eq? name 'NoteEvent)

(display "NoteEvent\n")

(display beatNum)

(display "/")

)

((eq? name 'EventChord)

(display "Accord\n")

)

((eq? name 'GraceMusic)

(display "Grace\n")

)

))

))

mus

)

 )

music = \relative c' { \time 4/4 <c e>4 d \grace dis8 e2 \time 7/4 e4 d c
e2 c }

{ \makeTab \music }

%%%%%%%%%%%%%%%

Christophe Pochon

Le 27 avril 2015 12:11, Christophe Pochon <[email-masked]> a

---

From: Daniel Cartron <[email-masked]>
Date: Mon, 27 Apr 2015 13:19:58 +0200

Le lundi 27 avril 2015, 12:16:20 Christophe Pochon a écrit :
> Ce qui prouve que les valeurs globales sont bien globales
Je suis comblé !

ça marche très bien, il me reste juste à intégrer tout ça, je risque de vous 
(la liste) laisser tranquille quelque temps ;-)

-- 
Cordialement, Daniel Cartron
« Si Adam avait été homosexuel, personne ne serait là pour le dire. »
Oscar Wilde

---

From: Daniel Cartron <[email-masked]>
Date: Mon, 27 Apr 2015 15:08:51 +0200

> Un truc comme ça devrait marcher.

J'y étais presque... J'avais juste mis music au lieu de evt dans  (if (eq? 
(ly:music-property

Bon ça me rassure j'avais pigé, c'était juste une faute d'étourderie.

-- 
Cordialement, Daniel Cartron
« Il y a des femmes dont l'infidélité est le seul lien qui les attachent à leur 
mari. »
Sacha Guitry —  Bloompott, exergue du chapitre 13

---

From: PharoahS <[email-masked]>
Date: Mon, 27 Apr 2015 13:45:27 -0700 (MST)

On a vu l' intérêt de set! qui modifie sa donnée d'entrée. En cherchant sur
internet j'ai vu que pour les deux langages de programmation Scheme et Ruby
le suffixe ! indique que la fonction modifie la donnée concernée.

--
View this message in context: http://lilypond-french-users.1298960.n2.nabble.com/scheme-recuperer-la-metrique-tp7582851p7582869.html
Sent from the LilyPond French Users mailing list archive at Nabble.com.

---

From: Daniel Cartron <[email-masked]>
Date: Tue, 28 Apr 2015 15:09:38 +0200

Le , 00:00:00 Olivier Miakinen a écrit :
> Tu n'as pas eu mes deux réponses ?

Non désolé mais j'ai un courielleur un peu sévère dans la chasse aux spams et 
tes messages étaient partis dans la boite pourriels... Où je viens de les 
trouver, mais je n'y fais le ménage qu'une fois par jour et à peine...

En tout cas merci pour tes remarques, c'est vrai que j'ai encore du mal à me 
faire au fait de devoir mettre deux parenthèses ouvrantes à la suite, c'est 
assez irrationnel pour moi. Mais il faut que je m'y fasse, c'est du scheme...

-- 
Cordialement, Daniel Cartron
« Un homme qui meurt par noyade revit en un éclair toute sa vie passée, alors 
qu'il ferait mieux de nager. »
François Cavanna - Le saviez-vous ?

---

From: Olivier Miakinen <[email-masked]>
Date: Tue, 28 Apr 2015 22:51:20 +0200

Bonjour,

Remarque préliminaire : cette fois j'ai pris le temps de chercher des
références sur Scheme. En particulier, cherchant l'équivalent en Scheme
des 'cond', 'if' et 'when' de Common Lisp, j'ai d'abord vu que le 'if'
est moins complet en Scheme qu'en CL et que le 'when' n'existe carrément
pas, puis j'ai compris en lisant la page suivante (en anglais) que
c'est une conséquence directe de deux philosophies différentes :
<http://symbo1ics.com/blog/?p=729>.

En gros, Scheme privilégie la syntaxe la plus simple possible permettant
de faire les choses, et élimine le superflu, alors que Common Lisp garde
toutes les différentes façons de faire la même chose, pourvu que chacune
ait son intérêt.

> le suffixe ! indique que la fonction modifie la donnée concernée.

C'est une convention assez sympa : un suffixe ! pour dire que ça
modifie la donnée et un suffixe ? pour les prédicats (tests retournant
un booléen). En Common Lisp, on a généralement un préfixe n (pour dire
'non-conservatif' si j'ai bien compris) à la place du suffixe ! et un
suffixe p (prédicat) à la place du suffixe ?, mais ce n'est hélas pas
systématique.

---

From: Olivier Miakinen <[email-masked]>
Date: Tue, 28 Apr 2015 23:10:53 +0200

> trouver, mais je n'y fais le ménage qu'une fois par jour et à peine...

;-)

> assez irrationnel pour moi. Mais il faut que je m'y fasse, c'est du scheme...

Pour l'accepter -- et le retenir -- il faut comprendre la raison de ce
choix. En Scheme ils ont conservé seulement deux syntaxes pour les
conditions, l'une (if) permettant juste deux choix (oui / non) avec à
chaque fois une seule instruction, l'autre (cond) permettant un nombre
quelconque de choix avec potentiellement un nombre quelconque
d'instructions par choix.

1) syntaxe simple :
   (if test expr_oui expr_non)

2) syntaxe complète :
   (cond
     (test1 expr1a expr1b expr1c expr1d ...)
     (test2 expr2a expr2b expr2c expr2d ...)
     (test3 expr3a expr3b expr3c expr3d ...)
     ...
   )

S'il n'y avait pas les paires de parenthèses en plus dans le cond,
on ne pourrait avoir qu'une seule instruction par condition, ou alors
il faudrait rajouter des (begin ...) après chaque test. Sachant que
le cond est déjà pour les tests assez lourds (possibilité de tester
plein de conditions différentes), ça permet d'éviter de l'alourdir
encore plus avec des tas de (begin ...) dont on n'a que faire.

P.-S. : Pour la petite histoire, en Common Lisp on a un if permettant
 plusieurs choix comme le cond mais avec une seule instruction par
 choix, mais aussi un when permettant un seul choix mais plusieurs
 instructions si le test est vrai, et un unless qui est un when à
 l'envers...

Cordialement,
-- 
Olivier Miakinen

---

From: Daniel Cartron <[email-masked]>
Date: Wed, 29 Apr 2015 06:40:47 +0200

Le mardi 28 avril 2015, 23:10:53 Olivier Miakinen a écrit :
> il faudrait rajouter des (begin ...) après chaque test.

Bon alors je vais pouvoir supprimer tous mes begin alors :-) Merci beaucoup, 
je n'avais pas compris ça. Faut dire que la doc sur le scheme guile est pas 
mal succincte, ça fait plus aide-mémoire pour celui qui sait que tuto pour 
débutant. Et ça manque cruellement d'exemples de code commentés, il y en a 
très peu. Et en plus quelque soit le site où on va c'est toujours les mm pages 
recopiées à partir de la doc officielle...

-- 
Cordialement, Daniel Cartron
« Si l'Administration militaire faisait correctement son travail, il n'y 
aurait pas de Soldat inconnu. »
François Cavanna - Le saviez-vous ?