The Hack language : PHP avec un peu de typage statique

Posté par  . Édité par Davy Defaud, BAud, V, chicco, claudex, ZeroHeure, Fabrice Le Fessant, olivierweb et Bruno Michel. Modéré par claudex. Licence CC By‑SA.
Étiquettes :
42
23
mar.
2014
PHP

Facebook vient enfin d’annoncer son nouveau langage de programmation pour le Web, plus d’un an après les premiers déploiements en interne. Baptisé Hack et entièrement interopérable avec PHP, il s’exécute sur leur machine virtuelle maison (HHVM) et permet aux développeurs qui le souhaitent d’ajouter un peu de typage statique dans leur développement PHP. Il semble que pour Facebook, cette dose de typage supplémentaire était devenue indispensable à la maintenance sur le long terme de leur grande base de code.

D’un point de vue performance, la machine virtuelle HHVM utilise des techniques de compilation à la volée, alors que, précédemment, ils utilisaient pour le code en production un compilateur de PHP vers C++. Sur le code du site Facebook lui‐même, ils annoncent un gain de performance de ×10 en temps processeur. De manière plus générale, HHVM vise à terme une compatibilité complète avec PHP 5 — aujourd’hui, 98,5 % de compatibilité —, dans ce cas, ils annoncent un gain de ×2 par rapport à la version actuelle de Zend.

Au delà du gain en CPU dû à la machine virtuelle, cette annonce montre aussi que les questions de fiabilité et le typage statique commencent à faire leur chemin. La complexité croissante des applications Web en font une question centrale pour l’avenir. Même si Facebook a fait le choix conservateur de typer PHP plutôt que tout traduire vers un langage fortement typé (à cause de l’énorme masse de code déjà écrite), il est frappant de noter que le compilateur Hack lui‐même et le tutoriel en ligne sont implémentés en OCaml.

Dans son annonce officielle Facebook remercie d’ailleurs l’équipe Gallium de l’INRIA pour le compilateur OCaml, et le projet Ocsigen (CNRS, INRIA, Université Paris Diderot) pour le compilateur js_of_ocaml. La machine virtuelle HHVM est écrite en C++.

Un peu, ou beaucoup, de typage statique

Ahhh, le typage statique ! Une ceinture de sécurité indispensable pour les uns, une plaie bridant l’imagination pour les autres. Un peu un combat entre une vieille Europe rationnelle et un nouveau monde plus dynamique. Hack propose une alliance originale entre deux modes de développement trop souvent présentés comme incompatibles.

Avec Hack, on préserve l’aspect réactif du développement avec PHP : il suffit d’éditer le fichier source et de rafraîchir son navigateur. Pas de phase de compilation, pas d’erreur de type interdisant l’exécution du programme. Le typeur est à côté, il nous apporte des garanties supplémentaires si on le souhaite et il se fait discret sur les fragments de code que l’on ne veux pas typer. Avec cette approche, on peut écrire le prototype sans se soucier du typage statique, puis progressivement ajouter des annotations de types et découvrir des erreurs de programmation que les tests n’avaient pas encore permis de découvrir.

Et, une fois le programme entièrement typé, que gagne‐t‐on ? À titre personnel, je dirais une certaine sérénité d’esprit et une dose de confiance supplémentaire en son code. Mais, plus concrètement, on peut dire : une meilleure compréhension de l’architecture du code, grâce à l’effort de spécification des types des fonctions et méthodes ; et, quand le nombre de lignes de code augmentera, la garantie que les modifications ne viendront pas trop facilement casser le code existant. Par exemple, changez le type d’une fonction, le typeur vous trouvera immédiatement — car celui de Hack est diablement rapide — toutes les lignes de code à adapter en conséquence.

Le tutoriel interactif, en lien dans la dépêche, contient une introduction au système de types de Hack. Reste à voir, si le système de types choisi sera aussi utilisable avec les styles de programmation différents de ceux utilisés en interne chez Facebook.

Quelques autres nouveautés

En plus d’un mécanisme de transition en douceur vers le monde merveilleux des types statiques, Hack ajoute à PHP deux ou trois petits choses utiles, par exemple (les extraits de code proviennent du tutoriel) :

  • de nouvelles classes pour les collections : Set, Vector, etc. Elles sont génériques pour le typage, leur type est paramétré par le type des éléments qu’elles contiennent ;
  • une syntaxe légère pour les lambda, ce qui est particulièrement pratique pour utiliser les méthodes map ou filter des collections susnommées.
function vector_add1(Vector<int> $v): Vector<int> {
  // Construit un nouveau vecteur en ajoutant 1 à chaque élément du vecteur $v
  return $v->map($x ==> $x + 1);
}
  • de nouvelles primitives pour faciliter la programmation asynchrone : async et await ;
  • l’extension XHP d’écriture de squelettes HTML, avec protection contre les XSS, est disponible par défaut :
function build_paragraph(string $text, string $style): :div {
  return
    <div style={$style}>
      <p>{$text}</p>
    </div>;
}
  • une syntaxe plus concise pour initialiser les champs d’un objet :
/* En PHP */

class PHPPoint {

  private float $x;
  private float $y;

  public function __construct(float $x, float $y) {
    $this->x = $x;
    $this->y = $y;
  }
}

/* En Hack */

class HackPoint {

  public function __construct(
    private float $x,
    private float $y
  ) {}
}

En prime : du multicœur pour OCaml ?

Pour ne pas freiner l’adoption du typage statique dans une communauté qui n’y est pas nécessairement habituée, il faut que le typeur soit rapide, voire très rapide, y compris sur un code de la taille de celui du fameux réseau social. Et pour ça, point de secret, la programmation multicœur peut aider ! Et en fouillant dans le code de Hack — disponible avec une licence BSD sur GitHub — on découvre une bibliothèque OCaml de tas partagé entre plusieurs processus.

Techniquement parlant, le typeur de Hack est un serveur qui tourne en tâche de fond et surveille les dossiers sources, notamment en utilisant inotify sur GNU/Linux. Ce serveur sert uniquement de point d’entrée, il délègue ensuite les vérifications de type et autres mécanismes d’inférence à des processus fils, créés à la demande. L’état global du typeur est maintenu collaborativement par tous les fils dans un tas partagé. Cette architecture collaborative évite aux processus fils de devoir communiquer leurs résultats au serveur maître et évite donc d’y introduire un goulet d’étranglement.

Ce joli exemple pourrait permettre de faciliter grandement la programmation multicœur en OCaml. Espérons que la bibliothèque de Hack sera rapidement proposée à la communauté OCaml, par l’intermédiaire d’un paquet pour opam, le gestionnaire de paquets édité par OCamlPro.

Aller plus loin

  • # PHPPoint

    Posté par  (site web personnel) . Évalué à 10. Dernière modification le 23 mars 2014 à 15:52.

    La classe PHPPoint n'est pas du PHP valide. Comme l'explique l'article, PHP ne supporte pas le typage statique et c'est justement ce qu'apporte Hack. Version corrigée :

        class PHPPoint {
    
          private $x;
          private $y;
    
          public function __construct($x, $y) {
            $this->x = $x;
            $this->y = $y;
          }
        }
    
  • # Encore mieux

    Posté par  (site web personnel) . Évalué à 7.

    L'un des gros avantages de Hack est que par défaut, les types n'acceptent pas de valeur nulle. Impossible donc, à priori, de se manger des exceptions de pointeur nuls en prod: on détecte tout ça à la compilation !

    Enfin je dis ça sans avoir testé, mais si ça marche vraiment comme ça c'est vraiment un plus indéniable par rapport à un bête typage statique qu'on peut trouver ailleurs. Bravo, les gars.

    Et si on accepte une valeur nulle, il faut le dire explicitement en rajoutant un ? devant le type: celui-ci devient alors nullable

    • [^] # Re: Encore mieux

      Posté par  . Évalué à 2.

      Cool ça, pouvoir rendre nullable les types scalaires, c'est un truc que j'avais adoré avec C# :)

      • [^] # Re: Encore mieux

        Posté par  . Évalué à 2.

        Ça revient a passer un pointeur vers une valeur au lieu d'une valeur, donc c'est moins efficace, je ne vois pas trop l'intérêt..
        Tu peux expliquer?

        • [^] # Re: Encore mieux

          Posté par  . Évalué à 3.

          Pouvoir avoir une valeur mauvaise (et pas devoir considérer 0 ou -1 sauf quand finalement c'est pas possible).

          Faut pas croire les valeurs nulles (ou l'utilisation de trucs comme Optional) sont utiles quand on a pas d'inférence de type.

          Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

        • [^] # Re: Encore mieux

          Posté par  . Évalué à 1.

          En C#, les types nullables sont des structures, et donc des types valeurs, pas référence.
          Je les utilisais principalement pour pouvoir considérer le cas ou une valeur était nulle en base, c'était plutôt pratique.

  • # Vieille Europe?

    Posté par  . Évalué à 2.

    Je n'ai vraiment pas compris cette histoire de combat entre l'Europe et le nouveau monde. Vraiment pas. Ça sent même furieusement le hors-sujet.

    • [^] # Re: Vieille Europe?

      Posté par  . Évalué à 3.

      Historiquement ça avait peut-être un sens (je pense à SmallTalk et Alan Kay qui n'aime toujours pas le typage statique), mais bon avec Haskell maintenant c'est totalement dépassé/faux de toute manière.

      • [^] # Re: Vieille Europe?

        Posté par  . Évalué à 2.

        Heu, historiquement, le typage statique est tout aussi présent dans le nouveau monde. Tiens pouf un exemple comme ça en passant, les spécifications steelman qui demandaient du typage fort. Ces spécifications ont donné Ada… proposé par Jean Ichbiah.

        D'ailleurs c'est quoi le nouveau monde aujourd'hui?

        Enfin, bref, je pinaille mais ce genre de comparaison sur les pays à l'emporte-pièce m'énerve un peu… Passons…

  • # Ça reste du PHP

    Posté par  (site web personnel) . Évalué à 1.

    Un langage qui répond true à la question md5('240610708') == md5('QNKCDZO'), je ne pense pas que ça vaille la peine d'investir du temps dessus. En 10 ans, Facebook aurait eu le temps de réécrire son site web depuis zéro vu les ressources qu'ils ont.

    • [^] # Re: Ça reste du PHP

      Posté par  (site web personnel, Mastodon) . Évalué à 2.

      Plutôt que de conclure qu'ils sont dans l'erreur, peut-être que tu devrais accepter que le plus gros site web utilises PHP pour le templating de ses pages web ? Et que ça marche bien.

      • [^] # Re: Ça reste du PHP

        Posté par  . Évalué à 8.

        Et que ça marche bien.

        Et que, vu ce gros "Hack", ça marchait bien (pour eux, et plutôt plus ou moins ?) justement, non ;-?

        • [^] # Re: Ça reste du PHP

          Posté par  (site web personnel, Mastodon) . Évalué à -2.

          Ce n'est pas parce qu'un système marche bien qu'il ne peut aller mieux. Le langage en lui-même semble satisfaisant, avec son workflow qui permet d'avancer rapidement quand on prototype, puis conçois, puis finalise un produit.

          FB voulait gagner en performance pour économiser de l'argent et en facilité pour gagner du temps. Bref, plutôt que d'inventer un langage caduque comme JavaScript, ils ont gardé un langage pas trop mal, simple, qu'il est possible d'évoluer facilement en interne.

    • [^] # Re: Ça reste du PHP

      Posté par  (site web personnel, Mastodon) . Évalué à 3.

      ah bah oui, mais bon, faut savoir les avantages/inconvénient d'un langage non typé, savoir les rêgles de conversion implicites du langage etc… Bref, avant de critiquer un langage, on l'apprend.

      md5('240610708') === md5('QNKCDZO')
      Tout de suite, ça va mieux….

      • [^] # Re: Ça reste du PHP

        Posté par  . Évalué à 5.

        Cependant, md5 retourne normalement des chaînes de 32 caractères.
        Et les 2 variables ont bien le même type, == devrait donc retourner false également.

      • [^] # Re: Ça reste du PHP

        Posté par  . Évalué à 1.

        Pas chez moi :

        $ php --interactive
        Interactive shell
        
        php > var_dump(md5('titi') == md5('toto'));
        bool(false)
        php > ^C
        $ php -v
        PHP 5.5.10 (cli) (built: Mar  5 2014 17:41:10) 
        Copyright (c) 1997-2014 The PHP Group
        Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
        • [^] # Re: Ça reste du PHP

          Posté par  (site web personnel) . Évalué à 10.

          Les valeurs n'étaient pas données au hasard.

          Pour un cas peut-être plus parlant :

          ~$ php -r "var_dump('0e4' == '0e5');"
          bool(true)

          ~$ php -r "var_dump('0e4' === '0e5');"
          bool(false)

          Le coeur du problème c'est qu'une chaîne commençant par un chiffre est traitée par l'opérateur '==' comme un nombre, ce qui est loin d'être évident de prime abord, et peut donc entraîner de grosses failles de sécurité dans le cas de comparaison de hash (le problème n'était bien évidemment pas lié à MD5…).

          alf.life

      • [^] # Re: Ça reste du PHP

        Posté par  . Évalué à 5.

        Salut, je ne fais pas de PHP donc je suis un peu surpris : si à chaque fois la réponse est « il suffit d'utiliser === », pourquoi est-ce que == continue d'exister en PHP ? Est-ce qu'il ne serait pas raisonnable de le déprécier ?

        • [^] # Re: Ça reste du PHP

          Posté par  (site web personnel) . Évalué à 6.

          Complètement. Cet opérateur est une belle saloperie, qu'ils conservent pour garder la compatibilité.
          Pour moi le comportement actuel de "===" devrait être le comportement par défaut de "==", tandis que le comportement approximatif de '==' devrait être relayé à un opérateur spécifique, genre "~=" pour dire que «c'est à peu près équivalent mais pas vraiment».

          Le hic, c'est que s'ils nous pondent un PHP 7 qui corrige ça, combien de personnes vont vouloir rester en PHP 5.* pour pouvoir faire tourner les vieux trucs qui reposent sur des âneries ?
          Un peu comme Python 2.* qui reste super utilisé quoi :D

          En attendant t'as ce genre de pièges qui traîne, et il faut faire très attention.

          alf.life

          • [^] # Re: Ça reste du PHP

            Posté par  . Évalué à 3.

            Il pourrait ajouter une option de compilation à l'interpréteur pour le faire (h)urler quand il voit ça, non ?
            Sinon existe-t'il des analyseurs statiques capables de détecter ça ?

            Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

          • [^] # Re: Ça reste du PHP

            Posté par  . Évalué à 3.

            Le hic, c'est que s'ils nous pondent un PHP 7 qui corrige ça, combien de personnes vont vouloir rester en PHP 5.* pour pouvoir faire tourner les vieux trucs qui reposent sur des âneries ?

            Je serais tenté de dire que je m'en fiche, ça semble être une position plus défendable que « baaah il suffit de connaître le langage ». Par ailleurs ça a aussi l'air d'être une transition plus facile que le passage Python 2 -> Python 3.

        • [^] # Re: Ça reste du PHP

          Posté par  . Évalué à 1. Dernière modification le 24 mars 2014 à 20:19.

          Étonnament, j'ai découvert il y a pas longtemps que c'était la même chose en Javascript. Il était très déconseillé d'utilisr == mais plutôt === partout, pour éviter ce genre de problème de castage implicite.

    • [^] # Re: Ça reste du PHP

      Posté par  . Évalué à -8.

      Ouais, je sais pas si c'est judicieux de juger un langage sur un tel bug.
      As-tu remonté ce bug?
      A-t-il été corrigé?

      En tout cas si tu comparais avec l'opérateur ===, il te répond bien false

      PS: en même temps, md5… ça fait longtemps que c'est déconseillé vu le fort risque de collision.

      • [^] # Re: Ça reste du PHP

        Posté par  (site web personnel) . Évalué à 6.

        Its not a bug, its a feature.

        Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141

  • # The Hack language : PHP avec un peu de typage statique ?

    Posté par  . Évalué à 6. Dernière modification le 25 mars 2014 à 14:42.

    Je pense que c'est une excellente initiative. Je surpris de cette nouvelle en fait. J'aurais pensé que cela émanerait, un jour, du core php team.

    Je dois bien dire, que la mise à jour de la syntaxe présenté dans les exemple de la dépêche est vraiment sympa.

    xhp est très très intéressant à lire https://github.com/facebook/xhp

    Je ne saurais dire si l'idée est vraiment géniale en pratique.
    Mais ce mariage entre le code php et html, est très surprenant. Inspiré, il me semble par l'expérience de la pratique, et des nécessité de maintenance très concrètes. J'aime beaucoup.

    http://docs.hhvm.com/manual/en/hack.async.php
    L'ajout de async et await laisse songeur quand aux cas pratique, cet ajout est très intéressant.

    http://docs.hhvm.com/manual/en/hack.shapes.php
    http://docs.hhvm.com/manual/en/hack.tuples.php
    Les tuples et les shapes sont aussi vraiment de bonnes idées, cela permet d’éliminer beaucoup de source code simplement et rapidement.

    http://docs.hhvm.com/manual/en/hack.overrideattribute.php
    Même le nouveau mot cléf override est très séduisant et semble très agréable à utiliser car c'est purement déclaratif dans les héritiers.
    Je n'arrive pas à me souvenir des règles d'utilisation ce genre de chose dans d'autre langages tels que c#, java c etc. je comparerais donc pas.
    Mais cela me plait beaucoup de déclarer la contrainte à l'usage et par l'usage.

    En fait je pense que fb a réalisé un super boulot………… Ou comment fb m'à surpris.

    Il me semble qu'il fournisse là une belle amélioration pour faire de php le langage de middle-ware par excellence.

    Je me dois d'applaudir des deux mains.

    Après oui cela reste du php, en d'autres termes nous continuerons décrire,
    hack !== php, mais aussi, hack == php

    • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

      Posté par  . Évalué à 2. Dernière modification le 26 mars 2014 à 15:55.

      Facebook a des problemes avec le codage en PHP, alors ils inventent une version java-ifiee de PHP!

      En fait c'est surtout quand j'ai vu les nouveaux types Vector, Set, Map et Pair que je me suis dit ca, en plus des autres changements :)

      Bref, les principales differences entre Hack et Java sont: pas de compilation pour Hack, l'utilisation de XHP qui rend le templating plus agreable et aussi plus sur car type.
      A part ca, Java savait deja faire beaucoup de chose que Hack apporte au monde PHP.

      • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

        Posté par  . Évalué à 2. Dernière modification le 26 mars 2014 à 16:16.

        Les développeurs web étant rarement payés à la ligne il y a peu d’intérêt à Java dans ce monde là.

      • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

        Posté par  . Évalué à 2.

        En fait c'est surtout quand j'ai vu les nouveaux types Vector, Set, Map et Pair que je me suis dit ca, en plus des autres changements :)

        Non mais n'importe quoi. L'un des gros apports de hack c'est de rendre des types non-nullables, tu l'a ça en Java ?

        Java utilise massivement l'injection de référence, chose impossible en PHP (parce qu'on ne peut pas manipuler de chargeur de classe comme dans la JVM).

        PHP possède une dynamicité que Java n'a pas (comme la possibilité d'avoir une méthode « par défaut » quand on appel une méthode sur un objet avec le mauvais nom - moche sur bien des aspects, pratique pour faire des proxy).

        Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

        • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

          Posté par  . Évalué à 2.

          L'un des gros apports de hack c'est de rendre des types non-nullables, tu l'a ça en Java ?

          Je l'attendais celle la.
          Oui, par l'utilisation de @NonNull qui va bien, avec l'IDE qui va bien. Et malheureusement ce n'est pas intégré au langage.

          Java utilise massivement l'injection de référence, chose impossible en PHP (parce qu'on ne peut pas manipuler de chargeur de classe comme dans la JVM).
          Et alors c'est bien ou mal selon toi?

          PHP possède une dynamicité que Java n'a pas (comme la possibilité d'avoir une méthode « par défaut » quand on appel une méthode sur un objet avec le mauvais nom - moche sur bien des aspects, pratique pour faire des proxy).
          Tout a fait, d'ailleurs je parlais des ajouts de Hack par rapport a ce dont dispose déjà Java.
          Quoique les proxy existent aussi en Java même s'ils ne sont pas très dynamique puisque leur utilisation suppose l'existence d'une interface.

        • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

          Posté par  . Évalué à -1.

          PHP possède une dynamicité que Java n'a pas (comme la possibilité d'avoir une méthode « par défaut » quand on appel une méthode sur un objet avec le mauvais nom - moche sur bien des aspects, pratique pour faire des proxy).

          Bah en deux coups de cuillère à peau avec un peu de réflexivité on fait la même chose moche

          • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

            Posté par  . Évalué à 2.

            Non. C'est possible, oui, en 2 coups de cuillère à pot, non. Il y a une différence (en terme de coût, en terme d'implémentation) entre avoir une méthode appelé quand aucune autre à matchée et générer dynamiquement une classe pour que ces instances proxyfient un objet. Plus généralement, si tu veux faire de la délégation à plusieurs objet et que certains ont le même profile de méthode c'est encore un peu moins amusant.

            Ou alors oui c'est 2 coups de cuillère, mais en PHP ou en groovy c'est « automatique » ? « inné » ? suffisamment simple pour qu'on arrête de se perdre dans l'implémentation et qu'on s'intéresse simplement à ce que l'on fait et pourquoi est-ce qu'on le fait ?

            Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

            • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

              Posté par  (site web personnel, Mastodon) . Évalué à 1.

              Voici la complexité d'un proxy naïf :

              <?php
              
              class proxy
              {
                  private $targets = array();
              
                  public      function __construct(array $targets = array())
                  {
                      $this->targets = $targets;
                  }
              
                  public      function __call($method_name, $args)
                  {
                      foreach($this->targets as $target)
                          if(method_exists($target, $method_name))
                              return call_user_func_array($target, $method_name);
              
                      throw new exception(sprintf('Method \'%s\' doesn\'t exist', $method_name));
                  }
              }
              
              class first
              {
                  public      function first()
                  {
                      return 'first';
                  }
              }
              
              class second
              {
                  protected   function second()
                  {
                      return 'second';
                  }
              }
              
              $proxy = new proxy(array(new first, new second, new third));
              assert('first' === $proxy->first());
              
              try
              {
                  $proxy->third();
                  assert(false);
              }
              catch(exception $e) { }
              
              $proxy->second(); // This trigger a fatal error
              assert(false);
            • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

              Posté par  . Évalué à 3. Dernière modification le 27 mars 2014 à 09:02.

              Non. C'est possible, oui, en 2 coups de cuillère à pot, non.

              Non c'est pas possible, quelque soit le nombre de cuillère à pot.

              Tu peux effectivement essayer d'implémenter call, __gettattr ou missingMethod en Java. C'est par exemple ce que fait PyObject dans Jython qui wrap tout les objets Java qui sont visibles côté Python. Bon AFAIK l'implémentation des méthodes fournies par PyObject tu ne peux pas la modifier et surement pour une très bonne raison.

              Mais tu ne pourras jamais appeler ce mécanisme depuis Java, typage static oblige. D'ailleurs c'est pour ça que si tu veux manipuler un objet Python depuis Java il faut qu'une interface Java soit définie.

              Après tu peux penser faire du Canada-dry avec une méthode unique doit et un varargs d'Object en paramètre. Mais la c'est juste du mauvais goût et le pire des deux mondes. Dan la vraie vie tu vas utiliser un patron du type multi-dispatch.

          • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

            Posté par  . Évalué à 3.

            Bah en deux coups de cuillère à peau avec un peu de réflexivité on fait la même chose moche

            Non.

            Ce que te permet facilement de faire Java c'est un proxy pour une interface déjà existante. L'exemple classique, et qui est généralement une très mauvaise idéee, c'est un système de RPC qui veux faire croire à une API locale. Tu vas automatiquement générer des proxy sur des interfaces et masquer tout le bordel à l'utilisateur. Pour lui il manipule un POJO.

            Ce que permettent de faire les langages dynamiques c'est de faire un proxy pour n'importe quoi dont la signature est totalement inconnue même à l'exécution (getattr en Python, methodMissing en Groovy etc.). Le proxy fait simplement des transformations syntaxiques bêtes et méchantes à partir du nom de méthode et des arguments passés puis effectue une action, il ne connait rien de l'API sous jacente et n'expose rien. L'exemple typique c'est client pour une API web. À partir du moment ou elle est régulière, ça marche. Ça a des avantages et des inconvénients par rapport à fournir une "vraie" API côté client. Mais dans tout les cas c'est pas faisable en Java.

            • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

              Posté par  (site web personnel) . Évalué à 2.

              http://www.javaroots.com/2013/03/understanding-dynamic-proxy-spring-aop.html ?

              Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

              • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                Posté par  . Évalué à 3.

                Oui, mais spring ça ne fait pas parti du langage. Là tu as affaire à quelque chose de monstrueux (en rapport à ce qui est fait ailleurs), tu sort des mécanismes d'AOP, c'est puissant mais c'est extrêmement complexe en rapport avec la solution PHP.

                Pour moi dire faire des dire « en Java faire des proxy ça se fait en 2 coups de cuillère à pot », ça veut dire que le langage et/ou sa bibliothèque standard me permet de le faire facilement pas « avec tel outil on peut le faire ».

                Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

              • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                Posté par  . Évalué à 2.

                Non, toujours non et ce sera toujours non.

                En Java tu as un typage static. Tu peux creer des proxy autour d'interfaces CONNUES.

                Dans un langage dynamique tu peux evidement creer ce type de proxy. Basiquement en Python:

                class wrapper:
                    def __init__(self, object):
                        self.wrapped = object
                    def __getattr__(self, attrname):
                        print('Trace:', attrname)
                        return getattr(self.wrapped, attrname)
                

                Mais tu peux aussi faire un proxy sur quelque chose qui n'est pas decrit dans ton langage. Par exemple quand tu ecris un client rest generique tu n'as aucune idee de ce qui existe vraiment dans l'API et ce n'est jamais decrit. Tu as juste un mapping dynamique 'GET /foo/bar?p=v' en client.get.foo.bar(p=v).

                Ce type de construction tu ne pourras jamais le faire en Java.

                • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                  Posté par  (site web personnel) . Évalué à 2.

                  En Java tu as un typage static. Tu peux creer des proxy autour d'interfaces CONNUES.

                  Dans l'exemple que j'ai donné, le proxy est créé par réflexivité. Il ne connaît pas les interfaces, elles peuvent même chargées à l'exécution, voire même créé de zéro en générant du code.

                  Tu as juste un mapping dynamique 'GET /foo/bar?p=v' en client.get.foo.bar(p=v).

                  On fait plutôt ça par annotations:

                  @Path("/tribune")
                  public class TribuneRestServer {
                  
                      @GET
                      @Path("/plonklist")
                      @Produces(MediaType.APPLICATION_JSON)
                      public String getPlonkList() {
                          (...)
                      }
                  }
                  

                  Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

                  • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                    Posté par  . Évalué à 1.

                    Qu'est ce que tu ne comprends pas dans typage dynamique et dans la phrase originale qui était " (comme la possibilité d'avoir une méthode « par défaut » quand on appel une méthode sur un objet avec le mauvais nom - moche sur bien des aspects, pratique pour faire des proxy)." ?

                    Je comprends parfaitement ce que tu m'expliques. Par contre tu ne comprends juste pas qu'à chaque fois ce que tu prends comme exemple ne fait qu'implementer automatiquement un proxy à partir d'une interface Java définie (il existe des dizaines de variantes possible). Derrière il te faut une Method ou un MethodHandle.

                    Si ca peut t'aider à comprendre regarde du côté de la doc de Groovy:
                    http://groovy.codehaus.org/Using+invokeMethod+and+getProperty
                    http://groovy.codehaus.org/Using+methodMissing+and+propertyMissing

                    Si tu veux comprendre comment ca s'implemente sur une JVM regarde ca: http://www.oracle.com/technetwork/articles/javase/dyntypelang-142348.html

                    Maintenant non cette fonctionalité ne peut pas exister en Java.

                    • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                      Posté par  (site web personnel) . Évalué à 2.

                      Par contre tu ne comprends juste pas qu'à chaque fois ce que tu prends comme exemple ne fait qu'implementer automatiquement un proxy à partir d'une interface Java définie

                      Tu peux charger du code dynamiquement ou en générer. Le proxy est créé à l'exécution, l'interface même peut être créé à l'exécution, le code du proxy peut être créé à l'exécution. C'est sacrément dynamique.

                      Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

                      • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                        Posté par  . Évalué à 1.

                        Tu ne peux toujours pas écrire ton code client c'est sacrement utile ;)

                        Juste au passage ce que tu décris, je l'ai fait pendant 5 ans pour génerer des proxy type RMI à runtime pour un système RPC (et oui c'est une mauvaise idée).

                        Ce que tu décris c'est générer des Proxy pour une interface Java (que ce soit via Proxy ou en générant du bytocde à runtime c'est juste la modalité qui change) et éventuellement générer du code avant pour créer ton interface. Tout cela existe et est pratique.

                        Mais pourquoi tu ne veux juste pas voir que ce dont on parle ne peut pas exister en Java car c'est antinomique avec un langage statiquement typé. Personne ne dit que tu as absolument besoin de cette fonctionalité ou qu'il faut en abusé. Mais c'est un fait __getattr__, __call ou methodMissing tu ne peux pas avoir de concept similair en Java.

                        J'ai vraiment l'impression que tu ne comprends pas la différence. Tu focalises sur une utilisation possible du mécanisme qui a été donnée en exemple mais on peut beaucoup d'autre chose avec. Prend le temps de lire les docs et d'essayer de t'en servir. Tu devrais finir par comprendre.

                        • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                          Posté par  (site web personnel) . Évalué à 3.

                          Personne ne dit que tu as absolument besoin de cette fonctionalité ou qu'il faut en abusé. Mais c'est un fait getattr, __call ou methodMissing tu ne peux pas avoir de concept similair en Java.

                          Je pensais qu'on parlait d'un besoin (faire des proxys dynamiques pour enrichir des comportements d'un objet à l'exécution) pas de techniques spécifiques à Python. Je n'ai pas bien compris ce qu'il y a de si génial dans getattr, __call ou methodMissing… Ce sont des solutions à quels problèmes?

                          Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

                          • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                            Posté par  . Évalué à 1.

                            Faire des pseudos interfaces à des choses non connues à la compilation voir à l'exécution (il faut essayer pour savoir).

                            Ca peut s'utiliser pour créer des DSL, des fonctionalité d'ORM, de metaprogramming, du sucre syntaxique (BeautifulSoup l'utilise par exemple pour permettre un accès via des pseudo membre aux élements de la data structure) etc.

                            Ta vision est bornée a un faire un proxy sur un type d'un langage statique. Et encore plus borné que Java n'étant pas fonctionnel pour un sou et n'ayant pas de fonction du premier ordre tu es obligé d'utiliser des Proxy et de l'AOP crado. Chaque plate forme à son idiome et tu ne concois et n'écris pas les choses de la même façon selon l'outil que tu as en main. Pour revenir au commentaire original "_PHP possède une dynamicité que Java n'a pas (comme la possibilité d'avoir une méthode « par défaut » quand on appel une méthode sur un objet avec le mauvais nom - moche sur bien des aspects, pratique pour faire des proxy)._" c'est vrai. En soit ce n'est pas une critique de Java c'est une constatation. Tu peux faire bien plus de chose avec des langages dynamique (dont un bon nombre de choses horribles).

                      • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                        Posté par  . Évalué à 2.

                        interface même peut être créé à l'exécution

                        Pas bien utile. Une interface ça sert de « contrat » (pas taper…).

                        Ton proxy tu veux probablement en faire quelque chose, appeler des méthodes sur lui, pour ça il faut que tu connaisse son type ou au moins son interface (c'est ça qui va te permettre de savoir s'il possède la méthode que tu souhaite appeler), si l'interface n'existe pas à la compilation, tu ne peux pas écrire le code qui appel les méthode de ton proxy avant la compilation.

                        Si tu en arrive à générer ton code qui appel le proxy (qui lui même appel la cible du proxy) dynamiquement est-ce encore du java ou un interpréteur écris en Java ?

                        Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

                        • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                          Posté par  (site web personnel) . Évalué à 3. Dernière modification le 28 mars 2014 à 09:27.

                          Pas bien utile

                          Anéfé, mais l'idée était de montrer que même un langage statique peut être très dynamique. Je n'ai pour l'instant jamais vu un cas d'usage qui justifie le typage dynamique.

                          Facebook propose un "php typé" avec hack, Google et Microsoft des "javascrits typés" avec Dart et Typescript, Python aussi s'y mets avec cette PEP

                          Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

            • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

              Posté par  . Évalué à -1.

              Mais dans tout les cas c'est pas faisable en Java.

              getClass, getMethod, invoke ?

              • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

                Posté par  . Évalué à 5.

                Non l'équivalent de getMethod serait: monObjet.maMethod (note l'absence de parenthèse). Method c'est juste "une jambe de bois" par ce que les fonctions ne sont pas d'ordre supérieur.

                Encore une fois oui ce genre de mécanisme est implémentable de manière efficace sur la JVM, c'est invokeDynamic + MethodHandle. Non ce n'est pas utilisable en Java. Tu ne pourras jamais écrire monObject.pzoeizjdfc si pzoeizjdfc n'existe pas dans la hierarchie de classe de ton objet.
                Un autre exemple: explication de comment JRuby fonctionne par Charles Nutter.

                J'arrête la. Il y a des liens dans mes différents posts si tu veux chercher à comprendre la différence.

      • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

        Posté par  . Évalué à 3.

        Facebook a des problemes avec le codage en PHP, alors ils inventent une version java-ifiee de PHP!

        Ce n'est pas le sentiment que j'ai. Alors oui il y à un existant, et cet effort est probablement celui qui répond bien à toutes es contraintes.
        Plutôt que de changer de langage, ce qui serait extrêmement coûteux dans leurs cas apparemment.

        Mais, comme tu le rappels, il y à xhp. Qui fait plus que du simple templating. Avec leurs systèmes tu as des contraintes, de l'héritage vertical, et peut être horizontal (si tant est que ce soit utile) à vérifier.
        Ce qui intéressant aussi c'est que pour une fois, il me semble, on vient de faire le total opposé de la doctrine mvc. Ils ont mis le code de présentation dans le langage de développement (pas nécessairement la couche métier, hein).
        Ce qui me fait dire qu'ils n'ont pas simplement cherché à patcher le langage pour en améliorer la maintenance, ou copier ce qui c'est fait ailleurs, ils ont vraiment fait évoluer le langage.

        En fait je pense qu'ils retournent à ce qu'était php au départ, un pur langage de template.
        Sauf que là on à un langage de template dopé au stéroide1000, qui ne fait que cela, et qui le fait bien.
        Et en plus tu peux faire d'autres trucs à côté, car on ne sait jamais.

        Les types que tu cites, je n'en vois pas trop l’intérêt moi non plus.
        Maintenant voici ce qu'ils en disent :

        Given the wide range of functionality offered by PHP arrays, they can be used to mimic common specialized collection types such as vectors, dictionaries, and sets. So why extend HHVM with its own collection classes and functionality? One key reason is code clarity. It's not always clear in PHP how an array is being used, or what the types of the keys and values are. This makes it harder to confidently make changes to a larger codebase without introducing subtle bugs. Another key reason is PHP array performance. Generally speaking, it is impossible to know with certainty if a PHP array is going to be used as a vector, as a map, as a set, etc., and as such the code generated by HHVM and associated data structures are more complex. Also, PHP arrays are copy-on-write. This means that programmers must use PHP references when they don't want the array to be copied, and using PHP references generally degrades code performance. Enter the Hack collection classes.

        Finalement, Java sait tout faire, ou presque, il me semble. Mais apparemment ce n'est pas suffisant.

        • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

          Posté par  . Évalué à 3. Dernière modification le 28 mars 2014 à 14:12.

          Oui j'ai la même analyse que toi sur le retour de PHP vers un langage de templating.
          C'est out a fait intéressant.

          Je n'ai pas dit que les nouveaux types étaient inutiles.
          Je suis au contraire convaincu que ne pas les avoir est une mauvaise idée.
          Ils rendent la compréhension du code plus claire et améliorent les performances en étant dédiés a une tache et une seule.

          En plus si je regarde Java, il y a plusieurs implémentations de List, Set ou Map qui répondent toutes a des besoins particuliers.
          Par exemple, je n'aime pas le choix de Go de forcer une et une seule implémentation de Map ou List.

    • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

      Posté par  . Évalué à 2.

      http://docs.hhvm.com/manual/en/hack.overrideattribute.php
      Même le nouveau mot cléf override est très séduisant et semble très agréable à utiliser car c'est purement déclaratif dans les héritiers.
      Je n'arrive pas à me souvenir des règles d'utilisation ce genre de chose dans d'autre langages tels que c#, java c etc. je comparerais donc pas.
      Mais cela me plait beaucoup de déclarer la contrainte à l'usage et par l'usage.

      En Java, le mot-clé @overrideest une annotation
      Ex :

      public abstract class Felin extends Animal {
      
              // Surcharge de la méthode Animal.deplacement()
              @Override
              void deplacement() {
                      System.out.println("Je me déplace seul !");
              }
      
      }
      • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

        Posté par  . Évalué à 2.

        Et en C#, en plus du mot clef override, il y a le mot clef new qui permet de masquer la méthode "ancêtre". Dans le cas d'un appel à la méthode virtuelle d'une classe de base, une méthode définie avec le mot clef new dans une classe fille ne sera pas appelé, c'est la méthode de la classe de base qui sera retenue.

        • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

          Posté par  . Évalué à 1.

          Et c'est bien ça ? Je veux dire c'est quelque chose de positif ?

          Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

        • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

          Posté par  . Évalué à 2.

          Tu aurais un exemple concret ?
          Et le mot-clé new il n'est pas déjà utilisé pour l'instanciation d'un objet ? Je veux bien croire qu'il ne peut y avoir de confusion pour le parseur, mais cette réutilisation d'un mot-clé pour un usage totalement différent, ça me parait bizarre…

          • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

            Posté par  . Évalué à 1.

            Tu aurais un exemple concret ?

            à part une pile d'héritages foireuse je ne vois pas trop, ça reste une forme de liberté assez subtile

            Et le mot-clé new il n'est pas déjà utilisé pour l'instanciation d'un objet ? Je veux bien croire qu'il ne peut y avoir de confusion pour le parseur, mais cette réutilisation d'un mot-clé pour un usage totalement différent, ça me parait bizarre…

            new ne sera jamais ambigü, les deux contextes étant bien distincts, non ? et niveau réutilisation C++ est bien pire dans le genre

      • [^] # Re: The Hack language : PHP avec un peu de typage statique ?

        Posté par  . Évalué à 2.

        Ah enfin un commentaire en rapport avec mon post AHAH

        OK, c'est clair, c'est tout aussi simple, merci. Et pour la même raison je trouve cela très pratique.

        Aussi je commence sérieusement à me demander ce qu'il se passe dans le core php team.

        Le langage subit des mises à jours, mais rien de très fondamental, ça donne le sentiment de patiner : /

  • # Et pourquoi pas...

    Posté par  . Évalué à 1.

    Et pourquoi ne pas créer un langage from scratch ?
    Vivement vendredi :-)

  • # La même chose en python ?

    Posté par  (site web personnel, Mastodon) . Évalué à 1.

    Si python proposait un tel typage statique je n'aurai plus aucun doute quant au langage à adopter pour mes projets…

  • # Merci!

    Posté par  . Évalué à 3.

    Tout d'abord, je voulais simplement vous remercier pour avoir écrit cet article.

    Je pense effectivement qu'il serait intéressant de faire une librairie générique du tas partagé que nous utilisons. Toutefois, je voudrais recommander la plus grande prudence. Le code ne fonctionnera pas tel quel sur ARM (il manque des barrières), et même sur Intel, les primitives ont été écrites pour fonctionner spécifiquement dans le cadre de Hack. Pour ne donner qu'un exemple, l'algorithme de "compaction" ne fonctionnera pas de manière concurrente. J'ai laisser un commentaire assez clair en tête du fichier pour les curieux ;-)

    • [^] # Re: Merci!

      Posté par  . Évalué à 4.

      julienv, comme Julien Verlaguet ?

      J'aime bien linuxfr qui nous met au contact direct des auteurs du code :)

      Tu as un lien sur le fichiers dont tu parles? J'ai regarde les commits de ton user sur la page github du projet, mais je ne l'ai pas trouve.

      Comme je suis curieux je te pose une petite question: sur quelle partie de Hack travailles-tu ?
      Es-tu responsable de l'utilisation de OCaml et js_of_ocaml?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.