Utilisation de BIND ? | |
Bertrand | 6-Feb-2009/12:48:23+1:00 |
Je voudrais pouvoir transcrire ceci en Rebol :to top :outer :inner print [I'm in top.] print sentence [:outer is] :outer print sentence [:inner is] :inner bottom "x print [I'm in top again.] print sentence [:outer is] :outer print sentence [:inner is] :inner end to bottom :inner print [I'm in bottom.] print sentence [:outer is] :outer print sentence [:inner is] :inner end C'est du Logo, et ça donne ça : ? top "a "b I'm in top. :outer is a :inner is b I'm in bottom. :outer is a :inner is x I'm in top again. :outer is a :inner is b En Rebol : REBOL [] top: func [outer inner][ print "I'm in top." print [":outer is" outer] print [":inner is" inner] bottom 'x print "I'm in top again." print [":outer is" outer] print [":inner is" inner] ] bottom: func [inner][ print "I'm in bottom." print [":outer is" outer] print [":inner is" inner] ] top 'a 'b halt donne ça : ** Script Error: outer has no value ** Where: bottom ** Near: outer sauf si je fais comme ceci : REBOL [] top: func [outer inner][ print "I'm in top." print [":outer is" outer] print [":inner is" inner] ; bottom: func [inner][ print "I'm in bottom." print [":outer is" outer] print [":inner is" inner] ] bottom 'x ; print "I'm in top again." print [":outer is" outer] print [":inner is" inner] ] top 'a 'b halt ... et ça marche. Mais je voudrais savoir s'il est possible d'avoir deux procédures indépendantes (comme en Logo et comme dans le premier exemple en Rebol) qui communiquent (en quelque sorte) entre elles. Peut-être avec bind ? | |
Bertrand | 6-Feb-2009/17:40:31+1:00 |
Bien sûr je pourrais tout réécrire bêtement comme ça :top: func [outer inner][ print "I'm in top." print [":outer is" outer] print [":inner is" inner] bottom 'x outer print "I'm in top again." print [":outer is" outer] print [":inner is" inner] ] bottom: func [inner outer][ print "I'm in bottom." print [":outer is" outer] print [":inner is" inner] ] mais mon intention était d'examiner comment Rebol gère-t-il les variables (locales) des procédures (ou fonctions). En Logo, par exemple, si une procédure fait référence à une variable qui n'appartient pas à cette même procédure, Logo recherche une variable du même nom dans la superprocédure de cette procédure (c.à.d. dans la procédure ou fonction appelante) et ainsi de suite. Au cas où la procédure possède une variable de même nom qu'une variable appartenant à sa superprocédure, cette dernière est alors "cachée" tant que la (sous)procédure (fonction appelée) est active (on le voit avec la variable 'inner'). Je voulais donc savoir si Rebol faisait la même distinction que Logo. Autrement dit, est-ce qu'une fonction Rebol peut partager ses variables locales avec une autre fonction (qu'elle appelle), autrement qu'en l'imbriquant dans son propre espace ? | |
Didec | 6-Feb-2009/21:10:46+1:00 |
Y'a peut-être un truc de guru pour arriver à ce que tu veux. Mais disons que ce n'est pas une caractéristique de base du langage comme ça l'est en Logo. Avec les nouvelles fonctions que va introduire R3 ce sera plus facile, mais peut-être pas encore équivalent. | |
Bertrand | 6-Feb-2009/21:40:03+1:00 |
OK, ce n'est pas un problème. C'était juste pour savoir ce que je peux faire avec Rebol et surtout comment le faire, autrement qu'avec les habitudes que j'ai prises ailleurs ... je n'aime pas trop les habitudes Par ailleurs en Rebol, on peut imbriquer des fonctions ou utiliser facilement des fonctions anonymes, c'est assez difficile en Logo, à part peut-être avec ELICA qui est un logo à part. Une fois, quelqu'un, sans doute un utilisateur ou un fan de Python, reprochait à Rebol, entre autres, l'absence d'arguments "avec étiquettes" (arguments optionnels que l'on peut nommer dans le désordre lors de l'appel d'une fonction). En moins d'une demi-heure j'ai trouvé que c'était possible en Rebol, en reprenant l'exemple de Python : REBOL[] ;; arguments optionnels avec étiquettes -> raffinements oiseau: func [ /voltage v /etat e /action a ][ if not voltage [v: 100] if not etat [e: "allumé"] if not action [a: "danser la java"] print ["Ce perroquet ne pourra pas" a] print ["si vous le branchez sur" v "volts !"] print ["L'auteur de ceci est complètement" e] ] oiseau print [] oiseau/etat/voltage/action "givré" 250 "vous approuver" print [] oiseau/action/voltage/etat "ne pas péter" 3000 "azymuthé" print [] oiseau/etat "cinglé" print [] oiseau/action "parler" halt Python: def oiseau(voltage=100, etat='allumé', action='danser la java'): print "Ce perroquet ne pourra pas", action print "si vous le branchez sur", voltage "volts !" print "L'auteur de ceci est complètement", etat C'est peut-être moins "élégant" en Rebol mais ça fonctionne. On doit pouvoir trouver mieux et plus concis peut-être ... J'ai essayé avec NewLISP aussi et ce n'est pas trop compliqué à réaliser. Avec des langages de ce type (Rebol, NewLISP et autres langages approchant) on arrive à faire pas mal de choses grâce à leur souplesse et leur conception. Il est plus difficile de reproduire en Python (ou en Basic, ou autre langage "impératif") des caractéristiques de Rebol (de Logo ou de divers Lisp) que l'inverse. | |
Bertrand | 6-Feb-2009/21:59:27+1:00 |
J'ai même trouver plus court pour cette histoire d'oiseau :oiseau: func [ /voltage v /etat e /action a ][ print ["Ce perroquet ne pourra pas" any [a "danser la java"]] print ["si vous le branchez sur" any [v 100] "volts !"] print ["L'auteur de ceci est complètement" any [e "allumé"]] ] Comme quoi, avec Rebol, tout est possible ... | |
Bertrand | 7-Feb-2009/16:03:46+1:00 |
Pour ce qui est du premier exemple, celui que j'ai voulu adapter de Logo, je viens de comprendre le pourquoi du comment. La portée des variables (variable scope) est "dynamique" en Logo alors qu'elle est "statique" ou "lexicale" en Rebol (comme en Scheme). Donc les variables locales d'une fonction sont perdues dès qu'elles sortent de cette fonction, ou plutôt elles sont ignorées à l'extérieur de cette fonction. NewLisp, par exemple a un portage dynamique contrairement à Scheme ou à Rebol. C'est un peu du charabia de spécialiste tout ça, mais il semble que ça a son importance, car le portage "lexical" (ou statique) permet de prévoir plus facilement le comportement des variables, en fonction de l'utilisation des fonctions, d'après ce que j'ai lu (et peut-être compris) sur le sujet. Il permet donc de contrôler et de prévoir quelles valeurs doit recevoir une variable (très utile pour les gros et longs programmes sûrement). Rebol est plus sûr que NewLISP à ce niveau. http://fr.wikipedia.org/wiki/Port%C3%A9e_(informatique) Ben, j'en apprends des choses depuis que j'utilise Rebol ! Désolé de vous ennuyer avec tout ça | |
guest2 | 9-Feb-2009/13:26:08+1:00 |
A noter qu'il y a des manières un peu plus Reboliennes de faire, que d'utiliser des raffinements. La fonction pourrait utiliser un block de paramètres plutôt que des raffinements. Ca rend l'utilisation de la fonction un peu plus lisible. oiseau: func [ input /local voltage etat action ][ do bind input 'local ;(mappage des variables du block vers les variables locales de la fonction) print ["Ce perroquet ne pourra pas" any [action "danser la java"]] print ["si vous le branchez sur" any [voltage 100] "volts !"] print ["L'auteur de ceci est complètement" any [etat "allumé"]] ] oiseau [] oiseau [etat: "givré" voltage: 250 action: "vous approuver"] oiseau [action: "parler"] ;On peut aussi créer un dialecte avec Parse, ça pourrait ressembler à ceci: dialecte: [ 'oiseau (voltage: etat: action: none) any [ 'voltage set voltage skip | 'etat set etat skip | 'action set action skip ] ( print ["Ce perroquet ne pourra pas" any [action "danser la java"]] print ["si vous le branchez sur" any [voltage 100] "volts !"] print ["L'auteur de ceci est complètement" any [etat "allumé"]] ) ] parse [ oiseau oiseau etat "givré" voltage 250 action "vous approuver" oiseau action "ne pas péter" voltage 3000 etat "azymuthé" oiseau etat "cinglé" oiseau action "parler" ][some dialecte] Il y'a mieux que les les variables nommées, Rebol reconnait les types tout seul comme un grand, donc le voltage peut être simplement détecté par la présence d'un entier ou non. Une version un peu plus complexe et permissive pourrait être ceci: dialecte: [ 'oiseau (voltage: etat: action: none) any [ '. break | set voltage integer! | 'est to string! set etat string! | 'pas to string! set action string! | skip ] ( print ["Ce perroquet ne pourra pas" any [action "danser la java"]] print ["si vous le branchez sur" any [voltage 100] "volts !"] print ["L'auteur de ceci est complètement" any [etat "allumé"]] print "===" ) | skip ] parse [ un oiseau . cet oiseau est vraiment "givré" à 250 et il peut pas "vous approuver" . cet oiseau peut pas "ne pas péter" à 3000 car il est "azymuthé" . un oiseau qui est completement "cinglé" . un oiseau qui veut pas "parler" . ][some dialecte] Il ya d'autres façons de créer des dialectes. C'est parfois le problème quand on débute avec Rebol. Trop de façons de faire, donc on se sent un peu paralysé. La seule limite c'est notre imagination. | |
Bertrand | 10-Feb-2009/11:00:19+1:00 |
Super! La première solution est en effet moins déroutante pour un débutant ou pour quelqu'un qui vient d'un autre "langage". Et puis ça ressemble à la définition que j'ai faite en NewLISP (define-macro (oiseau) (local (voltage etat action) (bind (args) true) (println "Ce perroquet ne pourra pas " (or action "danser la java")) (println "si vous le branchez sur " (or voltage 1000) " volts !") (println "L'auteur de ceci est complètement " (or etat "allumé"))) (println)) Les autres semblent plus spécifiques à Rebol et, en même temps plus difficiles à comprendre... Cependant elles offrent des solutions plus qu' "élégantes" (selon le terme consacré) et ouvrent des horizons inexplorés (dans les autres langages, plus "classiques"). En tout cas, merci pour ce cours, qui me fait m'accrocher encore un peu à Rebol, malgré d'autres tentations et en dépit de l'incertitude quant à l'évolution future (proche?) de Rebol, via Rebol3. P.S.: je bute un peu sur le some de [some dialecte] ? Je n'ai pas trouvé de doc là-dessus. | |
Bertrand | 10-Feb-2009/11:14:09+1:00 |
re-P.S.: j'ai trouvé la signification de some dans le Rebol-coreguide au chapitre "Parsing". Maintenant je comprends mieux comment on peut créer un dialecte en Rebol ... merci | |
Login required to Post. |