Cette séance va être consacrée à un survol de la syntaxe.
Donc, on va vous montrer l'entièreté de la syntaxe.
Il ne faut pas que vous vous stressiez par rapport à si
vous comprenez ou pas entièrement.
On reprendra tous ces éléments plus tard.
Par contre, l'idée, c'était de vous montrer l'ensemble de
ce qu'il y a dans Pharo. On va voir les éléments
syntaxiques principaux.
On va voir qu’il y a trois sortes de messages.
Et puis, on va voir la syntaxe sur les blocks qui est un
élément essentiel de Pharo.
Ne stressez pas si vous n'avez pas tout compris, on
reprendra chacun de ces points dans des séquences ultérieures.
Juste pour le rappel, vous avez toute la syntaxe sur ce transparent.
Là, par exemple, maintenant je peux venir un petit peu
dans les détails, vous avez une définition de méthode.
Là, je définis la méthode exampleWithNumber.
Elle a un argument.
Par exemple, je vais avoir des définitions locales de
variables avec les barres verticales.
J'ai le Return qui me permet de rendre une valeur.
Je vais avoir des boucles, une affectation.
Le point, par exemple ça va être un séparateur d'instruction.
On va voir ce genre de
choses.
Commençons par le traditionnel Hello World.
D'ailleurs, toutes les expressions, vous pouvez les
exécuter dans Pharo vous-même pour voir ce que donne le résultat.
Là, j'ai une chaîne que je convertis
dans une Morph, c'est un élément graphique.
Je demande à cet élément graphique de s'ouvrir dans une fenêtre.
J'ai envoyé message asMorph à l'objet String et j'ai
envoyé le message openInWindow à l'objet Morph résultant.
Donc là, on a eu deux envois de messages et un objet String.
Un exemple plus compliqué, imaginons que vous vouliez
prendre le logo Pharo qui se trouve sur le web, on va
faire ça de la manière suivante.
On va faire ZnEasy getPng avec une chaîne qui représente
l'url de la ressource qu'on veut lire.
Et encore une fois, on va la convertir en chaîne, en un
objet graphique et lui demander de s'ouvrir dans une fenêtre.
Là, qu'est-ce qu'on voit ?
On voit que ZnEasy est une classe parce que les classes
commencent par une majuscule. Le message getPng:
les deux points, ça veut dire que je j'attends un argument.
Qu'est-ce que j'ai comme argument ?
J'ai la chaîne'http://pharo.
org', j'ai cette chaîne-là qui est l'argument de la
méthode getPng. Donc, les messages
as Morph et openInWindow sont lus de gauche à droite.
Encore une fois, vous pouvez vraiment copier-coller ce
code, ou le retaper dans Pharo, l'exécuter et vous allez
récupérer le logo Pharo.
Si on regarde ce qu'il y a comme élément syntaxique dans
Pharo, vous avez les commentaires qui commencent avec des doubles quotes.
Ça, c'est un commentaire.
Des caractères, les caractères sont toujours avec dollar
quelque chose, $A, c'est le caractère A.
Vous avez des chaînes, les chaînes commencent et
finissent par une simple quote. Vous avez des symboles,
les symboles ce sont des chaînes uniques.
Souvent, ça commence comme ça, un symbole avec le symbole
dièse, donc #A c'est le symbole A.
Vous avez aussi des tableaux de littéraux.
Là, j'ai un tableau avec 12, 23 et 36.
J'ai un tableau à trois éléments.
Après, vous avez les entiers, ils ont plusieurs
représentations, mais dans ce cours, on ne va pas s'appesantir dessus.
En général, on va utiliser des représentations à base 10,
mais si vous voulez une représentation à base 2, vous pouvez aussi.
Vous avez des réels, c'est pareil.
Si vous en avez besoin, vous trouverez la syntaxe.
Vous avez les booléens avec True ou False.
Vous avez la valeur indéfinie, le nul de Java qui est le
nil en Pharo qui est instance de la classe UndefinedObject.
Et vous avez les points, un point, ça se décrit en Pharo
sous la forme de 10@200, par
exemple. Ça veut dire, je crée le point 10 qui a X en 10 et 200 en Y.
Maintenant, on a vu à peu près les éléments essentiels
pour l'aspect syntaxique. Vous avez les constructeurs du langage.
Vous avez définition de variable, définition de variable
temporaire, je vais mettre barre verticale suivie d'une barre verticale.
L'affectation, c'est deux points égal, ça c'est l'affectation,
je mets dans la variable var la valeur Value.
J'ai des messages dans mon système.
Comment je les sépare ?
Je les sépare par des points quand je veux avoir une séquence de message.
J'ai le retour, ça veut dire, une fonction ou une méthode
va rendre une valeur, je vais utiliser le chapeau qu'on
appelle caret en anglais.
Après, vous avez des blocks qui sont, de manière
technique, des cultures lexicales et qu'en première
instance, vous pouvez prendre comme des méthodes anonymes.
Je vous montre ce qu'est un block.
Un block, ça se définit avec des crochets et ça s'
exécute en utilisant le message value, on va voir ça aussi.
Vous avez tous les constructeurs du langage.
Si on regarde, qu'est-ce qu'un programme en Pharo, son essence?
C'est créer des objets, qu'on a sûrement créés en
utilisant des messages, envoyer des messages à ses objets
et, de temps en temps, utiliser des blocks ou des méthodes anonymes.
C'est tout.
Maintenant, il y a trois types de messages.
Pourquoi y a-t-il trois types de messages dans Pharo?
C'est principalement pour minimiser le nombre de parenthèse qu'on utilise.
Vous allez voir, c'est relativement simple.
Vous avez les messages unaires, un message unaire c'est
toujours un receveur, un sélecteur.
Là, par exemple, j'ai dit je veux 9².
Je veux obtenir la date d'aujourd'hui, j'envoie le
message today à l'objet date, à la classe date.
Il n'y a pas d'arguments, ce sont des messages unaires.
Vous avez les messages binaires.
Les messages binaires sont toujours de la forme un
receveur, un sélecteur, un argument.
Mais le sélecteur, ça sera +, -, ~, ~, =, =, /, /, /,
ce genre de choses.
Tout ce qui a l'air de grigri mathématique, c'est pour
les messages binaires. Là, on voit par exemple 1 + 2, c'est un message.
On envoie le message plus à l'objet 1 avec comme argument l'objet 2.
@ pour la création de points, c'est aussi un message.
C'est un message binaire.
Donc là, je crée le point 3 4 en envoyant le message
@.
Après, vous avez des messages qu'on appelle des messages à mots-clés.
Un message à mots-clés, c'est vraiment de la forme
receveur, une clé, un argument, une clé, un argument.
L'exemple que vous avez, c'est 2.
Est-ce que 2 est entre 10 et 20 ?
Si vous l'écriviez dans une syntaxe Java ou C, vous
l'écririez de la forme suivante. Vous écririez Between
and et vous
mettriez des parenthèses, 10, 20.
Dans Pharo, on va l'exprimer sous forme clé
et clé. On va revoir ça, évidemment, mais c'est pour vous
donner cette idée de la syntaxe.
Quand vous avez des messages, il y a une précédence entre
ces messages, le système va toujours exécuter en priorité
les parenthèses, puis les messages unaires, puis les
messages binaires et les messages à mots-clés.
Pourquoi? C'est l'idée de nous éviter d'écrire trop de parenthèses.
On aurait très bien pu avoir un système où on n'a pas
tout cette différenciation, mais on mettrait des
parenthèses partout et ça rendrait le code illisible.
Je vais revenir sur chacun de ces types de messages de manière très simple.
Un message unaire, par exemple, 10 000 factoriel.
Faites-le, vous allez voir, c'est un très gros chiffre.
10 000 factoriel, j'envoie le message factoriel à l'objet 10000.
Il n'y a pas d'argument.
C'est un message unaire.
De la même manière, un message binaire.
1 + 3, c'est un message binaire.
Le sélecteur, ça veut dire le nom de la méthode, là, c'est plus.
Et j'ai envoyé le message plus à l'objet 1 avec l'objet 3 en argument.
Un message à mots-clés, c'est ce que je vous expliquais tout à l'heure.
Je ne fais juste que répéter parce qu'enseigner, c'est répéter.
J'ai un message mots-clés dans lequel j'ai keyword,
keyword qui est le message avec les arguments.
Vous avez vraiment les arguments qui flottent à l'intérieur du message.
L'idée de cette syntaxe, c'était de faire une syntaxe que
les enfants puissent utiliser.
L'idée, c'est d'avoir quelque chose qui s'apparente à de l'anglais.
On va pouvoir introduire les arguments à l'intérieur
de nos messages. Regardez un exemple.
Imaginons que je veuille faire une requête http.
ZnClient c'est un serveur http Pharo, donc je crée une
instance de ZnServeur.
New est un message unaire, il n'y a pas d'argument, de
toute façon il n'y a pas deux points.
Url est un message à mots-clés, il y a un deux
points. QueryAt:put: est un autre message à mots-clés.
Et get est finalement un message unaire.
Ce qu'on voit ici, sur cet exemple, ce sont les point
virgules, on appelle ça une cascade.
La cascade, c'est l'idée de dire je veux envoyer tous ces
messages au même objet. Ça évite d'avoir une variable
temporaire pour rien et ça permet d'écrire du code un
petit peu plus compact.
Ce qu'il faut voir, c'est que les messages sont
absolument partout dans Pharo. Les conditions, les
boucles, les itérateurs, la concurrence, tout est exprimé
sous forme de message. Ce que je vous ai expliqué sur les
trois messages précédents va s'appliquer partout.
C'est la pierre angulaire du système.
Il n'y a rien d'autre que ces messages-là.
Regardons. Là, j'ai pris la définition débile de factoriel.
Comment est-ce que j'ai défini ce factoriel?
Je définis ma méthode factorielle, je mets un commentaire
pour la méthode parce qu'il y a des doubles quotes et je
commence à dire, self, si l'objet qui reçoit le message
est 0, alors je vais rendre 1, si self est positif, par
exemple, si je fais factoriel 6, self vaudra 6.
Si c'est vrai, à ce moment-là que vais-je faire, je vais
rendre quoi, 6 multiplié par 6 moins 1 factoriel, la
définition récursive qu'on connaît tous.
Ce qui est intéressant de regarder, c'est de voir ici que
le message ifTrue qui est une condition, c'est aussi un
message parce que c'est un message à mots-clés, il a deux
points qui est envoyé à un booléen.
Donc vous avez aussi ifTrue, ifFalse, ifFalse, ifFalse,
ifFalse, toutes ces conditions sont des messages qui
satisfont les règles et qui sont de la sorte des messages
à mots-clés que j'ai présentés précédemment.
Donc, les conditions sont des messages.
Les boucles sont aussi des messages.
Ça veut dire que là je veux faire une boucle de 1 à 4.
De 1 à 4, que dois-je faire ?
Je vais faire un block, un block c'est une méthode anonyme.
Je vais lui dire je veux que tu affiches la valeur de I,
et I va prendre 1, 2, 3, 4
puisque c'est ce que je dis.
Et là, ce que vous voyez c'est que to:do: est un message à mots-clés.
C'est un message qui va représenter une boucle.
Il y a plein d'autres boucles dans Pharo, timesRepeat: to:by:do: etc.
On va les voir dans le cours.
Là, to:do: est envoyé à l'objet 1 avec comme paramètre
4 et un block. On va voir ce qu'est un block rapidement après.
Vous avez aussi des itérateurs.
Les itérateurs, c'est différent, c'est que j'envoie le
message, par exemple, do: à la collection en lui disant
ce que je veux appliquer sur chacun des éléments.
Là, le each, l'argument de ma fonction va prendre comme
valeur 1, 2 moins 4 et moins 86.
Ce que je fais, c'est que le each, je vais lui appliquer
la valeur absolue et je vais l'afficher.
Encore une fois, ça sera un autre cours, on vous expliquera les itérateurs.
Les itérateurs sont des choses qui arrivent en Java 8 et
ça fait partie du noyau de Pharo.
Qu'est-ce qu'un block ?
Un block, c'est comme une fonction, ça veut dire que si
en maths vous écriviez F(x) égal x² + 3, vous avez
l'écrire comme ça, littéralement. Je définis une
variable, j'affecte dans cette variable quoi, un block.
Donc un block, c'est quelque chose qui commence par des crochets.
Là, le block a un argument qui est x et je vais mettre un
core qui est plus 3, x + 3.
Et maintenant, ce block quand je veux l'exécuter, l'application
de fonction par rapport à la définition, là c'était la
définition de fonction, maintenant j'ai l'application de fonction.
Je vais envoyer le message Value au block.
Là, si je fais value 2, x vaudra
2 et mon block va me rendre 5.
Qu'est-ce qu'un block ?
On peut considérer que c'est une fonction anonyme, ça n'a
pas de nom, mais dans la réalité, c'est une clôture lexicale.
On vous expliquera un peu ce que ça veut dire.
Sinon, les blocks sont des vrais objets à part entière.
Je peux les passer comme argument de méthode, je peux les
stocker dans des variables d'instance, ils peuvent être
retournés et ça nous sert, par exemple, pour les triggers
de boutons, pour des callback dans des applications web,
ils sont faits avec des blocks.
L'utilisation des blocks, on l'a déjà vue, par exemple
pour les itérateurs, vous avez eu des blocks.
On les a eus aussi pour les conditions, on a utilisé des blocks dedans.
Il y aura un cours dédié au block.
C'est quelque chose de très élégant, ça a été introduit
dans Eiffel, je l'ai dit récemment, ça a été introduit dans Java 8.
Il y a eu une première version qui a été aussi introduite
dans C Sharp, c'est quelque chose qui est fondamental.
Il se trouve que les blocks sont un élément fondamental
de la syntaxe et du modèle de calcul de Pharo.
Comment est-ce qu'on définit une classe dans Pharo?
Le browser va vous montrer des packages, vous allez avoir
un ensemble de classe à l'intérieur, et ils vous montrent un template.
Vous avez là un template qui dit, par défaut, tu es
ReadObject et puis il faut mettre le nom de la classe.
On va voir ça sur la classe point, par exemple.
Comment est définie la classe point ?
J'ai la classe Object, je lui envoie le message, c'est
aussi un message, le message subclass instanceVariableNames, etc.
Je dis je veux définir la classe point et je lui donne
les variables d'instances X et Y.
C'est juste pour vous montrer que la syntaxe suit
toujours le même modèle avec des messages.
En général, on ne s'amuse pas à l'écrire à la main, l'outil
vous donne le template et puis vous remplissez dedans.
Comment est-ce qu'on définit une méthode?
Les méthodes sont publiques et virtuelles et que, par
défaut, elles retournent Self.
Quand on est dans le browser de code, ce qu'on va voir,
il nous propose aussi un template.
Le template, ça va être le nom de la méthode potentielle.
Un commentaire parce qu'on est des gens bien élevés et qu'on
commande notre code.
Et puis, potentiellement, on va utiliser des variables
temporaires et des expressions. Qu'est-ce que ça donne?
On a déjà vu une méthode factorielle.
Par exemple, je suis dans la classe Integer, je regarde
la méthode factorielle.
Là, j'ai le code de la méthode factorielle avec le nom de
la méthode, son commentaire et le core de la méthode que j'ai définie.
En résumé, qu'avons-nous vu ?
On a vu qu'il y avait trois sortes de messages dans Pharo.
Il y a les messages unaires où il n'y a pas d'arguments,
les messages binaires où les sélecteurs sont tout ce qui
est mathématique et les messages à mots-clés qui sont les
messages où il y a un ou plusieurs arguments, qu'il y a
une priorité, ça veut dire qu'on va exécuter les
parenthèses en premier, puis les messages unaires,
binaires et à mots-clés; et que si on est au même
niveau, on va exécuter de gauche à droite.
Et on a vu toute la syntaxe.
Cette séance est terminée.
Qu'avons-nous vu? La syntaxe est très, très compacte.
Il y a très peu de constructeurs et ils sont tous très expressifs.
Ce sont principalement des messages et des fermetures
lexicales ou des blocks. Il y a trois types de message.
On vous fera faire un petit exercice pour développer un petit langage.
Ça permet de définir des langages qu'on appelle Domain Specific Languages.