Rebol Documentation Project

Aller au contenu | Aller au menu | Aller à la recherche

mercredi 21 avril 2010

Meeting REBOL - La Cantine - Paris 24 Avril

French REBOLers are invited to the Welcome REBOL! conference at La Cantine, a new-generation collaborative Internet technology workspace, in Paris, France on the 24th of April, 2010 at 14:00.

The conference will include workshops and other events where the content will be provided in a "no spectators, all participants" style. That is, bring your own presentation or ideas for discussion.

Potential topics include:

  • Presentation of projects and vision of each (round table).
  • Direction of REBOL now and in the future.
  • Ideas for improving REBOL communication and business. Relationship between coders-developers, project leaders, businesses and self-entrepreneurs, communicators (SEO, business, web marketing).
  • Specific details about projects from developers.
  • Ideas for joint projects.


Space is limited, so please sign up now!


For more information see: REBOL France and the RebelBB Forum.



Les Reboleurs français
sont invités à une conférence REBOL à La Cantine , un espace de travail collaboratif Internet, à Paris, France le 24 avril 2010 à 14:00.

La conférence comprendra des ateliers et autres échanges sur le mode "pas de spectateurs, tous participants".
Autrement dit, il faut apporter votre propre présentation et des idées pour la discussion.

Les thèmes possibles sont :

  • Présentation des projets et la vision de chacun (table ronde ).
  • Orientation de REBOL maintenant et dans l'avenir.
  • Idées pour améliorer la communication REBOL et les entreprises.
  • Relations entre les codeurs-développeurs, chefs de projet, les entreprises et les auto-entrepreneurs, des communicateurs (commerce, marketing web).
  • Les détails spécifiques sur les projets présentés.
  • Idées de projets fédérateurs.

L'espace est limité, donc s'il vous plaît Inscrivez-vous!

Pour plus d'informations, voir: REBOL France et le Forum RebelBB.

mercredi 23 décembre 2009

REBOL Brainwasher

Salut,

Connaissez-vous Jerry Tsai ?

Jerry intervient souvent sur Altme, et dans divers posts sur le Net.

Son histoire est assez symbolique de REBOL : il programmait plutôt en JAVA. Un jour, son patron lui demande de faire un développement en urgence. Jerry réalise alors qu'en Java, il en a pour plusieurs jours. Se rappelant REBOL, il tente de réaliser la solution en REBOL ... et çà marche. Depuis, il fait partie des "switchers" qui comme vous (peut-être) et moi, ont réalisés un jour que REBOL était génial !

Jerry a publié son témoignage ici

Jerry est aussi l'auteur d'une présentation PowerPoint qui décoiffe !

A voir absolument : la présentation Rebol Brainwasher.pptx

===Philippe

Donate - Faire un Don

Reboleurs ou curieux !

Vous pouvez nous aider à maintenir ce site en faisant un don ! Cliquez sur le bouton ci-dessous qui vous redirigera vers le site web Paypal. 

Merci de votre aide.

-----------------------------------------------------

Rebolers or visitors !

You can help us maintain this site by making a donation! Click the button below which will redirect you to the PayPal website.

Thanks for your help. 

mercredi 09 décembre 2009

Programmer's Notepad


L'une des questions qui revient lorsqu'on écoute les nouveaux sur REBOL, c'est : avec quel outil codez-vous ?

Bon, OK, sur cette question, la crédibilité du langage perd des points. 

En effet, il n'existe pas de suite de développement REBOL, qui intégrerait ce que d'autres font : 

  • Un environnement de travail intégré (EDI) permettant de gérer tout le cycle de développement depuis la conception jusqu'au packaging
  • Un éditeur de projet, et un générateur d'applications
  • Un assistant conceptuel permettant de modéliser/analyser, créer des diagrammes UML (MPD, MLD)
  • La gestion des versions en environnement multi-utilisateur
  • Un éditeur de fenêtre utilisant des templates / widgets pré-définis
  • Un compilateur et un débuggeur (suivi des bugs)
  • La possibilité d'accèder à la documentation du langage et d'automatiser la création de la documentation
  • Et bien sûr la coloration syntaxique, l'autocompletion, les détections de limite de blocs, l'appel de programmes externes, etc...

La plupart du temps, les développeurs utilisent des outils comme Notepad++, Crimson Editor, EditPlus. 

Il est aussi possible de paramétrer Eclipse comme je l'ai montré dans un autre post. Mais l'approche d'Eclipse est lourde, quoique riche.

En fait, il existe des briques de ces fonctionnalités.
- Carl avait réalisé en R2, en 2003 un script (layout-1.8.r), qui permet de créer des interfaces en choisisant des widgets


- Christophe Coussement (RebolTof) avait écrit un script Run.r permettant de générer automatiquement des tests cases et de la documentation.

Le choix est en fait assez simple : soit on utilise un IDE existant dans lequel vient s'ajuster notre langage préféré, soit on crée un IDE en REBOL, et là : problèmes de leadership, problème de disponibilité des reboleurs, de dispersion des compétences, des choix techniques, etc..

Depuis peu, il existe cependant un nouveau dérivé de Scintilla (le moteur d'édition Open Source), qui s'appelle Programmer's Notepad.

Il est possible de télécharger PN sur le site : http://www.pnotepad.org/

Ce software prend par défaut le REBOL dans sa liste de langages embarqués, qui est assez vaste.

L'interface est assez classique, mais on a enfin l'autocompletion du langage (à la façon Eclipse), la gestion de projets (avec des dossiers virtuels qui rassemblent les fichiers, dossiers éparpillés ).

Il gère bien sûr l'association avec un exécutable Rebol et la gestion de l'output, mais pas la gestion de versions concurrentes, ni la modélisation, ni l'auto-documentation. Il est cependant possible de le faire évoluer avec des scripts (écrits en Python). J'imagine qu'il doit être possible de rajouter des fonctionnalités.

Bien sûr, la création d'interfaces visuelles n'est pas d'actualité, mais bon, une initiative intéressante dans la (parfois) monotonie rebolienne !

La gestion de l'autocompletion :

Il est possible de plier/déplier des blocs de codes, ce qui est parfois bien pratique pour certains élèments (boucles, blocs, ..)

La fenêtre de gestion des projets :

La fenêtre des scripts (add-on spécifiques) :

Une partie de la fenêtre des options

Voilà, à découvrir donc  !

===Philippe

lundi 05 janvier 2009

REBOL dans le magazine Programmez! 115

Frédéric Mazué, du magazine Programmez! réalise un article sur REBOL (p.73 du n°115), présentant quelques aspects du langage : 

l'accès aux fichiers, les séries, les raffinements, les appels au système. 

http://www.programmez.com/magazine_articles.php?titre=A-la-decouverte-de-Rebol&id_article=1168&magazine=115

Le début d'une série d'articles, qui nous rappelle ceux réalisés dans feu le magazine LOGIN ?

Voilà pour bien démarrer cette nouvelle année !

===Philippe


Mise à jour de Dotclear et Bonne Année 2009

Le moteur du blog portant le Rebol Documentation Project a été mis à jour peu avant Noël !

Par ailleurs, certains liens cassés depuis le portage de SPIP à Dotclear ont été réparés. 

D'autres le seront progressivement. 

Bonne Année 2009, plein de REBOL 3 bien sûr !

===Philippe 

vendredi 06 avril 2007

Le concept des Set-Functions

Le concept des Set-Functions

Carl Sassenrath, CTO REBOL Technologies 2-May-2006 21:02 GMT Article #0019

Vous savez ce qu'est un set-word :

word: 10

C'est la syntaxe utilisée par REBOL pour définir la valeur d'un mot.

Une set-function est une fonction qui est appelée lorsque cette action de définition se produit. Une set-function dans l'exemple précédent aurait permis de controler le range, le datatype, de conserver la trace d'autres détails.

Le concept d'une set-function n'est pas nouveau. En fait, c'est l'un des éléments essentiels de l'un des aïeuls de REBOL : le langage Self (voir Self : The Power of Simplicity, l'un de mes livres préférés.)

Il y a longtemps, dans les premiers jours de création de Self, alors que j'étais chez Apple, je trainais avec David Ungar (concepteur de Self, à Standford actuellement) et je parlais de ce langage de communication. Je trouvais intéressant que David veuille retirer un état de Self en supprimant l'affectation. (L'affectation est l'une des cause d'ennuis classique dans les langages purement fonctionnels.) Il accomplissait toujours cela en utilisant des fonctions qui à la fois définissaient et récupéraient des valeurs au sein d'un contexte (objet).

L'idée me tentait toujours, mais je sentais que ce n'était pas exactement réalisable. L'état est un macro-composant par nature (je n'ai pas dit "composant" ici, parce que je ne veux pas entrer dans une discussion san fin). La suppression de l'état est une recherche mathématique, mais ce n'est pas nécessairement pratique. Il y a de nombreux aspects utiles à un état. Un journal est très utile, mais mathématiquement sans intérêt fonctionnel.

Lorsque vint le temps de reprendre cette approche dans REBOL (il y plus de 10 ans), j'ai décidé de conserver cela pratique. Cependant, en secret, j'ai toujours voulu conserver la méthode set-function, car elle a beaucoup de valeur. Une set-function peut précisément contrôler comment un mot est défini et ce qu'il définit.

Je devrais mentionner, cependant, qu'il n'est pas facile d'ajouter les set-functions. Si c'était vraiment facile, nous les aurions ajoutées. Le probléme réside dans le fait que les set-functions ajoute une nouvelle branche à l'arbre de la sémantique du langage REBOL.

Par exemple, comment sont définies les set-fonctions et comment sont-elles réflectives ?

Vous pouvez faire une sorte de set-function avec le code qui suit :

obj : make object ! [ value : 0 ; internal set-value : func [new] [value : new] ]

Et vous écririez :

obj/set-value 10

Mais ce que vous voulez réellement écrire, c'est :

obj/value : 10

à l'intérieur de la fonction pour définir cette valeur.

Mais là, la question se pose, comment faire référence à la set-function elle-même ?

OK, voilà quelque chose à méditer. Je ne suis pas sûr qu'il y ait une bonne réponse, ou aussi si nous avons besoin d'une. J'avais déjà parlé de cela autrefois, et sans suggérer que ceci soit ajouté à REBOL 3.0. (voir l'article précédent sur les extensions du langage.)

Je suppose que je suis en train de vous faire réfléchir à cela. Merci de me signaler vos commentaires.

(Traduction : Philippe Le Goff)

Les bonnes astuces du langage ne sont juste que cela.

Les bonnes astuces du langage ne sont juste que cela.

Carl Sassenrath, CTO REBOL Technologies 2-May-2006 20:28 GMT Article #0018

REBOL est un langage pour les personnes créatives. A cause de cela, il existe une richesse infinie d'astuces pour le langage et de possibilités que chacun peut inventer — spécialement dans un langage flexible comme REBOL. Certaines de ces astuces sont utiles, beaucoup ne le sont pas.

Malheureusement, après avoir inventé une amélioration au langage, la première chose que beaucoup de développeurs veulent est de la voir ajouter au langage. Mais est-ce vraiment judicieux ? est-ce que le langage est juste un "civet" de petites caractéristiques ?

Pas vraiment. Un langage doit être plus grand que cela. C'est une manière de penser - un moyen de faire correspondre des actions et de la logique, pas une collection de petits morceaux collés ensemble.

Maitenant, il y a un bon nombre de logiques très banales, comme un boucle while, et il y a encore plus de logiques rares. Je suis certain que vous avez vos préférées. Le probléme est de décider quand une logique, une action, ou une fonction devrait être une part officielle du langage ? Ce processus doit être pris en compte sérieusement. Il y a des douzaines de langages "surgonflés" qui possèdent des milliers de fonctions et de caractéristiques, qui sont très peu utilisées.

C'est une affaire pratique, pas une affaire académique ou de conception. Ce n'est pas "peut-on ajouter une caractéristique ?", c'est "doit-on ajouter cette caractéristique ?". Si la caractéristique est utilisée par un programmeur une fois dans l'année, est-ce que cela a de la valeur de l'ajouter ? Si la caractéristique est vague à comprendre ou difficile à utiliser, doit-elle faire partie de nos standards ?

J'ai dit "Non". Laissons cela en dehors ou faisons-en un package particulier ou un module de composant additionnel. Je préfére que REBOL demeure compact et léger. (Et, je serais le premier à admettre que RT est souvent coupable de ne pas respecter cette régle... des choses seront supprimées dans REBOL 3.0.)

Bien sûr, que rien ne vous arrête d'utiliser votre propre package ou extension du langage. Et si vous trouvez des douzaines de programmeurs qui utilisent cette caractéristique, alors il sera probablement temps de songer à l'ajouter. Un bon exemple est la package Include de Ladislav. Beaucoup de personnes l'utilise, et encore plus l'utiliseraient si il était inclus dans REBOL (donc, oui, il le sera.)

S'il vous plaît, ne m'en voulez pas. Je n'ai pas dit d'arrêter d'inventer de nouvelles extensions au langage, et je n'ai pas dit d'arrêter de suggérer leur ajout dans REBOL. Ce que je dis, c'est de mesurer les mérites de chaque extension.

Trions les codes les plus utilisés en les publiant dans la communauté REBOL et en regardant s'ils deviennent populaires. Puis, si vous avez une foule de gens qui les utilisent, venez cogner à ma porte et mettez-moi au courant. Je garantis que je vous écouterais avec interêt.

(Traduction : Philippe Le Goff)

Usage de ! et != dans REBOL ?

Usage de ! et != dans REBOL ?

Carl Sassenrath, CTO REBOL Technologies 2-May-2006 18:51 GMT Article #0017

Il existe de nombreuses et subtiles différences entre REBOL et d'autres langages. Certaines de ces différences sont importantes et d'autres non.

Dans leur grande majorité, les différences de REBOL ne sont issues d'un caprice. Par exemple, REBOL utilise les caractères "[]" pour les blocs, pour une raison et utilise le point-virgule " ;" des commentaires pour la même raison : ce sont des signes très faciles à saisir sur des claviers US (pour les claviers non-US, eh bien, désolé), et ils s'impriment correctement (les blocs ressemblent à des blocs avec []).

Mais une différence que les nouveaux utilisateurs n'apprécient pas est le symbole REBOL "<>", qui teste une inégalité. Ces caractères ont été choisis car < et > sont utilisés pour des comparaisons, de sorte que les mettre ensemble pour l'inégalité était logique.

Cependant, le langage C a établi la convention du " !=". C'est une combinaison du non " !" et du "=" (qui ne signifie pas réellement l'égalité en C, il indique une assignation, mais nous allons ignorer ce petit fait).

Actuellement en REBOL, " !" ou " !=" ne sont pas définis. Mais, nous essayons d'être plus amicaux dans REBOL 3.0, même si c'est juste un peu. Ainsi la question est donc : est-ce que nous devons faire de ceci une norme ? (pour la petite histoire, Python a été aussi modifié pour permettre ce changement entre <> et !=.)

Il est vraiment très facile de faire ce changement, et s'il rend quelques centaines de programmeurs plus heureux, bien, peut-être cela vaut-il le coup. Ce n'est pas la première fois que nous pensons à cette idée, mais dans REBOL 3,0 nous faisons des changements à grande échelle, de sorte que c'est une bonne idée de rediscuter quelques uns de ces petites problèmes.

Donc, faites moi remonter vos commentaires là-dessus.

(Traduction : Philippe Le Goff)

Variables typées d'objet

Variables typées d'objet.

Carl Sassenrath, CTO REBOL Technologies 2-May-2006 16:47 GMT Article #0016

REBOL 3.0 a la capacité de garder des informations sur les types des champs (ou variables) d'un objet. Par exemple, si votre objet a un champ nom, et que vous voulez que ce nom soit du type string !, vous pouvez spécifier cela.

L'information indiquant le type pour les champs est manipulée dans la nouvelle structure de contexte de REBOL 3. C'est une valeur composite, de sorte que vous pouvez spécifier plusieurs types, comme c'est faisable avec les arguments des fonctions (en fait, on utilise le même mécanisme que les fonctions, ce qui réduit la taille de REBOL.)

La question est : quel est le meilleur moyen de spécifier les types de données des champs d'un objet ? C'est une question quelque peu difficile parce qu'en REBOL, les définitions d'un objet servent également à initialiser les champs de l'objet.

make object ! [ name : "Bob" age : 27 city : "Mendocino" ]

Le bloc de spécification de l'objet est un bloc REBOL valide qui est évalué, et les valeurs initiales sont définies.

Une solution pourrait être d'introduire un bloc d'attributs similaire aux attributs de fonctions. Si la première valeur dans la définition de l'objet est un bloc, elle prend une signification particulière :

make object ! [ [name : city : [string !] age : [integer !]] name : "Bob" age : 27 city : "Mendocino" ]

Bien sûr, nous allons aussi réfléchir sur les autres attributs que nous pourrions introduire pour les objets dans le futur, car nous ne voudrions pas ajouter cette fonctionnalité et nous apercevoir plus tard que nous ne pouvons plus ajouter d'autres attributs (comme la possibilité de fixer un champ, l'observation d'un changement, etc.)

Envoyez vos remarques. Merci.

(Traduction : Philippe Le Goff)

Réferencer une variable de série dans FOREACH

Réferencer une variable de série dans FOREACH

Carl Sassenrath, CTO REBOL Technologies 2-May-2006 16:33 GMT Article #0015

Quelque chose que j'ai toujours voulu avec foreach : la possibilité d'accèder à la série, non seulement à ses valeurs. En d'autres mots, une sorte de mélange entre forall et foreach.

Une manière de réaliser cela serait de permettre à un mot du bloc de foreach d'inclure une sorte de notation indiquant que ce mot est censé se rapporter à la série, pas à une valeur de la série. Par exemple :

foreach [name count :] user-data [ change count length ? name ]

Cet exemple montre la puissance de cette méthode. Ici la variable count fait référence à la série, positionnée à cet index, de sorte que l'exemple modifie à cette position le bloc de la série courante. La notation "set-word" est cohérente avec celle utilisée dans le dialecte parse pour des raisons similaires.

Vous pouvez aussi l'utiliser comme un mot qui va vous donner la position de l'index sans avoir besoin d'incrémenter à part une variable dans la boucle foreach.

(Traduction : Philippe Le Goff)

Hash ! ou non

Hash ! ou non

Carl Sassenrath, CTO REBOL Technologies 2-May-2006 16:23 GMT Article #0014

Ok, j'ai entendu beaucoup de plaintes de personnes au sujet du datatype hash!, depuis qu'il a été ajouté. Je pense que le probléme est que ce type de données est très mal compris. C'est plus qu'une méthode pour faire des associations car il fournit une méthode séquentielle d'accès à des blocs cohérente avec le reste de REBOL. J'avais toujours pensé que c'était plus performant que les tableaux associatifs ou les dictionnaitres trouvés dans d'autres langages comme Python ou Perl. Mais, peut-être ai-je tort.

Maitenant, c'est l'heure pour votre décision. Si vous ne voulez pas du datatype hash, débarassons-nous de lui. Au lieu de cela, nous pouvons fournir divers genres d'associations simples "une à une" et trouver une manière facile de les mettre en série pour les entrées et sorties.

Vos commentaires seront appréciés.

(Traduction : Philippe Le Goff)

Assouplissement des alias pour les équivalences symboliques

Assouplissement des alias pour les équivalences symboliques

Carl Sassenrath, CTO REBOL Technologies 28-Apr-2006 23:33 GMT Article #0013

En REBOL 3.0, nous allons assouplir les conditions relatives aux alias.

Rappel : un alias est un équivalent symbolique pour un mot. Normalement, les alias sont utilisés pour mettre en majuscules ou minuscules l'équivalent des mots (ce qui est fait en interne et automatiquement dans REBOL).

Par exemple, vous pouvez écrire :

if time > now [...]

ou

IF Time > now [...]

Ces expressions sont identiques. La comparaison renvoie "true" :

'if = 'IF true

Dans les versions précédentes, si vous vouliez définir un alias pour un mot, vous deviez y faire attention. Le mot ne devait pas être déjà utilisé (de n'importe quelle manière). Vous pouviez créer l'alias d'un mot avec une ligne comme celle-ci :

alias 'if "fi"

Après cela, fi signifie la même chose que if. L'expression suivante est vraie :

'if = 'fi true

et vous pouvez écrire :

fi time > now [...]

Les débutants doivent noter que l'usage d'alias n'est pas la même chose que le partage de la la valeur des mots. L'exemple ci-dessus n'est pas la même chose que :

fi : :if

Voir le manuel pour plus d'information sur cela.

Comme les experts le savent, les équivalences avec des alias sont rarement nécessaires, mais c'est important dans certains cas, quand les mots sont utilisés symboliquement, comme avec :

'if = first [fi]

ou dans un path :

path/fi

REBOL 2.0 possède des restrictions sur la façon dont les alias doivent être définis. Un alias peut être refusé si le mot a déjà été utilisé.

En REBOL 3.0, nous allons assouplir ces contraintes et vous pourrez écrire :

alias 'if 'fi

même si fi est déjà apparu auparavant.

Notez, cependant, que vous devrez encore utiliser les alias avec beaucoup d'attention. Si vous définissez des contextes (modules,objects, fonctions) qui utilisent le mot avant que ne soit défini son alias, eh bien... alors, vous risquez d'avoir quelques problèmes parce que vous aurez changé quelque chose d'extrémement fondamental : le sens le plus basique du symbole.

Ce changement dans REBOL 3.0 n'est pas définitif. Nous allons observer comme cela fonctionne, et prévoir de revenir à la méthode de REBOL 2.0. Mais, je voulais pour le signaler. Faisons un essai.

(Traduction : Philippe Le Goff)

Les fonctions "closure"

Closure Functions

Carl Sassenrath, CTO REBOL Technologies 24-Apr-2006 16:32 GMT Article #0012

NdT : j'ai préféré laissé le terme anglais pour éviter les méprises.

Les fonctions closure seront fournies en standard dans REBOL 3.0.

Le concept des fonctions closure n'est pas neuf (au moins 30 ans d'âge), et peut être trouvé dans la plupart des types de langages fonctionnels. Une closure est un type particulier, ou une caractéristique, d'une fonction qui conserve "vivant" l'environnement local (arguments et variables locales) d'une fonction, même après que cette fonction ait terminé son exécution.

Avantages : l'environnement de la fonction (mots et données) reste valide après que la fonction ait retournée ses valeurs. (ce qui n'est pas vrai avec les fonctions normales). C'est pratique si vous voulez retourner des mots ou d'autres données de la fonction, et que vous voulez encore accéder à la valeur des mots.

Inconvénients : leur évaluation est plus lente que les fonctions normales car elles sont allouées et liées à l'exécution. Aussi, les fonctions closures requièrent souvent plus de mémoire (et provoquent plus de recyclage), selon l'usage que vous en faites et la façon dont vous stockez leurs résultats.

En REBOL 3.0, les fonctions closures seront implémentées avec le datatype closure ! et une nouvelle fonction mezzanine appelée closure. Voici un exemple qui définit une nouvelle fonction closure appelée has-name :

hash-name: closure [name [string!] /local hash] [ hash: checksum/secure name return [name hash] ; note: renvoie des mots, pas aux valeurs ]

Lorsqu'une fonction closure est définie, un objet REBOL est créé et le corps de la fonction est lié à cet objet. Lorsque la fonction est évaluée, l'objet de la fonction d'origine est cloné et le corps de la fonction copié complètement et relié à cet objet nouvellement cloné.

Vous appelez les fonctions closure de la même manière que vous le faites pour n'importe quelle fonction :

result: hash-name "Bob" print second result

Vous pouvez tester une fonction closure avec :

if closure? :hash-name [print "It is true"]

et, cette expression est aussi vraie :

 if any-function? :hash-name [print "It is true"]

Pour en savoir plus à propos du concept des fonctions closures, voir l'item "Function Closure" sur le site Wikipedia, et également les exemples et méthodes de fonctions closures REBOL fournies par Ladislav Mecir (qui travaille sur les versions courantes de REBOL) dans ses tutoriels et codes ("Bind a Function Yourself").

(Traduction : Philippe Le Goff)

Voulez vous un pointeur pour déboguer ?

Carl Sassenrath, CTO REBOL Technologies 12-Apr-2006 16:46 GMT Article #0011

Cet article concerne d'entre vous qui veulent plus de contrôle pour déboguer, pour créer des IDEs, etc. Voulez vous un pointeur de déboguage dans le mécanisme de gestion des erreurs ?

De quoi s'agit-il ? En REBOL 2, lorsqu'une erreur se produit, la pile retourne immédiatement au précédent état pré-déterminé de l'interpréteur, et tous les états entre l'erreur et l'endroit de la capture de l'erreur ("catch") sont effacés. Du fait de cela, il n'y a pas de moyens d'examiner les arguments de la fonction courante, de remonter la liste (backtrace) de fonctions, etc..

Avec REBOL 3, nous pouvons ajouter un pointeur (debug hook) de déboguage qui vous permettra de récupérer l'erreur interne, retardant le « throw » sur la pile, et permettant à du code spécialisé d'accéder à la pile de l'interpréteur.

(Notez que ceci n'a rien d'extraordinaire pour la plupart des interpréteurs. En fait, ce qui est curieux, c'est que nous avons fait ainsi avec REBOL sans le fournir.)

La pile manipule le contexte des fonctions, le bloc des arguments de la fonction, les références de mots (pour les fonctions nommées, ou celles appelées via un path), la référence précédente des fonctions (pour les libérer), et les traitements temporaires. Ce sont tous des datatypes REBOL valides, de sorte que vous pourriez en théorie accéder à la pile elle-même comme à un bloc. De la sorte, un IDE utilisant le mode débogage pourrait afficher toutes informations pertinentes, pour les programmeurs qui voudraient les voir durant une session de déboguage.

Bien sûr, nous devons aussi être prudents dans la manière d'accéder à cette information, afin qu'elle soit correctement extraite, pour éviter des problèmes de compatibilité futurs, peut être devrions-nous étendre le format de la pile. C'est une grosse préoccupation dont nous devons nous occuper. De plus, nous devrons faire attention aux cas d'erreurs qui placent la pile dans un état interrogeable, tels que les cas d'erreurs "not enough memory" ou "corruption" (qui ne devrait pas se produire).

Note : Je voudrais ajouter qu'il peut y avoir quelques problèmes de sécurité dans l'exécution, reliés à de tels pointeurs de déboguage (comme effectuer une recherche sur la pile pour des clés de cryptage, etc.), de sorte que cette caractéristique va induire un niveau de sécurité spécifique à la fonction secure pour les sessions de déboguage.

Il est trop tôt pour connaître précisément les détails ici, mais la sécurité est une priorité très importante.

(Traduction : Philippe Le Goff)

Guide du développeur REBOL/Services

Historique de la traduction

Date Version Commentaires Auteur Email
jeudi 6 avril 2006 1.0.0 Traduction initiale Philippe Le Goff lp—legoff—free—fr

Introduction

Ce document a été écrit pour ceux d'entre vous qui veulent comprendre les REBOL/Services et comment les utiliser, mais n'ont pas le temps de lire des dizaines de pages de documentation technique. Les informations présentées ici devraient être suffisantes pour vous permettre de démarrer avec vos propres scripts et applications, mais les utilisateurs expérimentés auront intérêt à lire certains autres documents techniques concernant les REBOL/Services.

Que sont les REBOL/Services ?

Il serait facile juste de se lancer et de démarrer dés à présent avec les REBOL/Services, mais avant de faire cela, vous devriez acquérir un minimum de compréhension de ce qu'ils sont et de comment ils fonctionnent.

Les REBOL/Services fournissent un moyen simple, élégant de partager de l'information entre les programmes informatiques. Ils peuvent être utilisés pour échanger de l'information entre des clients et des serveurs qui peuvent être éloignés de milliers de kilomètres, ou simplement entre applications fonctionnant localement sur votre ordinateur.

Les REBOL/Services implémentent un concept appelé "Service Orienté Architecture" ou SOA pour faire court. L'idée de base d'un SOA est que vous envoyez un message, une requête à un autre programme ("un service") qui va tenter de répondre à la requête et de renvoyer le résultat.

Avantages des Services

Les premiers avantages des REBOL/Services sont les suivants :

Facilité d'emploi : Vous pouvez accéder au service, ou implémenter un service personnalisé avec une seule ligne de code

Sécurité : L'authentification forte et le cryptage des données sont pré-inclus, les commandes sont émises en utilisant l'approche par dialecte spécifique à REBOL (aucune exécution directe de fonction ne se produit). Pour des systèmes extrêmement sécurisés, des clés privées peuvent être utilisées, ainsi le fait de connaître le nom et le mot de passe d'un utilisateur n'est pas suffisant.

Flexibilité : Les REBOL/Services sont basés sur le concept propre à REBOL, de dialecte (dialecting) qui permet un grand degré de liberté et de contrôle avec un minimum de code. De plus, les services peuvent être utilisés au-dessus de divers protocoles de transports (TCP et HTTP sont fournis en standard).

Fiabilité : Plus votre code est court, plus votre application est fiable. Lorsque votre code fait seulement quelques Kos, comparé à quelques Mos, il y a de bonnes probabilités d'éliminer tous les bogues.

Commodité : Chaque version de REBOL aura cette technologie incluse en standard, de sorte que vos scripts et vos applications peuvent tirer parti d'elle sans ajouter de librairies dédiées.

Un standard ouvert : Pour permettre aux développeurs d'apporter des améliorations et des suggestions, tout comme de fournir des jeux de services particuliers.

Une liste plus détaillée des avantages qu'apportent les REBOL/Services peut être trouvée par ailleurs.

Types de Services

En tant que SOA, les REBOL/Services vous offrent un moyen facile de créer une grande diversité d'applications telles que :
Partage sécurisé de fichiers
Administration à distance de serveurs
Gestion de code source
Collaboration sur des documents
Mise à jour de site Web
Echange de messages (incluant l'IM, l'Instant messaging)
Gestion de tâches
Traitement de cartes de crédits
Services d'horodatage, de synchronisation.
Vote et participation à un scrutin
Allocation de ressources systèmes
Application de comptabilité
Constitution de tableaux de bords

Il n'y a pas réellement de fin à cette liste, car cela prend seulement une page ou deux pour implémenter la plupart des services. Je suis certain que vous saurez imaginer encore d'autres usages.

Pour plus d'information

Beaucoup d'autres informations à propos des REBOL/Services seront documentées dans les mois à venir. Nous fournirons un lien vers ces informations sur notre site Web.

Comment fonctionnent les REBOL/Services ?

Pour utiliser un service, vous envoyez simplement une requête. Le service traite la requête et retourne un résultat. Le service peut être n'importe où. Il peut se trouver sur un serveur distant, ou sur un autre client dans votre réseau locale, ou être un autre processus sur la même machine. Il n'y a pas de différences.

Le séquencement entre la requête et le résultat

Regardons plus attentivement ce qu'il se passe :

Requête : La requête est émise vers le service. Le format de la requête est très simple : c'est un bloc REBOL. Le bloc commence avec un mot (indiquant la commande) et contient d'autres mots et des valeurs qui sont structurées dans l'ordre où le service les attend. Il s'agit d'un dialecte en REBOL, qui offre tous les avantages de ce concept.

Traitement : La requête est traitée par le service. Il doit analyser la requête (la commande), agir en conséquence, et mettre en forme le résultat à renvoyer. Tout cela est habituellement déterminé par la fonction PARSE, mais d'autres méthodes sont également autorisées.

Résultat : Lorsque le traitement est complet, le résultat est retourné vers le client. Le format du résultat est quelque chose d'assez similaire à celui de la requête, mais pas identique.Le format permet au client de connaître rapidement si la requête a été un succès et d'obtenir les valeurs résultant du traitement.

Tous les transferts depuis et vers le service sont cryptés. Divers niveaux de cryptage sont possibles. Ils sont décrits dans un autre document.

Exemples de requêtes

A quoi ressemble le bloc d'une requête ? Cela dépend du service. Par exemple, la requête peut être aussi simple que ce bloc :

[date]

La requête demande la date courante au service. Cette commande fait partie des commandes fournies en standard pour tous les services. Le bloc d'une requête plus complexe pourrait être comme ceci :

[file/get %maui.jpg 12-Mar-2005/10:00 %hawaii.jpg 14-Mar-2005/2:20]

Ce bloc demande le transfert de deux fichiers vers le client, si les fichiers sont plus récents que les dates indiquées. Si les fichiers sont plus anciens, ils ne sont pas récupérés.

Une requête peut aussi inclure plusieurs blocs de commandes. Voici trois commandes émises dans la même requête :

[date]

[info title]

[file/put %photo.jpg (read/binary %photo.jpg)]


Le résultat qui sera retourné au client contiendra trois blocs de résultats.

Exemples de résultats

Les résultats renvoyés par un service sont constitués de deux parties :
un indicateur de succès,
et un bloc qui comprend les valeurs résultant du traitement.

Par exemple, la commande date ci-dessus va retourner :

ok [date 25-Mar-2005/12:08:12-8:00]

L'indicateur ok signifie que le traitement de la commande s'est correctement déroulé. S'il échoue, pour une raison quelconque, le mot fail est renvoyé et si une erreur se produit, le mot error est retourné.

Le bloc qui suit l'indicateur de succès rappelle la commande et vous donne son résultat. Ce bloc est aussi exprimé dans un dialecte, car le format du bloc dépend du service. Cependant, le premier item dans le bloc est toujours la commande. (Ceci rend aisé pour des clients complexes la possibilité de générer des événements en callback, au sein d'une application.)

Pour des commandes multiples dans vos requêtes, vous obtiendrez de multiples commandes dans vos résultats. L'exemple du paragraphe précédent conduira à ces résultats :

ok [date 25-Mar-2005/12:08:12-8:00]

ok [info "Default REBOL Service"]

ok [file/put %photo.jpg 20456 ]


Il y a une chose supplémentaire à savoir à propos du bloc de résultat et que nous n'avons pas montrés ci-dessus (pour simplifier l'exemple).

Il contient un indicateur et un bloc récapitulatifs de la requête. Un exemple de récapitulatif ressemble à ceci :

done [reply seq 1 service "Generic Service" commands 1 time 0:00:01]

Le mot done indique qu'aucune erreur ne s'est produite et que la requête a été complètement traitée. Le suivi du succès de la requête en est facilité, même si elle contient de multiples commandes. Le bloc contient une information qui récapitule l'état du traitement de la requête. La plupart du temps, vous pourrez ignorez sans souci cette information.

Accéder à un service

Bon, à présent, voyons comment accéder à un REBOL/Service. Les services sont implémentés en REBOL au travers d'une interface basée sur des fonctions (function-based interface). Cette approche permet de conserver une interface très simple, en minimisant ce que l'utilisateur à besoin de savoir pour faire son travail. D'autre part, sous la surface visible, un mécanisme de port asynchrone en REBOL est utilisé, permettant aux développeurs expérimentés un très grand niveau de contrôle.

Le plus simple exemple

Pour débuter, le mieux est de regarder une ligne de code qui accède à un service :

result: do-service tcp://server:8000 [date]

Cette ligne envoie une requête date, attend la réponse, et renvoie le résultat. On appelle ceci une requête synchrone. La fonction do-service va attendre, jusqu'au moment où le serveur a fini son traitement, avant de retourner le résultat.

Accès asynchrone (No-wait)

Pour certains types de programmes, vous voudrez peut-être utiliser une requête asynchrone. Dans ce cas, la fonction n'attend pas le résultat . Vous pouvez soit fournir une fonction qui sera appelée lorsque le résultat sera reçu (fonction en callback), soit attendre la réponse.

Voici un exemple de requête asynchrone :

send-service/action tcp://server:8000 [date] [print mold result]

Ici, une requête date est émise vers le service, mais sans attendre le résultat. Lorsque le résultat est reçu, le second bloc est évalué, pour afficher le résultat. Cette approche est très similaire avec le principe des interfaces graphiques, qui sont par nature asynchrones (plusieurs choses réalisées en même temps). S'il est nécessaire que vous attendiez le résultat d'une requête faite précédemment, vous pouvez utiliser la fonction wait-service.

Voici un exemple :

req: send-service tcp://server:8000 [date]

do-some-other-stuff

result: wait-service req

La requête est envoyée, puis tandis qu'elle est traitée, vous pouvez faire d'autres choses. Lorsque vous avez besoin du résultat, vous pouvez l'attendre et le placer dans la variable result.

Emissions de requêtes multiples

L'exemple ci-dessus illustre comment utiliser une URL pour appeler un service. Cependant, la plupart du temps, dans les applications réelles, vous n'aurez pas à fournir une URL à chaque fois. Au lieu de cela, vous établirez une connexion qui restera active pour de multiples requêtes. Ceci peut être réalisé avec la fonction open-service :

port: open-service tcp://server:8000

Elle renvoie un port qui peut être utilisé comme argument pour d'autres fonctions :

result: do-service port [date]

send-service/action port [date] [print mold result]

Lorsque vous aurez fini, vous enverrez un ordre pour fermer la connexion :

close-service port

Il s'avère également que vous pouvez employer les fonctions send-service et login-service pour ouvrir le port et pour le maintenir ouvert. Il n'est pas nécessaire d'utiliser uniquement open-service ; cependant, open-service permet de spécificier des options particulières, susceptibles d'être employées pour la connexion.

Les fonctions utiles pour les requêtes à un service

Voici un résumé des fonctions qui sont utilisées pour manipuler les requêtes émises vers un service. Elles sont implémentées dans l'API client (Application Programming Interface).

Function Description
do-service Émet une requête vers un service et attend le résultat. Renvoie le résultat. Le résultat sera simplifié si c'est possible (Les champs de la réponse pourront ne pas être tous renvoyés. Voir plus loin.)
send-service Émet une requête vers un service mais n'attend pas le résultat. Renvoie un objet req-message qui peut être utilisé par d'autres fonctions listées ci-dessus. Un bloc (ou une fonction) peut être aussi spécifié en option pour le callback, en utilisant le raffinement /action.
wait-service Attend le résultat d'une requête émise précédemment avec send-request et renvoie le résultat. Le résultat n'est pas simplifié (il contient tous les champs de la réponse faite par le service.)
query-service Retourne le résultat d'une requête émise précédemment avec send-request, si elle a été reçue. Sinon, retourne NONE. Cette fonction vous permet de tester la disponibilité d'un résultat sans l'attendre. (NdT : une sorte de "polling" sur la réponse, en quelque sorte)
open-service Ouvre une connexion à un service et renvoie un port REBOL, qui peut être utilisé avec toutes les autres fonctions de l'API. Permet de spécifier des options supplémentaires relatives au service, comme des délais pour des time-outs, ou des clés, des méthodes de cryptage.
close-service Ferme le port lié au service ouvert précédemment. Aucune erreur ne se produit si le service a déjà été fermé.
abort-service Interrompt une requête send-service précédente, si c'est possible. Renvoie TRUE si la fonction s'est exécutée correctement. Renvoie FALSE si la requête a déjà été envoyée au service et ne peut être interrompue.
login-service Il s'agit d'une fonction qui facilite l'authentification lors de l'accès à un service et initie une session complètement cryptée. Cette fonction ne rend la main que lorsque l'étape de login est compléte (l'implémentation est faite en tant que fonction synchrone). Le login asynchrone est implémenté par l'envoi d'une requête login au service avec la fonction send-service.
logout-service Termine une session authentifiée et cryptée.

Requêtes à un service

Une requête à un service est un bloc de commande(s) qui est émis vers le service par les fonctions do-service et send-service.

Requêtes uniques

Pour conserver une certaine simplicité aux exemples ci-dessous, seule la requête date est présentée :

result: do-service tcp://server:8000 [date]

Les requêtes uniques peuvent être émises ainsi dans un bloc. Ici, le mot date est la commande demandée, et elle ne nécessite pas d'arguments. D'autres commandes peuvent nécessiter des arguments additionnels. Ceux-ci peuvent également être fournis au sein du bloc :

result: do-service tcp://server:8000 [info title]

result: do-service tcp://server:8000 [login "carl"]

Les fonctions de requête à un service effectuent un COMPOSE/deep sur le bloc. Ceci vous permet d'insérer des termes à évaluer à l'intérieur du bloc. Par exemple :

result: do-service tcp://server:8000 [

file/put %photo.jpg (read/binary %photo.jpg)

]

Dans cet exemple, le fichier photo.jpg est lu comme un fichier binaire, puis est inséré dans la requête avant son envoi.

Requêtes multiples

Le format des requêtes à commande unique permet de conserver un code simple. La forme la plus générale permet cependant l'envoi de commandes multiples à un service dans une seule requête. Pour cela, chaque commande doit être encapsulée dans un sous-bloc :

result: do-service tcp://server:8000 [

[date]

[info title]

[file/put %photo.jpg (read/binary %photo.jpg)]

[file/get %manual.txt]

]

Cet exemple envoie les quatre commandes via une service avec une seule requête. Les résultats retournés seront dans un format similaire, voir la section "Résultats de services" plus loin.

L'écriture utilisée (paths) pour les commandes file/put et file/get indique qu'elles sont trouvées dans le contexte du REBOL/Service file (le service de fichier ), pas dans le contexte global par défaut. Voir la section "Contexte d'un service" ci-dessous.

Les requêtes utilisent un dialecte

Il est important de comprendre que les requêtes faites aux REBOL/Services sont des dialectes REBOL. Ceci étant, elles n'appellent pas les fonctions REBOL directement au sein du service, mais sont interprétées comme un sous-langage spécifique à un domaine.

Cette approche :

  • Permet une meilleure sécurité car l'API du langage REBOL n'est jamais directement utilisée. 
  • Permet d'avoir une plus grande diversité d'expression qu'en RPC (remote procedure call) ou RMI (remote method invocation). Les jeux de commandes peuvent être des sous-langages complets. 
  • Nécessite très peu de code pour implémenter des services en comparaison d'autres approches. 
  • Les rend plus facile à tester. Les dialectes de commandes sont manipulés par la fonction PARSE qui être facilement appelée et déboguée de manière autonome durant leur développement. Le service n'a pas besoin d'être mis en ligne pour être massivement testé.

Résultats des Services

Le résultat d'un service est une ou plusieurs valeurs retournées par le traitement de la requête.

Résultats simples et uniques

La fonction do-service fournit une simplification des résultats pour des requêtes particulières. Ceci se voit dans les exemples suivants :

print mold do-service tcp://server:8000 [date]

25-Mar-2005/12:08:12-8:00

print mold do-service tcp://server:8000 [info title]

"Default REBOL Service"

Dans la plupart des cas, le résultat est retourné sous la forme d'une valeur unique. Ceci est uniquement vrai pour le cas où do-service est utilisé avec une seule commande. Les requêtes à plusieurs commandes renvoient des blocs à plusieurs résultats, comme décrit ci-dessous.

Note de conception : Nous pouvons être amenés à réévaluer cette façon d'opérer. Elle est similaire dans le comportement à la fonction LOAD, laquelle si elle n'est pas bien connue par l'utilisateur, peut conduire à des erreurs. Me contacter pour donner votre avis sur ce point.

Résultats multiples

Lorsque des commandes multiples sont envoyées à un service dans une seule requête, leurs résultats sont retournés sous forme de plusieurs blocs. Voici un exemple de résultat issu d'une requête à plusieurs commandes.

probe do-service tcp://server:8000 [

[date]

[info title]

[file/put %photo.jpg (read/binary %photo.jpg)]

[file/get %manual.txt]

][

ok [date 25-Mar-2005/12:08:12-8:00]

ok [info "Default REBOL Service"]

ok [file/put %photo.jpg 20456]

ok [file/get %manual.txt 25-Mar-2005 #^{...^}]

]

Chaque résultat commence avec un indicateur de succès (ok), suivi d'un bloc, le contenu du résultat. Pour rendre plus facile l'identification des résultats, ceux-ci sont toujours retournés dans le même ordre que les commandes, et chaque résultat inclut la commande requise : c'est le premier item du bloc. Il vous est possible, selon les options particulières choisies, d'avoir des résultats mixtes comprenant des requêtes réussies et d'autres qui ont échouées :

[

ok [date 25-Mar-2005/12:08:12-8:00]

ok [info "Default REBOL Service"]

fail [file/put not-allowed]

fail [file/get not-exists]

]

De plus, le bloc de résultat peut inclure un en-tête optionnel qui récapitule les résultats de la requête, en comprenant d'autres détails qui sortent du cadre de ce document.

Contextes propres aux commandes des REBOL/Services

Un serveur peut incorporer de multiples contextes pour les commandes des services. Chaque contexte fournit un lot de commandes pour un service spécifique. Par exemple, le serveur par défaut (pré inclus) fournit les contextes suivants :

Home - implémente des commandes qui font partie de tous les services. C'est le contexte par défaut et c'est un service requis. Son principal objet est de fournir des informations sur un serveur.

Admin - fournit les commandes pour contrôler votre service, sa mise à jour, redémarrage, gestion des utilisateurs, récupération des logs et d'autres encore.

File - Un ensemble de commande pour accéder ou transférer de petits fichiers (moins de quelques Mos). Ce service peut être utilisé pour uploader ou télécharger des pages web, des graphiques, du code et d'autres fichiers.

Les commandes au sein d'une requête peuvent explicitement spécifier un contexte en utilisant la notation avec les paths :

[admin/reset]

[file/get %photo.jpg]

(NdT : on a une notation du type /)

Ou, vous pouvez sélectionner un contexte différent avec la commande SERVICE :

[service admin]

[add-user "Bob" "Robert Smith" ...]

[change-user 47 user "Jenny"]

[date]

Ici les commandes add-user et change-user font partie du contexte admin. Vous pouvez changer le contexte de la commande autant de fois que vous le voulez au sein de la même requête. De plus, les commandes du contexte home sont toujours utilisables au sein des autres contextes, tant qu'elles n'ont pas été écrasées par des commandes dans le contexte courant. par exemple, ceci est valide :

Ici la commande date fait partie du service (contexte) home, pas du service (contexte) admin.

Créer un service

A présent que vous savez comment accéder aux REBOL/Services, voici quelques bases pour créer un service.

Un simple serveur

Cet exemple démarre un serveur, mais n'appelle aucun service spécifique. Il utilisera que les services standards (home, admin, et file, comme indiqué précédemment.)

service: start-service tcp://:8000

Le serveur utilise une connexion directe en TCP sur le port 8000. Immédiatement, il commencera à traiter des traiter des requêtes.

Voici un exemple de ce que vous pouvez saisir dans un script et tester :

REBOL [Title: "Example Server"]

service: start-service tcp://:8000

ask "PRESS ENTER TO QUIT"

stop-service service

Le serveur continuera à fonctionner jusqu'à ce que vous pressiez la touche "Enter". Lorsque celle-ci est activée, le service s'arrête.

Créer votre propre service

Pour créer votre propre service, tout ce dont vous aurez à faire est de créer un contexte de service avec un dialecte pour vos commandes.

Un contexte de service est un objet REBOL qui est mis dans un fichier, ce fichier étant chargé lorsque votre serveur démarre. Voici un exemple de service qui implémente un petit système de bulletins électroniques (Bulletin board).name: 

'bbs-example

title: "Micro-BBS Service"

description: " un BBS très simplifié."

; Message format: [date author message]

messages: any [attempt [load %messages.r] copy []]

commands: [

'put "Store a new message"

arg: string! "Author" string! "Message" (

write/append messages mold reduce [now arg/1 arg/2]

result: true

)

| 'get "Get a messages by number"

(result: copy [])

some [

arg: integer!

(repend result [arg/1 pick messages arg/1])

]

| 'list "List new message numbers since a given date or number"

(result: copy []) [

arg: date! (

num: 1

foreach msg messages [

if msg/1 >= arg/1 [append result num]

num: num + 1

]

)

| arg: integer! [

repeat n length? skip messages arg/1 [

append result n

] ]

] ]

]

Notez que les chaînes de caractères à l'intérieur du dialecte pour les commandes sont utilisées pour documenter le code, et elles sont extraites lorsque le service est initialisé. Le bloc de règles passé à la fonction PARSE ne contient pas de chaînes littérales. Il existe aussi une notation spéciale à utiliser pour inclure des chaînes spécifiques à une langue. (Plus d'information plus tard sur ce point). Les variables result et arg sont définies localement dans la fonction là où le bloc de la commande est évalué. La variable resultat contient la valeur ou le bloc qui sont retournés depuis la commande et renvoyés au client.

Pour mettre le service en ligne, vous devez l'indiquer dans le bloc des services qui est fourni en tant qu'option à la fonction start-service.

service: start-service/options tcp://:8000 [

services: [%bbs-example.r]

]

Il est également possible d'ajouter le service dans la configuration du serveur en utilisant la fonction handle-service, mais cette caractéristique sera décrite dans un document à part.

Le binding à la volée (Just-in-time (JIT))

Le binding à la volée

Carl Sassenrath, CTO REBOL Technologies 11-Apr-2006 16:39 GMT Article #0010

REBOL 3.0 va introduire un nouveau type de binding : le binding à la volée (Just-in-Time). C'est un article assez long, mais je pensais que vous seriez intéressés par des détails, et je sais que vous ne serez pas timides en me faisant vos commentaires

Actuellement, REBOL supporte deux sortes de binding :

Definitional Context Binding (DCB) C'est le binding qui se produit lorsque vous définissez un bloc de données comme le corps d'un datatype particulier ou un contexte. C'est le binding usuel tel qu'il est implémenté par la fonction bind. Par exemple, les variables de la fonction sont liées au corps de la fonction lorsque make function! est mis en oeuvre (ou les mezzanines comme func, function, etc.)

Late Path Binding (LPB) C'est le binding qui se produit lorsque vous utilisez un path contenant des champs symboliques. Ce binding très tardif se produit durant l'évalution du path lui-même. Cela arrive principalement quand vous accédez aux champs d'un objet, et il est effectué tardivement pour que les champs soient eux-mêmes des variables.

Ces méthodes de binding fonctionnent bien pour le code REBOL classique ; cependant, pour traiter des dialectes en REBOL, ils n'apportent aucun bénéfice car les mots du dialecte ne subissent jamais le processus de définition. Les dialectes sont juste des blocs, pas des datatypes spécialisés tels que les fonctions ou les objets.

Durant l'implémentation du projet Rebcode (qui a créé un modéle unique de machine virtuelle REBOL très performante), il est devenu évident qu'une méthode très rapide de consultation était nécessaire pour les op-codes de la machine virtuelle (VM). Lorsque vous indiquez un "add" ou un "sub", vous ne souhaitez pas que l'interpréteur dépense du temps en essayant d'imaginer ce que ces op-codes signifient.

Deux solution deviennent évidentes :

utiliser le DCB ou créer un nouveau type de binding "tardif", qu'en attente d'une définition plus convenable j'ai appelé "just-in-time binding (JIT)". Les deux méthodes seront à prende en compte ; cependant, parce que le Rebcode a été incorporé dans un wrapper de fonction, il a eu l'opportunité d'utiliser DCB. En outre, on ne permet pas la modification des blocs de Rebcode après leur définition. Ainsi le DCB était parfait pour cela et a amélioré la vitesse de Rebcode par trois ou quatre fois.

Bien, qu'en est-il à propos des dialectes REBOL ? Les performances des dialectes avec draw et avec parse peuvent-elles êtres améliorées ?

Oui, c'est possible. Prenez par exemple le dialecte draw. Les mots-clés (commandes) du dialecte sont évalués rapidement, mais pour des grands blocs (commme de grandes images SVG), les performances pourraient être meilleures. Une quantité significative de temps est nécessaire pour résoudre les mots-clés chaque fois que le bloc draw est évalué.

Rebcode a été implémenté en utilisant la technique dans laquelle un contexte pour le dialecte définit les mots du dialecte, et le DCB a été utilisé pour binder le bloc du dialecte à ce contexte. Il n'y a rien d'extraordinaire jusque là.

Cependant, cette méthode avec le DCB ne marche pas bien avec des dialectes comme draw, qui peuvent changer dynamiquement. Par exemple, durant une animation, le programmeur peut insérer ou supprimer des commandes dans ou depuis le bloc draw.

De tels changements diminueraient la raison d'être du travail effectué par le DCB, sachant qu'une alternative serait de forcer le programmeur à maintenir le binding manuellement pendant chaque insertion, mais que nous préférerions éviter cela.

C'est là qu'entre en scéne le "JIT binding", le binding à la volée. Avec le JIT, les mots d'un bloc sont liés au contexte qu'ils ont trouvé durant leur évaluation. Contrairement au LPB, les mots d'un bloc sont modifiés pour conserver leurs nouveaux bindings. Ils sont "collants". A l'évaluation suivante du bloc, un contrôle rapide du contexte des mots est exigé, et aucune autre action n'est nécessaire. Si un nouveau mot a été inséré, le contrôle échoue, et le binding JIT se produit.

Le résultat est que des dialectes avec draw et parse sont évalués plus rapidement, mais sans la nécessité de pre-binder les mots au bloc du dialecte. Et, si le bloc reste globalement peu modifié, la vitesse d'évaluation d'un dialecte est très proche du pur code REBOL (nécessitant seulement un contrôle de contexte pour chaque mot).

Y-a-t-il une contre-partie à cette méthode ? Oui. La bonne conception repose sur la gestion des différences. Cela prend une petite fraction de temps de définir la méthode JIT avant l'évaluation du dialecte. Pour des blocs de petite taille qui contiennnent moins de trois ou quatre mots-clés, le coût de la prise en compte de la JIT peut ralentir le traitement de ces blocs. C'est le genre de chose que nous devrons tester et évaluer. Il peut aussi y avoir quelques pénalisations légéres pour les exceptions (erreurs, break, retours, throwns) qui se produisent durant l'évaluation des dialectes en mode JIT ; cependant, ces évenements devraient être rares dans la plupart des codes de dialectes.

En conclusion : le binding à la volée (just-in-time) est juste une sorte de DCB effectué "à la volée". Il est possible que ce type de binding puisse conduire à des gains en performance pour les dialectes, qui utilisent draw, parse, etc. Il est aussi possible que nous utilision le JIT au lieu du LPB pour améliorer les performances sur les accès des champs des objets. Cela doit être étudié.

Note : ce concept est encore au tout début de la phase de conception, et nous en saurons plus bientôt. Si vous avez des commentaires sur cette idée, je sais que vous serez heureux de les poster sur le blog. Merci.

(Traduction : Philippe Le Goff)

La question du 64 bit

Carl Sassenrath, CTO REBOL Technologies 10-Apr-2006 20:00 GMT Article #0009

Cette question est dans un coin de ma tête depuis déjà quelques mois.

Pour le moment, REBOL 3.0 utilisera encore des nombres entiers sur 32 bits afin de le mettre en service et de le faire fonctionner aussi rapidement que possible.

Cependant, le temps va venir au cours des prochaines semaines de faire le grand saut à 64 bits. Bien sûr, l'intérêt est que les nombres entiers puissent avoir des valeurs beaucoup plus grandes, donc des tailles très grandes de fichiers , etc... L'inconvénient est que les valeurs 64 bits exigent plus de temps CPU pour les opérations d'accès mémoire et mathématiques. Elles prennent également deux fois plus d'espace mémoire, cependant REBOL assigne déjà cet espace, de sorte que la plupart des programmes ne verront pas cette augmentation.

Le changement vers le 64 bit affectera plus que les valeurs des nombres entiers. Par exemple, voulons nous permettre des séries (exemple : chaînes de caractères, binaires) plus grandes que 2/4GB ? Je ne suis pas en train de parler des fichiers (voir ci-dessous) ; je parle des séries courantes en mémoire. Si nous voulons cela, non seulement la structure de gestion (ex. la position de fin, tail) va grandir, mais le pointeur pour indexer la série aussi (pour être capable d'adresser des séries de grande taille). Bien que ce ne soit pas une grosse affaire pour les définitions de structure, c'est en une pour le code run-time ; REBOL est en effet complètement packagé avec des références à des choses comme la fin (tail) et l'index de série (pour du contrôle de limites, etc.).

Et finalement, il y a l'idée que peut-être, nous pourrions utiliser une compilation variable en 32 ou 64 bits pour produire des versions correspondantes. Une version 32 bits peut avoir plus de sens pour des choses comme des téléphones mobiles et des PDAs. Mais, cela soulève la question que ces versions de REBOL devront être étroitement compatibles, mais pas parfaitement compatibles. Peut-être pourraient-elles être améliorées en employant des nombres entiers sur 64 bit, mais des séries sur 32 bits.

Comme avec tout processus de conception, il y a diverses possibilités à considérer. Certainement, les besoins des utilisateurs de REBOL devraient nous aider à déterminer le meilleur compromis entre les choix. Personnellement, j'aime l'idée des maths avec des nombres entiers sur 64 bits, mais la restriction des séries sur 32 bits me va bien.

D'ores et déjà, j'avais l'habitude d'utiliser seek pour adresser les grands fichiers .

Et, en ce qui concerne les fichiers, je dois noter que j'envisage une nouvelle version du datatype port! qui autorise l'accès à des index sur 64 bits. Ces nouveaux ports ne stockeront plus leurs positions d'index dans leurs références, mais dans l'objet lui-même. L'objet system fonctionnera davantage comme dans l'accès traditionnel aux fichiers, qu'il ne l'a fait dans le passé.

(Traduction : Philippe Le Goff)

jeudi 04 mai 2006

Les fonctions ordinales des séries se comportent à présent comme PICK

Carl Sassenrath, CTO REBOL Technologies 9-Apr-2006 21:59 GMT Article #0008

Les fonctions ordinales (first, second, etc.) ont été à l'origine conçues pour être assez strictes - principalement pour les débutants.

Par exemple :


print first tail "abc"
** Script Error: Out of range or past end

provoque une erreur. Cependant, la fonction pick n'en provoque pas :


print pick tail "abc" 1
none

Je pensais que cette différence était Ok, car les experts n'utilisent pas first. Cependant, je ne crois plus cela. Les fonctions ordinales sont des fonctions très efficaces et je tends moi-même à les utiliser comme des "sélecteurs" rapides dans des bouts de code comme celui-ci :


the-name: :first
the-email: :second
the-message: :third

send the-email data the-message data

Pour du code "haute performance", cette méthode est aussi rapide qu'il est possible.

Lorsque elle est utilisée dans des grandes boucles, elle est plus efficace en rapidité que de sélectionner les champs d'objets ( qui nécessitent à la fois une interprétation des paths et le binding durant l'exécution). En fait, j'utilise si souvent cette méthode, que j'avais implémentée une fonction ordain pour définir dans mon code les relations ordinales précédentes.

Il y a seulement un problème. L'erreur "past end" n'est pas souhaitée.

En REBOL 3.0, les changement dans l'implémentation des fonctions ordinales (depuis les fonctions d'action spécifiques aux datatypes jusqu'aux natives génériques) rend leur comportement similaire à pick, par défaut. L'erreur "past end" est maintenant supprimée.

Cela semble préférable, et la modification devrait conserver la compatibilité, car le cas "past end" rconduisait à une erreur (une exception) dans les versions précédentes, de sorte qu'il n'était pas utilisé dans le code existant.

Notez que ceci nécessitera certaines mises à jour mineures dans la documentation.

(Traduction : Philippe Le Goff)

Les erreurs désarmées, la fonction "cause"

Carl Sassenrath, CTO REBOL Technologies 9-Apr-2006 19:13 GMT Article #0007

En REBOL 3.0, les valeurs d'erreur sont désarmées (disarmed) par défaut.

Les versions précédentes de REBOL utilisaient les erreurs "à chaud". Cependant, vous deviez traiter ces valeurs d'erreur de façon spécifique, ou elles déclenchaient automatiquement la gestion d'erreur. Ce comportement avait été implémenté à l'origine pour éviter que les erreurs se propagent trop loin de leurs origines (le principe était de préserver autant que possible la localisation d'une erreur).

Ces erreurs "à chaud" finissaient par être réduites à néant, et l'intérêt de pouvoir localiser une erreur était compensé par la difficulté de gérer les valeurs d'erreur en général. (Voir les articles de Ladislav Mecir qui a écrit d'excellentes notes sur ce sujet). C'était très souvent vraiment épineux.

Avec ceci à l'esprit, sachez que REBOL 3.0 supprimera les erreurs à chaud.

Les valeurs d'erreurs (objets) sont désarmées par défaut, et peuvent être traitées de la même manière que tous les autres objets. Les fonctions comme try peuvent être utilisées pour capturer les erreurs et les traiter comme des valeurs normales.

Dans les cas où il est nécessaire de ré-armer une erreur, et de forcer son retour dans l'état "à chaud", la fonction cause a été ajoutée. Vous "provoquez" la reconsidération de l'erreur pour être traitée. (voir la description de Ladislav sur "fire".)

Voici un simple exemple de manipulation d'une erreur spécifique :


result: try [... do something ...]
if all [
error? result
result/id = 'zero-divide
] [
cause result
]

L'exemple évalue un bloc et capture toutes les erreurs. Le résultat (erreur ou non) est stocké dans le mot result. Le code vérifie si l'erreur est celle d'une division par zéro (zero-divide), et si oui, renvoie l'erreur à un niveau de traitement supérieur (non montré). Remarquez que disarm n'est pas utilisée.

Pour la compatibilité avec REBOL 2.0, la fonction disarm sera encore fournie, mais elle ne fait plus grand chose. (renvoie l'objet error comme un object ! plutôt que comme une error !, c'est tout.)

Notes pour les experts :

En interne, la fonction cause provoque un "stack throw" (un long saut en C) qui est très rapide, mais des parties importantes du contexte d'exécution sont perdues dans ce processus.

Par comparaison, les fonctions REBOL break, return, et throw libèrent la pile d'une manière ordonnée, ce qui permet de rendre possible des options de déboguage durant le processus.

Plus d'informations sur la gestion des erreurs,bientôt.

(Traduction : Philippe Le Goff)

- page 1 de 7