Résolution de l'équation iScheme = infix (Scheme)

Bonjour tutti,

Depuis que j’utilise LilyPond, le frein, voire le mur, que représente la syntaxe Scheme pour les utilisateurs lambda me turlupine.
Pratiquement tous sont incapables de comprendre les solutions que les gentils aideurs comme Jean leur fournissent, sans parler de les adapter/ré-utiliser pour leurs besoins. En un mot, il ne peuvent pas être autonomes.

En y réfléchissant, on pourrait définir une syntaxe infixée au-dessus de Scheme, beaucoup proche de celles des langages ‘usuels’. Appelons-le iScheme.

La bascule en syntaxe iScheme pourrait se faire avec un @, par exemple.

Ainsi :

#(define (grow-in-up-direction beam)
   (let* ((Y-positions (ly:grob-property beam 'positions))
          (left-position (car Y-positions))
          (right-position (cdr Y-positions)))
     (cond
       ((< left-position right-position)
        RIGHT)
       ((> left-position right-position)
        LEFT)
       (else
        CENTER))))

\relative c' {
  \override Beam.grow-direction = #grow-in-up-direction
  c'16 d e f g f e d c g c g c e g c
}

pourrait s’écrire avec iScheme:

@define grow-in-up-direction (beam) {
  let* {
    Y-positions    = ly:grob-property (beam, 'positions),
    left-position  = car (Y-positions),
    right-position = cdr (Y-positions);

    cond {
      left-position < right-position:
        RIGHT;

      left-position > right-position:
        LEFT;

      else:
        CENTER;
    }
  }
}

\relative c' {
  \override Beam.grow-direction = @grow-in-up-direction
  c'16 d e f g f e d c g c g c e g c
}

Les noms de fonctions s’écrivent avant la parenthèse contenant les arguments, qui sont séparés par des virugles.
Les accolades servent à structurer les choses.

Cerise sur le gâteux, les noms des fonctions de base comme define, let*, cond, if et else pourraient être dans d’autres langues que l’anglais.

Pensez-vous que cela pourrait être utile?

JM

Bonjour Jacques.

J'approuve complètement ta démarche, bravo.

Je suis sur que Jean va réfléchir et donner une solution.

A+

Hello,

L'idée est excellente, mais il faudrait un truc comme bison et flex pour parser le tout. Et ça, je ne sais plus faire...

La biblio donne beaucoup de réponses sur Scheme to C, mais pas l'inverse, c'est que ça doit être graton comme on dit à Lyon.

Utile, je pense quand même : combien parmi les anciens (dont je fais partie) et même la jeunesse ont appris LISP à l'école (et même parfois sous la torture), juste pour le partiel de juin ?

Dès qu'on a compris que c'était un langage à pile, je pense qu'on a compris beaucoup de choses (d'mon temps, on apprenait même la notation polonaise inverse ! )

Du coup, Scheme devient relativement listble, mais... de là à être écrit... Donc utile, et ça vaudrait presque le coup d'y mettre un thésard en info !

C'était mon petit avis du soir.

Bon courage, bravo pour tous ces posts enrichissants, et bonne fin de journée à tous,

Bernard.

···

Le 08/06/2022 à 18:41, Jacques Menu a écrit :

Bonjour tutti,

Depuis que j’utilise LilyPond, le frein, voire le mur, que représente la syntaxe Scheme pour les utilisateurs lambda me turlupine.
Pratiquement tous sont incapables de comprendre les solutions que les gentils aideurs comme Jean leur fournissent, sans parler de les adapter/ré-utiliser pour leurs besoins. En un mot, il ne peuvent pas être autonomes.

En y réfléchissant, on pourrait définir une syntaxe infixée au-dessus de Scheme, beaucoup proche de celles des langages ‘usuels’. Appelons-le iScheme.

La bascule en syntaxe iScheme pourrait se faire avec un @, par exemple.

Ainsi :

#(define (grow-in-up-direction beam)
   (let* ((Y-positions (ly:grob-property beam 'positions))
          (left-position (car Y-positions))
          (right-position (cdr Y-positions)))
     (cond
       ((< left-position right-position)
        RIGHT)
       ((> left-position right-position)
        LEFT)
       (else
        CENTER))))

\relative c' {
  \override Beam.grow-direction = #grow-in-up-direction
  c'16 d e f g f e d c g c g c e g c
}

pourrait s’écrire avec iScheme:

@define grow-in-up-direction (beam) {
  let* {
    Y-positions    = ly:grob-property (beam, 'positions),
    left-position  = car (Y-positions),
    right-position = cdr (Y-positions);

    cond {
      left-position < right-position:
        RIGHT;

      left-position > right-position:
        LEFT;

      else:
        CENTER;
    }
  }
}

\relative c' {
  \override Beam.grow-direction = @grow-in-up-direction
  c'16 d e f g f e d c g c g c e g c
}

Les noms de fonctions s’écrivent avant la parenthèse contenant les arguments, qui sont séparés par des virugles.
Les accolades servent à structurer les choses.

Cerise sur le gâteux, les noms des fonctions de base comme define, let*, cond, if et else pourraient être dans d’autres langues que l’anglais.

Pensez-vous que cela pourrait être utile?

JM

Juste en passant... Peut être qu'avec Bigloo Scheme ?...
Si quelqu'un a le temps de regarder...

···

Le 08/06/2022 à 19:08, Bernard Barbier a écrit :

Hello,

L'idée est excellente, mais il faudrait un truc comme bison et flex pour parser le tout. Et ça, je ne sais plus faire...

La biblio donne beaucoup de réponses sur Scheme to C, mais pas l'inverse, c'est que ça doit être graton comme on dit à Lyon.

Utile, je pense quand même : combien parmi les anciens (dont je fais partie) et même la jeunesse ont appris LISP à l'école (et même parfois sous la torture), juste pour le partiel de juin ?

Dès qu'on a compris que c'était un langage à pile, je pense qu'on a compris beaucoup de choses (d'mon temps, on apprenait même la notation polonaise inverse ! )

Du coup, Scheme devient relativement listble, mais... de là à être écrit... Donc utile, et ça vaudrait presque le coup d'y mettre un thésard en info !

C'était mon petit avis du soir.

Bon courage, bravo pour tous ces posts enrichissants, et bonne fin de journée à tous,

Bernard.

Le 08/06/2022 à 18:41, Jacques Menu a écrit :

Bonjour tutti,

Depuis que j’utilise LilyPond, le frein, voire le mur, que représente la syntaxe Scheme pour les utilisateurs lambda me turlupine.
Pratiquement tous sont incapables de comprendre les solutions que les gentils aideurs comme Jean leur fournissent, sans parler de les adapter/ré-utiliser pour leurs besoins. En un mot, il ne peuvent pas être autonomes.

En y réfléchissant, on pourrait définir une syntaxe infixée au-dessus de Scheme, beaucoup proche de celles des langages ‘usuels’. Appelons-le iScheme.

La bascule en syntaxe iScheme pourrait se faire avec un @, par exemple.

Ainsi :

#(define (grow-in-up-direction beam)
   (let* ((Y-positions (ly:grob-property beam 'positions))
          (left-position (car Y-positions))
          (right-position (cdr Y-positions)))
     (cond
       ((< left-position right-position)
        RIGHT)
       ((> left-position right-position)
        LEFT)
       (else
        CENTER))))

\relative c' {
  \override Beam.grow-direction = #grow-in-up-direction
  c'16 d e f g f e d c g c g c e g c
}

pourrait s’écrire avec iScheme:

@define grow-in-up-direction (beam) {
  let* {
    Y-positions    = ly:grob-property (beam, 'positions),
    left-position  = car (Y-positions),
    right-position = cdr (Y-positions);

    cond {
      left-position < right-position:
        RIGHT;

      left-position > right-position:
        LEFT;

      else:
        CENTER;
    }
  }
}

\relative c' {
  \override Beam.grow-direction = @grow-in-up-direction
  c'16 d e f g f e d c g c g c e g c
}

Les noms de fonctions s’écrivent avant la parenthèse contenant les arguments, qui sont séparés par des virugles.
Les accolades servent à structurer les choses.

Cerise sur le gâteux, les noms des fonctions de base comme define, let*, cond, if et else pourraient être dans d’autres langues que l’anglais.

Pensez-vous que cela pourrait être utile?

JM

Bonjour,

Hello,

L'idée est excellente, mais il faudrait un truc comme bison et flex
pour parser le tout. Et ça, je ne sais plus faire...

La biblio donne beaucoup de réponses sur /Scheme to C/, mais pas
l'inverse, c'est que ça doit être graton comme on dit à Lyon.

Guile 2 (la version de Guile utilisée dans LilyPond 2.23) possède un
équivalent à Bison qui permet d'écrire un analyseur syntaxique sans
sortir de Scheme, ou plutôt deux : un générateurs d'analyseurs LALR(1),
comme Bison, et un pour les analyseurs PEG.

Par conséquent, il serait tout à fait envisageable de définir cette
syntaxe dans un fichier à \include, sans toucher au code de LilyPond.

Utile, je pense quand même : combien parmi les anciens (dont je fais
partie) et même la jeunesse ont appris LISP à l'école (et même parfois
sous la torture), juste pour le partiel de juin ?

Dès qu'on a compris que c'était un langage à pile, je pense qu'on a
compris beaucoup de choses (d'mon temps, on apprenait même la notation
polonaise inverse ! )

Du coup, Scheme devient /relativement/ listble, mais... de là à être
écrit... Donc utile, et ça vaudrait presque le coup d'y mettre un
thésard en info !

Oh, pas besoin d'un thésard : une fois la syntaxe définie, je ne crois
pas que l'implémenter devrait poser de problème majeur. Par contre, à
titre personnel, je serai plutôt concentré sur les grilles d'accords
cette semaine.

Comme je le disais à Jacques, je suis curieux des réponses sur ce fil
(merci pour celles déjà données). Comme l'apprentissage de Scheme est un
point qui cause régulièrement des difficultés, j'aimerais comprendre où
ça coince. Mon expérience personnelle est plutôt faite d'un chemin
tortueux pour comprendre le principe de la programmation fonctionnelle,
mais il est tout à fait possible que pour d'autres cela soit plutôt
compliqué au niveau de la syntaxe parenthésée et préfixe.

Même si je n'imagine pas abandonner moi-même un jour la syntaxe «
normale », ne serait-ce que parce que tout le code Scheme de LilyPond
est écrit comme cela, je serai intéressé de voir si cela aide les débutants.

Juste en passant... Peut être qu'avec Bigloo Scheme ?...
Si quelqu'un a le temps de regarder...

À quoi fais-tu référence ? En lisant la table des matières de la
documentation de Bigloo Scheme, je n'ai rien trouvé qui parle de syntaxe
infixe.

Cordialement,
Jean

···

Le 08/06/2022 à 19:08, Bernard Barbier a écrit :

Bonjour,

Merci Jean de cette réponse.

Bonjour,

Hello,

L'idée est excellente, mais il faudrait un truc comme bison et flex pour parser le tout. Et ça, je ne sais plus faire...

La biblio donne beaucoup de réponses sur /Scheme to C/, mais pas l'inverse, c'est que ça doit être graton comme on dit à Lyon.

Guile 2 (la version de Guile utilisée dans LilyPond 2.23) possède un équivalent à Bison qui permet d'écrire un analyseur syntaxique sans sortir de Scheme, ou plutôt deux : un générateurs d'analyseurs LALR(1), comme Bison, et un pour les analyseurs PEG.

LALR(1) Parsing (Guile Reference Manual)

PEG Parsing (Guile Reference Manual)

Par conséquent, il serait tout à fait envisageable de définir cette syntaxe dans un fichier à \include, sans toucher au code de LilyPond.

Ça je ne savais pas et c'est exactement adapté.

Utile, je pense quand même : combien parmi les anciens (dont je fais partie) et même la jeunesse ont appris LISP à l'école (et même parfois sous la torture), juste pour le partiel de juin ?

Dès qu'on a compris que c'était un langage à pile, je pense qu'on a compris beaucoup de choses (d'mon temps, on apprenait même la notation polonaise inverse ! )

Du coup, Scheme devient /relativement/ listble, mais... de là à être écrit... Donc utile, et ça vaudrait presque le coup d'y mettre un thésard en info !

Oh, pas besoin d'un thésard : une fois la syntaxe définie, je ne crois pas que l'implémenter devrait poser de problème majeur. Par contre, à titre personnel, je serai plutôt concentré sur les grilles d'accords cette semaine.

Comme je le disais à Jacques, je suis curieux des réponses sur ce fil (merci pour celles déjà données). Comme l'apprentissage de Scheme est un point qui cause régulièrement des difficultés, j'aimerais comprendre où ça coince. Mon expérience personnelle est plutôt faite d'un chemin tortueux pour comprendre le principe de la programmation fonctionnelle, mais il est tout à fait possible que pour d'autres cela soit plutôt compliqué au niveau de la syntaxe parenthésée et préfixe.

Même si je n'imagine pas abandonner moi-même un jour la syntaxe « normale », ne serait-ce que parce que tout le code Scheme de LilyPond est écrit comme cela, je serai intéressé de voir si cela aide les débutants.

Bin... si on se pose la question d'analyse d'une partition (raccourci rapide !) : on la lit en entier, on empile et on dépile à la double barre... Scheme est exactement ce qu'il faut ! Après... il faut - je pense - déjà avoir un brin de connaissances pour, comme disait Jean, ne pas avoir peur du mur.

Alors, peut-être un tuto écrit comme tu aurais aimé qu'on te l'enseigne... D'expérience, ça marche souvent bien. J'ai fait ça (il y a longtemps) avec les machins bizarres comme les codes BCH, les corps de Gallois, et d'autres trucs étrangeoïdeaux et j'avais eu de bons retours des étudiants.

Juste en passant... Peut être qu'avec Bigloo Scheme ?...
Si quelqu'un a le temps de regarder...

À quoi fais-tu référence ? En lisant la table des matières de la documentation de Bigloo Scheme, je n'ai rien trouvé qui parle de syntaxe infixe.

Je me posais vraiment la question, sans apriori... tout bêtement, pour savoir si c'était adapté. Je n'avais pas le temps de regarder, et tu as répondu, donc merci !

Cordialement,
Jean

bien cordialement,

Bernard.

···

Le 08/06/2022 à 23:22, Jean Abou Samra a écrit :

Le 08/06/2022 à 19:08, Bernard Barbier a écrit :

Un tuto dans ce goût-là ?

https://tutoriel-scheme.readthedocs.io/

:slight_smile:

Cordialement,
Jean

···

Le 09/06/2022 à 10:12, Bernard Barbier a écrit :

Bonjour,

Merci Jean de cette réponse.

Le 08/06/2022 à 23:22, Jean Abou Samra a écrit :

Bonjour,

Le 08/06/2022 à 19:08, Bernard Barbier a écrit :

Hello,

L'idée est excellente, mais il faudrait un truc comme bison et flex
pour parser le tout. Et ça, je ne sais plus faire...

La biblio donne beaucoup de réponses sur /Scheme to C/, mais pas
l'inverse, c'est que ça doit être graton comme on dit à Lyon.

Guile 2 (la version de Guile utilisée dans LilyPond 2.23) possède un
équivalent à Bison qui permet d'écrire un analyseur syntaxique sans
sortir de Scheme, ou plutôt deux : un générateurs d'analyseurs
LALR(1), comme Bison, et un pour les analyseurs PEG.

LALR(1) Parsing (Guile Reference Manual)

PEG Parsing (Guile Reference Manual)

Par conséquent, il serait tout à fait envisageable de définir cette
syntaxe dans un fichier à \include, sans toucher au code de LilyPond.

Ça je ne savais pas et c'est exactement adapté.

Utile, je pense quand même : combien parmi les anciens (dont je fais
partie) et même la jeunesse ont appris LISP à l'école (et même
parfois sous la torture), juste pour le partiel de juin ?

Dès qu'on a compris que c'était un langage à pile, je pense qu'on a
compris beaucoup de choses (d'mon temps, on apprenait même la
notation polonaise inverse ! )

Du coup, Scheme devient /relativement/ listble, mais... de là à être
écrit... Donc utile, et ça vaudrait presque le coup d'y mettre un
thésard en info !

Oh, pas besoin d'un thésard : une fois la syntaxe définie, je ne
crois pas que l'implémenter devrait poser de problème majeur. Par
contre, à titre personnel, je serai plutôt concentré sur les grilles
d'accords cette semaine.

Comme je le disais à Jacques, je suis curieux des réponses sur ce fil
(merci pour celles déjà données). Comme l'apprentissage de Scheme est
un point qui cause régulièrement des difficultés, j'aimerais
comprendre où ça coince. Mon expérience personnelle est plutôt faite
d'un chemin tortueux pour comprendre le principe de la programmation
fonctionnelle, mais il est tout à fait possible que pour d'autres
cela soit plutôt compliqué au niveau de la syntaxe parenthésée et
préfixe.

Même si je n'imagine pas abandonner moi-même un jour la syntaxe «
normale », ne serait-ce que parce que tout le code Scheme de LilyPond
est écrit comme cela, je serai intéressé de voir si cela aide les
débutants.

Bin... si on se pose la question d'analyse d'une partition (raccourci
rapide !) : on la lit en entier, on empile et on dépile à la double
barre... Scheme est exactement ce qu'il faut ! Après... il faut - je
pense - déjà avoir un brin de connaissances pour, comme disait Jean,
ne pas avoir peur du mur.

Alors, peut-être un tuto écrit comme tu aurais aimé qu'on te
l'enseigne... D'expérience, ça marche souvent bien. J'ai fait ça (il y
a longtemps) avec les machins bizarres comme les codes BCH, les corps
de Gallois, et d'autres trucs étrangeoïdeaux et j'avais eu de bons
retours des étudiants.

Un tuto dans ce goût-là ?

E G Z A C T E M E N T ! ! !

Et en plus, c'est tout à fait comme j'aurais aimé qu'on me l'enseigne.

Merci pour cet énorme travail très clair et très pédagogique. Bravo.

Bernard.

Bonjour,

[...]

#(define (grow-in-up-direction beam)
   (let* ((Y-positions (ly:grob-property beam 'positions))
          (left-position (car Y-positions))
          (right-position (cdr Y-positions)))
     (cond
       ((< left-position right-position)
        RIGHT)
       ((> left-position right-position)
        LEFT)
       (else
        CENTER))))

\relative c' {
  \override Beam.grow-direction = #grow-in-up-direction
  c'16 d e f g f e d c g c g c e g c
}

pourrait s’écrire avec iScheme:

@define grow-in-up-direction (beam) {
  let* {
    Y-positions = ly:grob-property (beam, 'positions),
    left-position = car (Y-positions),
    right-position = cdr (Y-positions);

    cond {
      left-position < right-position:
        RIGHT;

      left-position > right-position:
        LEFT;

      else:
        CENTER;
    }
  }
}

J'avoue que je suis partagé.

D'un côté, c'est vrai que cette syntaxe infixée sera plus accessible à
ceux qui ont l'habitude de C, Java, PHP, JavaScript, Python, et beaucoup
d'autres langages. Je suppose d'ailleurs qu'elle doit permettre d'écrire
de façon procédurale, en masquant le fait que cela se traduira par un
« (progn ... ... ...) » implicite.

D'un autre côté, je suppose qu'il y aura toujours besoin dans certains cas
de revenir au vrai Scheme, ce qui veut dire apprendre deux langages au lieu
d'un (Scheme + iScheme) en plus de la syntaxe LilyPond.

Ajoutons à cela le fait qu'aux bugs que l'on peut trouver dans Scheme et
dans LilyPond il faudra tenir compte de bugs possibles dans la traduction
de iScheme en Scheme. Par exemple, dans le cas de if et cond imbriquées,
la traduction en Scheme pourrait ne pas imbriquer les instructions dans le
même ordre que ce que croit la personne qui code en iScheme. Pareil avec
les traitements de l'ordre des opérateurs tels que a * b + c * d, surtout
si a, b, c et d sont en fait des appels de fonctions.

Quoi qu'il en soit, je ne dis pas que c'est impossible ni que ce n'est
pas souhaitable. L'idée est même très séduisante.

\relative c' {
  \override Beam.grow-direction = @grow-in-up-direction
  c'16 d e f g f e d c g c g c e g c
}

Si la définition de grow-in-up-direction en iScheme se traduit par une
définition de même nom en Scheme, alors je pense qu'on pourrait tout aussi
bien continuer à écrire l'appel sous la forme #grow-in-up-direction au
lieu de @grow-in-up-direction. Cela dit, ça peut être une bonne idée
quand même d'introduire cette nouvelle syntaxe comme une sorte de rappel
de comment ça a été implémenté.

[...]

Cerise sur le gâteux, [...]

Mais non, il ne faut pas croire que l'on est gâteux quand on a du mal avec
le Scheme ! :slight_smile:

···

Le 08/06/2022 18:41, Jacques Menu a écrit :

--
Olivier Miakinen

Bonjour,

Presque exactement deux mois plus tard...

Le 08/06/2022 à 19:08, Christian LE BARS a écrit :

Bonjour Jacques.

J'approuve complètement ta démarche, bravo.

Je suis sur que Jean va réfléchir et donner une solution.

Ce qui a fini par arriver est que Jacques posait des questions à
Jean sur la manière dont on pouvait s'y prendre, et Jean a fini par
trouver que c'était tout aussi facile de donner un exemple que de
tout expliquer verbeusement, et puis Jean s'est pris au jeu, et
cela a donné ceci :

https://gitlab.com/jeanas/herescheme/

C'est un dépôt Git. Pour ceux qui ne sont pas à l'aise avec Git,
il suffit de télécharger le code dans un archive .zip avec le bouton
« Download » qui est dessiné par une flèche vers le bas, vers le haut
à droite de la page. Ou bien utiliser ce lien direct :

https://gitlab.com/jeanas/herescheme/-/archive/main/herescheme-main.zip

Plus qu'à dézipper, mettre ça quelque part sur votre ordinateur, et
\include le fichier "/.../herescheme/herescheme.ily".

Le README.md (que l'on peut lire sur la page du dépôt) contient une
explication de chaque élément de la syntaxe. C'est en anglais pour
l'instant. Lien direct :

https://gitlab.com/jeanas/herescheme/#usage

Le fichier herescheme-examples.ily contient un certain nombre d'exemples.

En voici un pour conclure, tiré de herescheme-examples.ily, qui correspond
à l'exemple que donnait Jacques dans son post de départ avec quelques ajouts :

\relative c' {
\shape &"[(0, 0), (0, 1.5), (0, 0.4), (0, 0)]" Slur
\override Beam.grow-direction =
&"function(beam) =>
let Y_positions = ly.grob_property(beam, |positions|) in
{
ly.message('Beam \\'positions are ~a', Y_positions);
let left_position = car(Y_positions) in
let right_position = cdr(Y_positions) in
if left_position < right_position then {
RIGHT
}
else if left_position > right_position then {
LEFT
}
else if left_position = right_position then {
CENTER
}
else ly.error('this can\\'t happen')
}"
c'16( d e f g f e d c g c g c e g c)
}

Je tiens à préciser que tout ceci est hautement expérimental. Les commentaires
sont fortement les bienvenus, en revanche je recommande d'attendre un peu
avant de l'utiliser sérieusement dans une partition.

Je n'ai à vrai dire aucune idée de l'utilité de ce projet ou du futur
qui peut l'attendre, je suis surtout curieux de voir. D'un côté, toute la
documentation LilyPond, tous les tutoriels Scheme, les manuels de Guile,
les snippets fournis sur les listes, et aussi l'affichage des valeurs dans
la console utilisent la syntaxe Scheme normale, donc il n'est pas question de
l'oublier. Ne faire qu'avec le Herescheme sans connaître la syntaxe Scheme
usuelle risque d'être compliqué. D'un autre côté, j'ai vu un certain
nombre de personnes qu'écrire du Scheme rebute à cause des nombreuses
parenthèses et de la syntaxe préfixe. Si cela peut aider ces personnes à
prendre en main le Scheme, pourquoi pas après tout. Deux précisions pour
finir. 1° On peut mélanger à volonté le Scheme et le Herescheme, et
donc choisir par exemple de n'écrire que les opérations mathématiques en
Herescheme. 2° Herescheme n'est absolument pas un nouveau langage de programmation,
simplement une syntaxe qui permet d'écrire du Scheme différemment. Il ne
faut pas s'attendre à retrouver Java, Python ou autre. En particulier,
il faudra comprendre à peu près les mêmes concepts d'écriture des programmes,
comme le style fonctionnel. Par contre, la syntaxe est plus habituelle pour
un œil qui n'est pas familier des langages de la famille Lisp.

Cordialement,
Jean