Outils pour utilisateurs

Outils du site


cours:informatique:dev:programmation_objet_pharo:205_messages_pour_programmeurs_java

Comparaison entre Pharo et un langage POO comme Java

Dans cette séquence, nous allons aborder Pharo en le comparant avec un autre langage de programmation objet comme Java.

Alors, en Pharo, on ne manipule que des objets. On effectue des traitements uniquement grâce aux messages et à l'assignation de valeurs dans des variables.

La présetation suivante va vous montrer quelques équivalences entre Java et Pharo pour bien comprendre les différences et les ressemblances.

ArrayList<String> strings = new ArrayList<String>();

Ci-dessus un exemple en Java de création d'une nouvelle collection qui contient des chaînes de caractères et l'affectation de cette nouvelle collection dans une variable appelée strings.

Ci dessous voici l'équivalent en Pharo. C'est la même chose, la classe qui gère les collections s'appelle OrderedCollection plutôt qu'ArrayList, mais le comportement de cette collection est le même.

strings := OrderedCollection new.

Alors plusieurs choses sont à noter:

  • Premièrement, new en Pharo, c'est l'envoi d'un message à une classe. Donc, c'est l'envoi du message new à la classe OrderedCollection qui va créer une nouvelle instance de cette collection. En Java, le new est placé devant. Cette construction syntaxique est particulière à l'instanciation d'objets en Java, alors que pour Pharo, c'est juste un envoi de message complètement standard.
  • Il n'y a pas de typage statique en Pharo. Et donc, beaucoup de choses qui apparaissent dans la ligne Java n'apparaissent pas dans la ligne Pharo. On n'a pas le fait que la collection contienne des chaînes de caractères. Et on n'a pas non plus le fait que strings est une collection.

Autre comparaison ou équivalence, cette fois pour la création d'un processus fils. On a un bout de code qu'on voudrait voir exécuter dans un autre processus.

Thread regThread = new Thread(
  new Runnable() {
    @Override
    public void run(){
      this.doSomething();
    }
  });
  regThred.start();

Ci-dessus en Java, on est obligé de créer une nouvelle instance de la classe Thread en lui donnant un objet Runnable en paramètres. Donc, on fait un new Runnable et à l'intérieur comme Runnable est une classe abstraite, il faut définir une méthode qui lui manque. Donc la méthode s'appelle run() et son contenu, c'est le code qu'on veut pouvoir exécuter dans un processus fils: ici, c'est this. doSomething(). Ce code-là, la méthode doSomething() appartient à la même classe que celle où ce code se trouve.

En Pharo, on va pouvoir constater que la syntaxe est beaucoup plus simple:

[ self doSomething ] fork

Et à la fin de l'exemple de syntaxe Java, le regThred.start(); va permettre de lancer le processus fils.

En Pharo, c'est ce qu'on va pouvoir faire grâce au message fork. Donc c'est un message qui est envoyé au block.

Depuis Java 8, la syntaxe s'est bien améliorée.

new Thread(()->this.doSomething()).start();

On voit que le code est beaucoup plus clair en Java maintenant.

Trois types de messages

Pour rappel en Pharo il y a trois types de messages:

" Message Unaires"
5 factorial.
Transcript cr.

"Messages Binaires"
3 + 4.
5 -> 10.

" Messages à mots clés"
Transript show: 'Hello world!'.
2 between: 0 and: 5.
  • Les messages unaires, donc des messages qui ne prennent pas d'arguments qui s'appliquent sur un receveur. C'est le cas de la méthode factorielle qu'on a déjà pu voir. C'est aussi le cas de la méthode cr qui permet d'afficher une ligne vide dans la console.
  • Il y a aussi les messages binaires, donc eux, ils s'appliquent à un receveur. Et ils prennent une valeur en argument. Donc, c'est le cas par exemple des opérateurs mathématiques + qui fait la somme entre 3 et 4. Et là, t , ça permet de créer une paire donc avec une clé et une valeur: donc 5 → 10, ça crée la paire (5, 10);
  • Et le troisième type de messages, ce sont les messages à mots-clés. Donc eux, ils peuvent prendre un, deux, trois ou plus de paramètres. Ce sont des mots qui sont séparés par des deux points. Donc là, le message à mot-clé, c'est show:. Il s'envoie sur l'objet Transcript et il prend un paramètre qui est la chaîne de caractères affichée dans la console. Et dans le deuxième exemple, le message, c'est between: and:. C'est un message articulé en deux mots clés. Il prend deux arguments et il s'applique sur un receveur. Donc, le message between: and: s'applique sur l'objet 2 et prend les arguments 0 et 5.

De nouveau comparons à Java, surtout par rapport au troisième type de message, les messages à mots clés, c'est ceux-là qui ont une grosse différence par rapport à Java.

receiver.keyword1keyword2(arg1, arg2)

En Java, on a un receveur, un point, le nom du message qu'on envoie à l'objet et les arguments séparés par des virgules entre parenthèses.

En Pharo, on exprime la même chose en séparant les différents mots clés du nom de la méthode et en mettant les arguments au milieu.

anObject keyword1: arg1 keyword2: arg2

Si on prends un exemple concret, on souhaite envoyer le message send à un objet postman (facteur) dans le but d'envoyer un courrier à un destinataire. Ci-dessous la syntaxe Java:

postman.send(mail, recipient);

On va la décomposer petit à petit cette syntaxe Java, pour arriver jusqu'à la syntaxe Pharo.

En première étape, on extrait les parties qui sont syntaxiques de Java: le point, les parenthèses, la virgule et le point-virgule. On obtient alors l'expression

postman send mail recipient

Si on transforme ça en phrase pour simplifier la lecture:

postman sent mail to recipient

C'est plus facile à lire, et pour avoir une syntaxe correcte Pharo, on ajoute les deux points. Donc ici, il y a un message:

postman send: mail to: recipient.

Le message send: to: est envoyé à postman et prend deux arguments: le courrier (mail) et le destinataire (recipient).

Les conditions sont des messages

Les structures conditionnelles comme if, else et les boucles do, for, etc. , tout ça, ce sont des mots clés en Java.

En Pharo, on n'a pas ces mots-clés. Ce ne sont pas des mots particuliers qui sont définis au niveau du langage et du compilateur. Ce sont juste des messages qu'on va envoyer à certains types d'objets.

fullName isEmpty
  ifTrue: ['FistnameLastname']
  ifFalse: [fullname']

En Pharo par exemple pour faire un if, on envoie le message ifTrue: ifFalse:, donc c'est un message qu'on envoie à un booléen et qui prend deux blocks en paramètres, un block qui est exécuté si le booléen est vrai et un block est exécuté si le booléen est faux.

De la même façon, les boucles sont juste des messages qu'on envoie à certains types d'objets.

" Equivalents d'une boucle for"
4 timesRepeat: [self doSometing].

0 to: 100 do: [:i| ...].

" 2 0 à 100 par pas de 2 unités"
0 to: 100 by: 2 do: [i:| ...].

" Execute un block sur les éléments d'une liste"
aCollection do: [each| ...].

Pour la première expression de l'exemple, on a l'objet 4, c'est en nombre, on lui envoie le message timesRepeat: avec un block en paramètres. Et la méthode sous-jacente va exécuter le block, le nombre de fois indiqué par le receveur.

De la même façon, le message to: do: est envoyé à un nombre et prend un nombre et un block en paramètres et là, entre la valeur i qui est le paramètre du block va prendre toutes les valeurs entre 0 et 100. De la même façon, le message de to: by: do:, prend en plus, un pas. Et donc i va prendre les valeurs de 0 à 100, mais seulement les multiples de 2, donc 0, 2, 4, 6, etc.

Enfin le message envoyé à une collection est l'équivalent d'une boucle for each en Java et donc va exécuter le block pour chaque élément de la collection. La variable each qui est ici va d'abord prendre la première valeur qui se trouve dans la collection, donc le premier élément de la collection. Le block va être exécuté avec cette valeur each. Puis each va prendre le deuxième élément de la collection. Le block va être exécuté avec cette valeur de each jusqu'à la fin de la collection.

En résumé, il y a trois types de messages:

  1. Les messages unaires;
  2. Les messages binaires;
  3. Les messages à mots-clés.

L'ordre de précédence, c'est:

  • D'abord l'exécution de tout ce qui est entre parenthèses;
  • Ensuite les messages unaires;
  • Ensuite les messages binaires;
  • Ensuite les messages à mots-clés.

Les conditions et les boucles sont juste des messages qui sont envoyés à un certain type d'objets contrairement à d'autres langages comme Java, où des mots clés sont définis par le langage avec des instructions particulières au niveau du compilateur.

cours/informatique/dev/programmation_objet_pharo/205_messages_pour_programmeurs_java.txt · Dernière modification : 2022/07/17 17:21 de yoann