lambdaway
::
coder
3
|
list
|
login
|
load
|
|
{uncover https://mindsarentmagic.files.wordpress.com/2020/02/l_1-2.png 100 260 John Tromp diagram} _h1 coder _p Coder, autrement dit "concocter" inlassablement des suites d'algorithmes en utilisant la syntaxe d'un langage de programmation, est un art demandant pas mal de technique. A ce jour je n'ai jamais trouvé d'introduction au codage qui me satisfasse. Entre introductions à l'algorithmique devenant vite illisibles et présentations techniques des fonctionnalités de tel ou tel langage j'ai eu beaucoup de mal à progresser dans la découverte des concepts fondamentaux de la programmation. A comprendre {i vraiment} ce qu'est une variable, une fonction, une boucle, une récursion, une fermeture, une application partielle, une structure de données, liste, arbre, tableau et bien d'autres choses. Je suis resté trop souvent sur ma faim, sur trop de zones d'ombre qui restaient et m'empêchaient de comprendre au fond de quoi il s'agissait. _p C'est donc le but de ce qui suit, et je propose de découvrir un langage de programmation en le construisant sur de bases suffisemment simples pour réduire les zones d'ombre. Je ne suis "gourou" de rien du tout, mais je vous propose de partager mes curioisités. _p Let's go! _p Si je vous demande de {pre ({b remplacer} {u nom} {u prénom} {u qualité} {b par} James Bond agent-007 {b dans} Je m'appelle {u nom}, {u prénom} {u nom}, {u qualité} !) } _p notez bien les deux parenthèses analogues à deux mains en porte-voix signifiant une "commande" expresse, vous répondez sans peine {pre Je m'appelle Bond, James Bond, agent-007 ! } _p Vous venez de réaliser un remplacement des mots soulignés, des mots-tiroir, par des valeurs à l'intérieur d'une phrase contenant ces mots-tiroir. Cette phrase était incompréhensible en l'état et vous lui avez donné du sens. C'est ce que fait un ordinateur à longueur de temps. Tout ce qui va suivre n'est qu'une application de cette opération fondamentale. _p Notez bien la {b syntaxe} employée, les parenthèses englobantes signifiant une commande, les trois mots en gras, [{b remplace par dans}], et, moins visibles, les espaces séparant les trois mots-tiroir et les trois valeurs respectives. Nous pourrions bien sûr recommencer avec d'autres valeurs {pre ({b remplacer} nom prénom nombre {b par} Monica Bellucci 90/50/90 {b dans} Je m'appelle nom, prénom nom, qualité !) } _p et je vous laisse deviner le résultat. Rien n'empêche de modifier l'ordre des trois lignes, ainsi {pre ({b remplacer} nom prénom nombre {b dans} Je m'appelle nom, prénom nom, qualité ! {b par} Ward Cunningham theWikiMan) } _p et c'est d'ailleurs cet ordre que nous allons garder dans ce qui suit. Cela nous permet de distinguer deux parties, celle qui reste identique dans les trois appels et les valeurs variables par nature. En donnant un nom à la partie constante {pre ({b remplacer} hello {b par} {b remplace} nom prénom nombre {b dans} Je m'appelle nom, prénom nom, qualité ! {b par} ... ) } _p les trois points {b ...} représentant ce qui est omis, nous pouvons alors plus simplement écrire {pre (hello Ward Cunningham theWikiMan) } _p sachant que {b hello} sera immédiatement remplacé par sa valeur, la commande se développe ainsi {pre ({b remplacer} nom prénom nombre {b dans} Je m'appelle nom, prénom nom, qualité ! {b par} Ward Cunningham theWikiMan) } _p et on aboutit bien sûr au même résultat. Dans le langage des spécialistes du code {b hello} désigne le nom d'une {b fonction} et les mots-tiroir sont ses {b arguments}. Nous avons ainsi défini une fonction et nous l'avons {b appliquée} trois fois à des séquences de {b données} différentes. Définir une fonction nous permet ainsi de cacher la mécanique interne du remplacement, ce qui sera d'un grand secours quand nous aborderons des combinaisons plus complexes de remplacement. Nous procèderons par emboitements successifs ne laissant à la surface que l'essentiel. Construire ces emboitements est un art. _p Voici un second exemple, plus utile et très simple {pre ({b remplacer} a b {b dans} b a {b par} James Bond) -> Bond James } _p La phrase est réduite à peu de choses mais l'opération est évidente, on a interchangé les deux mots. En écrivant {pre ({b remplacer} swap {b par} {b remplacer} a b {b dans} b a {b par} ... ) } _p on obtiendra encore le résultat attendu et de façon plus concise {pre (swap James Bond) -> Bond James } _p Combinons à présent les fonctions {b hello} et {b swap} et suivons la cascade de remplacements jusqu'au résultat {pre (hello (swap James Bond) agent-007) -> (hello ({b remplacer} a b // swap est remplacé par sa valeur {b dans} b a {b par} James Bond) agent-007) -> (hello Bond James 007) // et appliquée -> {b remplacer} nom prénom nombre // hello est remplacé par sa valeur {b dans} Je m'appelle nom, prénom nom, qualité ! {b par} Bond James 007) -> Je m'appelle James, Bond James, agent-007 ! // et appliqué } _p la fonction {b swap} a tout d'abord interverti le prénom et le nom et les a transmis tels quels à la fonction {b hello} pour achever le remplacement. La succession de remplacements devient difficile à suivre mais les règles restent simples et systématiques. Assez simples et systématiques pour être confiées à un ordinateur. C'est exactement ce que peut faire mon ordinateur à condition que je lui parle dans un langage qu'il comprenne. Il y en a des centaines mais en voici un, {b lambdatalk}, qu'il comprend et qui a le mérite de suivre une syntaxe proche de tout ce qui vient d'être dit : {pre '{def hello {lambda {:a :b :c} Je m'appelle :b, :a :b, :c !}} -> {def hello {lambda {:a :b :c} Je m'appelle :b, :a :b, :c !}} '{hello James Bond agent-007} -> {hello James Bond agent-007} '{def swap {lambda {:a :b} :b :a}} -> {def swap {lambda {:a :b} :b :a}} '{swap James Bond} -> {swap James Bond} '{hello {swap James Bond} agent-007} -> {hello {swap James Bond} agent-007} } _p Capito ? En gros, à part les deux nouveaux mots, {b def} qui signifie {b définir} ce nom en remplacement de ce qui suit, et {b lambda}, qu'il suffit de traduire par {b remplacer}, tout le reste s'apprivoise facilement. D'accord, il y a des accolades partout et c'est un peu pénible mais les emboitements sont équilibrés, on en devine la logique et on distingue bien les noms de fonctions et les arguments signalés par deux points. Notez bien la grande simplicité de cette syntaxe, notamment dans la définition de la fonction {b swap}. On comprend surtout le systématisme de cette syntaxe, tout est écrit sous la forme {b '{function phrase}} où {b phrase} peut être un simple mot ou une autre forme {b '{fonction phrase}}. Semble-t'il à l'infini. _p A tel point qu'on a envie d'essayer des tas de choses. Par exemple pour appliquer des règles de style on devine que ce sera sous une forme du genre {b '{règle mots}} {prewrap '{b hello world} -> {b hello world} '{b {i {u hello world}}} -> {b {i {u hello world}}} et cetera... } _p ou pour faire un peu de math sous la forme {b '{opérateur nombres}} {prewrap '{+ 1 2} -> {+ 1 2} '{* 1 2 3 4 5 6} -> {* 1 2 3 4 5 6} ou pour les paresseux '{* {S.serie 1 6}} -> {* {S.serie 1 6}} et pour les matheux '{S.reduce long_mult {S.serie 1 100}} -> {S.reduce long_mult {S.serie 1 100}} } _p Mon copain matheux me parle de factorielle et je le laisse jouer {prewrap '{def fac {lambda {:n} {if {= :n 1} then 1 else {long_mult :n {fac {- :n 1}}}}}} -> {def fac {lambda {:n} {if {= :n 1} then 1 else {long_mult :n {fac {- :n 1}}}}}} '{fac 100} -> {fac 100} } _p Etonnant c'est le même résultat. Merci {b lambdatalk} ! _p Pour la {b syntaxe} du langage c'est vu, on a compris l'essentiel, elle est {b unique}. Il ne reste plus qu'à découvrir les fonctionnalités de ce langage déjà créées. Comprendre comment fonctionnent les opérateurs arithmétiques {b +, *, long_mult}, d'où viennent ces fonctions {b S.serie} et {b S.reduce}. C'est un passage obligé dans n'importe quel langage, mais ici on a compris une chose, on a les pieds fermement ancrés sur le sol, tout est affaire de remplacement de texte, et on pourra à tout moment en revenir à cette fondation. _p Vous pourriez continuer le voyage ici [[coding]]. Bonne route. _p {i alain marty | 2022/03/10} _p PS.: Par curiosité voici comment s'écriraient les fonctions {b swap} et {b fac} en javascript {pre var swap = function(a,b) '{ return b + ' ' + a } swap('James','Bond') -> Bond James var fac = function(n) '{ if (n===1) return 1 else return n*fac(n-1) } fac(6) -> 720 } _p Tous les langages se ressemblent, mais pas complètement. {style pre { box-shadow:0 0 8px #000; padding:10px; } }
lambdaway v.20211111