Sortie de Vala 0.7.6

Posté par  . Modéré par Nÿco.
Étiquettes :
22
20
sept.
2009
Gnome
Pour rappel, Vala est un langage de programmation orienté objet dont la syntaxe ressemble beaucoup à celle de C#, mais adapté au système GObject utilisé par Gtk et GNOME.
Contrairement à C# le code n'est pas interprété par une machine virtuelle, c'est un langage compilé. Pour être plus précis, le compilateur génère de manière intermédiaire du "C", ce qui permet à un logiciel programmé en Vala d'utiliser facilement des bibliothèques en C, ou à l'inverse à une bibliothèque programmée dans un langage qui s'interface avec du "C", de faire appel à une bibliothèque programmée en Vala.

Dès le début ce nouveau langage apportait nativement des fonctionnalités très intéressantes comme :
  • Les interfaces
  • Les propriétés (spécifique aux GObjects)
  • Les signaux (démocratisé par Qt)
  • Les expressions Lambda
  • Les classe génériques
  • La gestion assistée de la mémoire
  • La gestion des exceptions

Cette nouvelle mouture apporte deux grosses nouveautés :
  • Les closures (version plus puissante des expressions Lambda)
  • Les appels asynchrones

Plus d'informations dans la suite de la dépêche. Jürg Billeter et Raffaele Sandrini, les développeurs de vala fournissent quelques exemples des deux nouveautés, dont voici une retranscription en français quelque peu remaniée (cf blog pour la version anglaise) :

Closures

Bien que Vala supporte les expressions lambda depuis longtemps, elles ne permettaient pas d'accéder aux variables locales en dehors du contexte de leur construction.
Avec la version 0.7.6 celà a changé puisque vous pouvez accéder et modifier toutes les variable locales dans les expressions lambda, ce qu'on appelle les closures.
Nous espérons quelles seront utiles pour simplifier l'écriture des gestionnaires de signaux (slots en Qt), comme dans l'exemple ci-dessous :
  void main (string[] args) {
    Gtk.init (ref args);

    var window = new Gtk.Window (Gtk.WindowType.TOPLEVEL);
    window.set_default_size (300, 50);
    window.destroy.connect (Gtk.main_quit);

    var button = new Gtk.Button.with_label ("Click me!");
    button.clicked.connect (() => {
      window.title = "Closures in Vala";
    });

    window.add (button);
    window.show_all ();

    Gtk.main ();
  }


Vous pouvez même écrire des expressions lambda récursives :
  delegate int Func (int i);

  void main () {
    Func fib = null;
    fib = (i) => (i <= 1) ? i : (fib (i - 2) + fib (i - 1));

    for (int i = 0; i < 10; i++) {
       message ("%d", fib (i));
    }
  }


Méthodes asynchrones

Pour simplifier l'écriture de code faisant appel à des fonctions asynchrones nous avons eu l'idée d'intégrer les méthodes asynchrones directement dans le langage.
Les méthodes asynchrones sont fréquemment utilisées dans les API d'entrée/sortie telles que GIO et D-Bus. En général, écrire des programmes asynchrones est considéré difficile, car l'on en arrive vite à écrire des suites de callbacks et l'on perd facilement la trace du flot d'exécution du programme.
La gestion expérimentale des méthodes asynchrones a été développée depuis longtemps en vala. Cependant, cette mise en œuvre relevait plus du prototype qu'autre chose. Bien que l'on s'attende à quelques bugs, avec cette nouvelle mouture, nous avons une implémentation bien plus complète et robuste qu'elle ne l'a été par le passé.

Alors à quoi ça ressemble? Le code suivant définit une méthode asynchrone nommée list_dir qui énumère de manière asynchrone tous les fichiers du répertoire "Home" :
  async void list_dir () {
    var dir = File.new_for_path (Environment.get_home_dir ());
    try {
      var e = yield dir.enumerate_children_async (FILE_ATTRIBUTE_STANDARD_NAME, 0, Priority.DEFAULT, null);
      while (true) {
        var files = yield e.next_files_async (10, Priority.DEFAULT, null);
        if (files == null) {
          break;
        }
        foreach (var info in files) {
          print ("%s\n", info.get_name ());
        }
      }
    } catch (GLib.Error err) {
      warning ("Error: %s\n", err.message);
    }
  }

  void main () {
    list_dir.begin ();

    var loop = new GLib.MainLoop (null, false);
    loop.run();
  }


Comme vous pouvez le constater, il est très facile d'appeler les méthodes asynchrones enumerate_children_async et next_files_async que ce soit dans une boucle ou même dans un bloc gérant les exceptions (try-catch). Inutile de s'encombrer avec la création de structures pour les donnée à conserver entre les appels, tout est limpide et intégré au langage.

Aller plus loin

  • # Intéressant…

    Posté par  . Évalué à 5.

    Il n’y a plus qu’à espérer que les développeurs de GNOME abandonnent cette horreur de Mono pour Vala !

    DLFP >> PCInpact > Numerama >> LinuxFr.org

    • [^] # Re: Intéressant…

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

      Hmm les développeurs de GNOME utilisent surtout du C, et aussi du python et du C++.

      Les developpeurs de Mono utilisent Mono et ne sont pas près d'arrêter...

      http://www.vuntz.net/journal/post/2006/08/08/393-gnome-et-mo(...)
      • [^] # Re: Intéressant…

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

        Le plus grand bien que je leur souhaite, c'est d'arriver à produire quelque chose de la qualité de Samba. C'est à dire un élément se posant à égalité avec son concurrent, voire le dépassant, tout ça depuis un projet initialement basée sur un travail d'ingénierie inversée.
        Mais ça me semble mal barré dans la mesure ou là le concurrent est en constante évolution (pas les mêmes besoins que samba), j' ai bien peur que Mono ne fasse que suivre, éternellement. Ou alors tout le monde se met à coder en Mono, et là on a que du compatible, tout le temps. Là, encore plus, ça relève de l'utopie.
        Mais ça serait pas un mal, ouaih, que les distributions arrêtes d'inclure les applications mono pour gnome par défaut, car de plus elles n'apportent rien de spécial que d'autre ne sachent faire. (un mail presque au hasard : http://www.mail-archive.com/gnewsense-dev@nongnu.org/msg0088(...) )

        Perso, je préfère largement Adobe Air à Mono ;) au moins ça se développe partout pareil, ça marche partout pareil et ça avance à visage découvert. \o/
        • [^] # Re: Intéressant…

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

          >c'est d'arriver à produire quelque chose de la qualité de Samba.
          >C'est à dire un élément se posant à égalité avec son concurrent

          Faut peut être pas abuser... Actuellement, Samba3 tel qu'il est livré dans les distributions GNU/Linux fait pale figure face à un serveur Windows 2008 et l'ensemble des technologies fournis par ce dernier pour les clients Windows...

          Samba4, y'a du mieux, mais il semble que cela ne soit pas encore génial au niveau de la gestion des GPO...

          Actuellement, une solution offrant le même niveau de service qu'un serveur Microsoft, y'a SambaEdu3:
          - Déploiement de GPO via machine, utilisateur, groupe, parcs, ...
          - Déploiement d'imprimantes via machine, utilisateur, groupe, parcs, ...
          - Déploiement d'applications via machine, utilisateur, groupe, parcs, ... (wpkg)

          Seul hic, SambaEdu est trop lié à l'utilisation en collèges/Lycées pour l'utilisant dans un autre contexte... Et arrivé au niveau de fonctionnalité de ce dernier sur un Samba de base, y'a une quantité énorme de travail.

          SambaEdu.org: http://wwdeb.crdp.ac-caen.fr/mediase3/index.php/Accueil
          • [^] # Re: Intéressant…

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

            Tu compares pas Samba à Active Directory, là ?

            En tout cas, merci pour le lien vers SambaEdu
          • [^] # Re: Intéressant…

            Posté par  . Évalué à 3.

            > > c'est d'arriver à produire quelque chose de la qualité de Samba.
            > > C'est à dire un élément se posant à égalité avec son concurrent

            > Faut peut être pas abuser... Actuellement, Samba3 tel qu'il est livré
            > dans les distributions GNU/Linux fait pale figure face à un serveur
            > Windows 2008 et l'ensemble des technologies fournis par ce dernier
            > pour les clients Windows...

            genre planter ou redémarrer le serveur à distance si on lui envoie le bon petit paquet qui va bien ?

            merci du cadeau, hein.
  • # je suis pas convaincue

    Posté par  . Évalué à 3.

    Je suis novice en programmation mais un langage qui génère un code dans un autre langage, n'est il pas moins performant que du code natif ?
    D'une manière générale, n'est il pas plus intéressant d'utiliser de très bonnes lib comme Qt plutôt que des langage de 17ième niveau??
    Si vous me répondez non, je jure de me mettre au vala.
    • [^] # Re: je suis pas convaincue

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

      Non ce n'est pas moins performant.
      Ca genere du C, ensuite ça compile le C comme si tu avais écrit le C et les performances sont les mêmes.
      • [^] # Re: je suis pas convaincue

        Posté par  . Évalué à -5.

        Je défie quelque générateur de code que ce soit d'être aussi raisonné et efficace qu'un être humain en ce qui concerne l'optimisation du code final... Pourquoi pas un générateur de générateur de langage, tant qu'on y est!... Ce ne sont là que deux des raisons pour lesquelles je n'aime pas et n'apprécierai jamais les générateurs de code.

        [Jean-Pierre Troll! Au secours!]
        • [^] # Re: je suis pas convaincue

          Posté par  . Évalué à 3.

          Je pense que tu peux aller lire le code javascript généré par GWT en mode OBF.
        • [^] # Re: je suis pas convaincue

          Posté par  . Évalué à 10.

          Je suis tout à fait d'accord avec toi, c'est d'ailleurs pour ça que j'écris tous mes programmes en assembleur. Cependant, il y a encore trop d'abstraction, donc je crois que je vais finir par tout écrire directement avec les opcodes.
        • [^] # Re: je suis pas convaincue

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

          Je défie quelque générateur de code que ce soit d'être aussi raisonné et efficace qu'un être humain en ce qui concerne l'optimisation du code final... Pourquoi pas un générateur de générateur de langage, tant qu'on y est!... Ce ne sont là que deux des raisons pour lesquelles je n'aime pas et n'apprécierai jamais les générateurs de code.

          Dans un temps illimité, soit. Mais en temps limité, je ne me mesurerais pas à un compilo.

          Vu la complexité du moindre CPU actuel (et c'est valable pour les MCU), il faut prendre en compte tellement de paramètres (temps d'exécution d'une séquence en fonction du choix des registres, remplissage du cache, et sûrement d'autres trucs que j'ignore) que la machine fait finalement du bon boulot.

          J'ai pu le constater sur avr-gcc en voulant réécrire du code en assembleur. Les choix du compilo (qui en plus n'est pas le plus abouti) ne sont pas tous idiots, loin de là, mais ça ne saute pas au yeux.

          Maintenant, en ce qui concerne l'efficacité des langages évolués, je pense qu'au contraire, ils permettent au compilo de faire de meilleurs choix car le code fourni par le programmeur est alors plus proche de la description du problème et s'éloigne de la fourniture d'une solution qui peut orienter le compilo vers une direction moins optimale. Un peu comme ce que je disais au dessus, en fait.

          Pour en revenir à vala, sans le connaître, je l'imagine comme un préprocesseur très évolué. Donc pas de perte de performance.

          Je crois me souvenir que l'élaboration de C++ est passée par un préprocesseur du même genre, qui gobait du « C with classes » pour en faire du C K&R. Je peux me tromper !

          « J'ai pas Word, j'ai pas Windows, et j'ai pas la télé ! »

          • [^] # Re: je suis pas convaincue

            Posté par  . Évalué à -2.

            Quand je parlais du code final, je ne parlais évidemment pas de l'assembleur ou de l'optimisation des instruction par le compilateur. Ma remarque ne portait pas sur cet aspect.
        • [^] # Re: je suis pas convaincue

          Posté par  . Évalué à 8.

          Les compilateurs C actuels font un remarquable travail avec les "out-of-order execution" par exemple. Un humain a toutes les peines du monde à faire aussi efficace qu'un compilateur.
          Bien entendu, sur un petit nombre d'exemples soigneusement choisis, l'humain fait mieux... mais ça prends 50 ou 100 fois plus de temps. Et sur tous les autres exemples, l'humain fait jeu égal ou moins bien.

          Les compilateurs actuels sont _vraiment_ puissants. Et quand je dis actuels, ça vaut en fait depuis des années. Au milieu des années 90 déjà, il fallait s'accrocher pour produire du code au moins aussi bon que le Watcom C par exemple.
          • [^] # Re: je suis pas convaincue

            Posté par  . Évalué à 2.

            Oui alors là par contre je ne suis pas du tout d'accord.

            Un compilateur sur une machine Out-of-Order a justement *moins* de boulot à fournir, vu que le moteur OoO matériel se charge de rendre moins moche un code « mal généré ».

            Pour donner un ordre d'idée, sur une archi certes quasi-morte, à savoir l'Itanium 2, la qualité du code généré par gcc comparée à celle d'icc [1] est carrément lamentable. Le compilateur d'Intel dans ce cas est en moyenne 3 fois plus performant que gcc. Bien sûr, il y a plusieurs raisons :
            1/ Plus de dévs pour gcc/x86 (mais là je renvoie à gcc/PowerPC qui se débrouille plutôt bien, et je suis sûr que l'OoO y est pour beaucoup)
            2/ L'Itanium 2 n'est pas une machine très répandue (et pour cause), ce qui est finalement une variation sur 1/. :)

            N'empêche : l'Itanium 2 a une architecture VLIW et superscalaire, et dont les seules opérations out-of-order sont liées à la mémoire. Presque tout est laissé au compilateur, et si celui-ci se débrouille mal pour la génération de code, alors le programme résultant sera vraiment mauvais.

            Sur x86, l'OoO limite vraiment la casse.

            [1] Le compilateur du constructeur (Intel), donc évidemment il y a un avantage net pour ce dernier, qui possède le modèle machine du CPU
            • [^] # Re: je suis pas convaincue

              Posté par  . Évalué à 1.

              mais là je renvoie à gcc/PowerPC qui se débrouille plutôt bien, et je suis sûr que l'OoO y est pour beaucoup

              Apple aurait pas file un coup de pouce a gcc sur ppc?
              C'est une question, xcode ayant longtemps utilise gcc, je me dit qu'ils ont du bosser sur le compilo pour en faire qq chose de bien.
              • [^] # Re: je suis pas convaincue

                Posté par  . Évalué à 2.

                À ma connaissance, Apple a surtout aidé au dév de gcc pour y rajouter le support d'AltiVec.
        • [^] # Re: je suis pas convaincue

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

          Vala n'est pas un générateur de code, c'est bien un compilateur. C'est juste qu'il utilise du C comme code intermédiaire, c'est tout. Le C est suffisamment proche de la machine pour que ca ne pose pas de problèmes de performances. En fait, je pense que c'est même plus rapide que de générer du code machine ... gcc a plein d'optimisations qui sont mises a profit dans Vala.

          Même gcc utilise du code intermédiaire, il n'est ni écrit, ni spécifié, mais c'est du code intermédiaire.
    • [^] # Re: je suis pas convaincue

      Posté par  . Évalué à 8.

      La plupart des compilateur C performants génèrent de l'assembleur, et l'assembleur génère du code "machine". Pourtant, programmer en C est plus simple, plus efficace, et souvent plus performant que programmer directement en assembleur ou en code machine.
      Il y a bien entendu des exceptions, mais elles restent rares.

      Cela est valable même si on programme mal. Un mauvais programmeur en C donnera un programme plus lent (ou plus gros, etc) qu'un bon programmeur en assembleur. Mais le mauvais programmeur en C, si il avait fait le code en assembleur, aurait produit également quelque chose de très mauvais.

      Reste que les langage dits de haut niveau ne sont pas faits pour être plus performants, mais pour coder plus vite. Ce qui, dans beaucoup de cas, est un atout considérable.
      • [^] # Re: je suis pas convaincue

        Posté par  . Évalué à 9.

        l'assembleur génère du code "machine"
        Non, l'assembleur est juste une représentation humaine du code machine. On ne compile pas l'assembleur en code machine, on le "traduit", et cette traduction est réversible sans que cela n'entraîne de différences sur le contenu.
        • [^] # Re: je suis pas convaincue

          Posté par  . Évalué à 1.

          Bouais. Pas vraiment. Au moment de l'édition de liens, ton code assembleur est donc lié aux bibliothèques que tu utilises (libc, etc.), et du code supplémentaire est généré par l'éditeur de liens. Sans parler du fait que parfois certaines mnémoniques, pourtant différentes au niveau ASM sont traduite dans le même opcode au niveau binaire.
        • [^] # Re: je suis pas convaincue

          Posté par  . Évalué à 4.

          Si tu regardes dans de l'assembleur généré par gcc par exemple, il y a des tas de directives qui sont là pour que le compilateur assembleur prenne un certain nombre de décisions. Décisions que le compilateur C n'a pas à prendre.

          Il y a même du code pur et dur qui est traduit en fonction du contexte.
          Exemple tout bête: jmp mon_etiquette peut être traduit en saut relatif "short" (0xeb) ou "near" (0xe9). Autrefois il y avait même le jump far (0xea). Même chose pour call. Tu peux préciser jump short ou jump near si tu le souhaites, dans ce cas tu as une traduction de 1 vers 1, mais tu perds la souplesse offerte par le compilateur.
          Et justement, un compilateur C écrit des jmp, donc il délègue au compilateur assembleur le choix de la bonne instruction finale. Ce n'est pas le boulot d'un compilateur de haut niveau de savoir si la cible d'un saut est proche ou non.
    • [^] # Re: je suis pas convaincue

      Posté par  . Évalué à 5.

      Les performances obtenu en vala sont les mêmes que celles obtenues si on avait programmé la même chose avec GObject.
      C'est là l'un des gros atouts de vala, pas de perte de performance. Les développeurs de vala ont justement conçu le langage pour que le mapping en C soit très proche de ce que l'on écrit nativement.
      En regardant de près le code généré, on remarque qu'il y a quelques différences par rapport à ce que l'on écrirait à la main.
      - Les boucles for sont traduites en boucles while ce qui peu réduire les chances de voir les boucles statiques optimisée par le compilateur.
      - les déréférencements ont systématiquement un test pour vérifier que le pointeur n'est pas null, chose qui ne pourrait être vérifié qu'une fois.

      je ne doute pas qu'il y a d'autres points ou la transcription n'est pas (encore) parfaite, mais il me semble aussi que ces points sont facilement améliorable, et ne remet pas en cause le fait qu'on peut générer un code C aussi rapide que celui qu'on aurait écrit à la main.
      • [^] # Re: je suis pas convaincue

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

        >>> les déréférencements ont systématiquement un test pour vérifier que le pointeur n'est pas null, chose qui ne pourrait être vérifié qu'une fois.

        Je suppose que tu voulais écrire "les déréférencements ont systématiquement un test pour vérifier que le pointeur n'est pas null, chose qui pourrait n'être vérifié qu'une fois" ?.
      • [^] # Re: je suis pas convaincue

        Posté par  . Évalué à 2.

        Tu fais quoi des fonctionalités avancées genre les closures et les fonctions asynchrones, entre autre, qui auraient été probablement des "pains in the ass" (sic) à programmer directement en C ?

        Pour ça le code aurait été tellement différent que comparer les performances respectives des deux langages à pas de sens, si tu prends pas en compte la facilité de debuggage, de codage, etc.
        • [^] # Re: je suis pas convaincue

          Posté par  . Évalué à 3.

          Pour les closures, je me demande si c'est si compliqué que ça vu que gcc a les "Nested Functions" [http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html] qui pour moi sont des closures (si je ne me trompe pas).
          • [^] # Re: je suis pas convaincue

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

            Il n'y a pas une histoire de gestion de la pile ?

            En gros, si la nested function est executé en dehors de la fonction qui la créer la pile d'appel n'a plus aucun sens. Une vrai closure doit gérer ce cas-là (Lisaac le fait pour les types blocs).

            "La première sécurité est la liberté"

            • [^] # Re: je suis pas convaincue

              Posté par  . Évalué à 5.

              Oui effectivement, il faut faire en sorte de "sauvegarder" la pile quelque part. Mais comme Vala se base sur du C, et que ce mécanisme serait d'assez bas niveau (i.e. pas accessible depuis le C "classique"), j'ai supposé qu'il s'appuyait sur certaines fonctionnalités de gcc.

              Pour moi, Vala n'est qu'une surcouche qui ne réimplémente pas des choses aussi fondamentales que ça. Peut-être que je me trompe, je ne connais pas vraiment bien le projet, mais j'aimerais bien savoir alors comment il fait.

              Ha, et une petite remarque désargéable (oui, j'aime bien être désagréable) : citer Lisaac pour ça alors que pleins d'autres langages plus connus (à peu près tous les langages fonctionnels, .Net, Scala et plein d'autres) le gèrent, ça fait un peu fanboy de Lisaac .... (oui, je dois avoir l'air d'un fanboy Scala)
              • [^] # Re: je suis pas convaincue

                Posté par  . Évalué à 4.

                il faut faire en sorte de "sauvegarder" la pile quelque part

                Pas besoin de sauvegarder toute la pile, juste les variables de la fermeture. En général il y en a seulement quelques-unes, et tu les connais à l'avance (lors de la compilation). Tu peux donc déléguer l'accès à ces variables à une structure ad hoc, passée en paramètre caché de ta fonction-fermeture (un peu comme le "this" caché de tes méthodes, d'ailleurs un objet n'est rien d'autre qu'une fermeture un peu retournée).

                (oui, je dois avoir l'air d'un fanboy Scala)

                Oui, vu que de toute façon Python et Ruby (et probablement Perl) gèrent aussi les fermetures.
            • [^] # Re: je suis pas convaincue

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


              En gros, si la nested function est executé en dehors de la fonction qui la créer la pile d'appel n'a plus aucun sens. Une vrai closure doit gérer ce cas-là (Lisaac le fait pour les types blocs).


              Tu veux me dire que comme vala, les block Lisaac peuvent accéder à des variables définies en dehors du block (upvalue), même si ces variables ne sont plus dans la pile au moment où le block est appelé ?
              Je ne pense pas que ce soit le cas ...
              Cela voudrait dire une allocation dans le tas.
      • [^] # Re: je suis pas convaincue

        Posté par  . Évalué à 3.

        C'est en effet de genre de choix/tests réalisé pas le compilateur qui fait perdre des performances par rapport au C. Au final si les perfs sont nécessaires alors faire du C reste mieux sinon le Vala est vraiment intéressant. Personnellement je pense que je m'y mettrais mais pas avec GTK :p
    • [^] # Re: je suis pas convaincue

      Posté par  . Évalué à 3.

      Beaucoup de langages, comme ce fut le cas pour le C++, à leurs débuts passent par la génération de code C, c'est une sorte de garantie de ne pas perdre ce qui a été fait si la langage disparait.
      Si un jour suffisamment de gens estiment que Vala tient la route tu auras un compilateur Vala (un front-end gcc par exemple)
      • [^] # Re: je suis pas convaincue

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

        Exactement. C'est que que faisait Sather, c'est aussi ce que fait Lisaac.

        Et puis, on utilise Qt mais Qt est une surcouche au C++ et le code doit être précompilé avec moc avant de pouvoir être compilé avec gcc. Donc finalement, Vala reprend un peu la même approche...
        • [^] # Re: je suis pas convaincue

          Posté par  . Évalué à 6.

          Et puis, on utilise Qt mais Qt est une surcouche au C++ et le code doit être précompilé avec moc avant de pouvoir être compilé avec gcc. Donc finalement, Vala reprend un peu la même approche...

          Un peu seulement. Parce qu'avec Qt, on a très largement du C++ "normal", avec juste une adjonction - qui aurait été possible en C++ pur, mais syntaxiquement lourde - pour le principe des signaux/slots.

          Ici, on a un langage "complet", avec sa propre syntaxe - certes inspirée du C# - qui est transformé en un autre langage.

          En gros, Qt n'est pas un langage. C'est juste une bibliothèque (ou un ensemble de) qui s'autorise une petite déviation par rapport au langage "officiel" et fournit les outils pour que cette déviation soit indolore.
        • [^] # Re: je suis pas convaincue

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

          Erreur: le moc n'est pas un pre-compilateur.
          Le moc lis les fichier en-tête, et génère le code des signaux et celui nécessaire pour l'introspection. Le code généré est sous la forme d'une autre fichier C++ à adjoindre à la compilation.

          Le code que l'on écrit quand on fait de la programmation avec Qt est du C++ pur et est directement compilé par GCC.

          Le code que l'on écrit en Vala est traduit en C avant d'être compilé
          • [^] # Re: je suis pas convaincue

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

            Donc en fait MOC c'est TrollTech^WNokia qui réinvente la roue^W^Wles templates.

            pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

          • [^] # Re: je suis pas convaincue

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

            Le moc n'est pas un pré-compilateur mais génère des fichiers C++ ! Alors qu'est ce que c'est. Pour moi, c'est exactement la définition d'un pré-compilateur... Un pré-compilateur, c'est une action de transformation qui a lieu sur les fichiers sources avant le passage du compilateur.

            Le code écrit pour Qt n'est pas du C++ pur car tu ne peux pas le compiler avec n'importe quel compilateur si tu n'est pas passé par la moulinette moc avant. Je t'accorde cependant que le dialecte de Qt est très proche du C++, c'est une simple extension alors que Vala est plus un traducteur.
            • [^] # Re: je suis pas convaincue

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

              Le code écrit pour Qt est du C++ pur car tu peux le compiler avec n'importe quel compilateur !
              (Et utiliser les outils d'analyse statique de code, ou les éditeurs spécialisés dans le C++)

              Par contre, si tu ne lance pas le moc, ça ne passeara pas l'étape de l'édition des liens car le linkeur te dira qu'il manque des symboles.
              • [^] # Re: je suis pas convaincue

                Posté par  . Évalué à 2.

                Excuse mon ignorance, mais peux-tu me dire comment :
                #include

                class Counter : public QObject
                {
                Q_OBJECT

                public:
                Counter() { m_value = 0; }

                int value() const { return m_value; }

                public slots:
                void setValue(int value);

                signals:
                void valueChanged(int newValue);

                private:
                int m_value;
                };

                (extrait de http://doc.trolltech.com/4.4/signalsandslots.html )peut passer _syntaxiquement_ dans un compilo C++ standard ? (en particulier les public slots et signals ...)
                C'est considéré comme des labels que MOC utilise au moment du link ?!?
                • [^] # Re: je suis pas convaincue

                  Posté par  . Évalué à 4.

                  La moindre des choses, lorsque l'on cite une reference pour appuyer ses dires, c'est de la lire soit-meme...

                  Partie "Building the example", quelques dizaines de lignes en dessous du code que tu as copier-coller:

                  The C++ preprocessor changes or removes the signals, slots, and emit keywords so that the compiler is presented with standard C++.

                  puis

                  By running the moc on class definitions that contain signals or slots, a C++ source file is produced which should be compiled and linked with the other object files for the application.

                  ce qui est tres exactement ce que decrit Gof.

                  Je pense que dans ta hâte a critiquer QT, tu as oublie que tout compilateur C++ est egalement dote d'un preprocesseur qui permet l'ecriture de macros. Cela-dit c'est pas grave, on t'en veut pas :P

                  Tiens, le liens direct vers le fichier source avec les definitions pour slots et signal (tu vas voir, c'est pas tres complique...):
                  http://qt.gitorious.org/qt/qt/blobs/master/src/corelib/kerne(...)
                  • [^] # Re: je suis pas convaincue

                    Posté par  . Évalué à 2.

                    Je pense que dans ta hâte a critiquer QT, tu as oublie que tout compilateur C++ est egalement dote d'un preprocesseur qui permet l'ecriture de macros.
                    Oui c'est exactement ça /o\
                    Vous pouvez me moinsser.

                    Merci pour ces infos !
                • [^] # Re: je suis pas convaincue

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

                  Je suppose parce que dans les en-tête Qt, il doit y avoir des macros:

                  #define slots /*nothing*/
                  #define signals /*nothing*/

                  Ce sont juste des mots-clefs supprimés par le préprocesseur C++ qui sont là pour que le compilateur moc comprenne où sont les signaux et les slots.
            • [^] # Re: je suis pas convaincue

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

              moc ne transforme pas tes fichiers sources...
      • [^] # Re: je suis pas convaincue

        Posté par  . Évalué à -1.

        Un compilateur sans intermediaire en C ne verra certainement jamais le jour pour la simple et bonne raison qu'on perdrait la possibilité de générer des bibliothèques réutilisable en C.
        Le fait qu'il y ait un code intermédiaire en C à été voulu par les concepteurs du langage.
        En fait, toutes les librairies au dessus GObject (comme Gtk) pourraient être réimplémenté en Vala et continuer à avoir une ABI et une API compatible avec celle d'aujourd'hui.
        • [^] # Re: je suis pas convaincue

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

          Sauf qu'implémenter Gtk en Vala fait perdre les connexions à Gtk aux langages de scripts !

          L'objectif de GTK et maintenant de GNOME est d'avoir les bases en C pour pouvoir programmer les applications dans le langage que l'on souhaite. Cependant, les bases doivent rester en C.
          • [^] # Re: je suis pas convaincue

            Posté par  . Évalué à 2.

            Non, c'est ce que j'explique, l'ABI et l'API restent identique, vu que le même .h reste généré...
            Les langage de script resteront compatible. c'est la beauté de Vala.
        • [^] # Re: je suis pas convaincue

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

          Il est parfaitement possible d'écrire des bibliothèques réutilisables en C avec C++, Haskell, D, (O)Caml, Pascal... alors que tous ces langages ont des compilateurs natifs. Rien n'interdit donc à Vala de faire pareil.
          • [^] # Re: je suis pas convaincue

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

            Si tu veux écrire une bibliothèque C++ réutilisable en C tu devras réfléchir à ce que vas faire le compilateur au niveau binaire dès lors que tu utilise du C++ complexe.

            Quand tu écris du Vala, le code généré est *très* lisible et permet de comprendre le travail réalisé derrière. De plus des 'binding' antre langages automatiques sont réalisés grâce aux capacités de GObject pour l'introspection, cf [http://live.gnome.org/GObjectIntrospection].

            Une autre approche est d'utiliser un générateur d'interface tel que SWIG [http://www.swig.org] mais, personnellement je trouve cette approche très lourde par rapport à l'introspection.
          • [^] # Re: je suis pas convaincue

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

            Je suis d'accord mais en pratique, je n'en connais pas... sauf les bibliothèques de base en calcul numérique qui étaient historiquement en Fortran mais c'est de moins en moins vrai (blas...).

            As tu des exemples qui sont utilisés courament (or de la mouvance Qt et KDE) ?
          • [^] # Re: je suis pas convaincue

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

            Comment on fait pour réutiliser en Haskell une bibliothèque écrite en C++ ???
            .NET ou Java utilisent leur bytecode comme dénominateur commun pour que les bibliothèques puissent être utilisables sur tous les langages de la plateforme.
            La plateforme GNOME utilise le C. Vala produit du C, celui-ci peut être passé dans les moulinettes automatiques qui génèrent les bindings C++, Python, etc...
            • [^] # Re: je suis pas convaincue

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

              Comment on fait pour réutiliser en Haskell une bibliothèque écrite en C++ ???

              Attention, relis bien ce que j'ai écrit: je n'ai pas dit qu'il était possible de prendre n'importe quelle bibliothèque écrite dans n'importe quel langage et de la réutiliser dans n'importe quel autre langage! J'ai dit qu'il était possible d'écrire une bibliothèque en C++ ou en Haskell de telle sorte qu'elle soit utilisable depuis un programme C. Et dans ce cas elle devient effectivement utilisable dans la majorité des langages.

              Rien n'empêche Vala de faire pareil si ils veulent développer un compilateur natif.

              PS: Je ne dis pas qu'ils devraient le faire, hein? Juste qu'il peuvent le faire sans perdre la compatibilité C.
  • # Performances

    Posté par  . Évalué à 1.

    Vous pouvez aller jeter un oeil au projet vala benchmark pour voir la difference de performance entre Vala et du C à l'heure actuelle.

    http://code.google.com/p/vala-benchmarks/wiki/BenchResults
    • [^] # Re: Performances

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

      C'est dommage que Vala ne soit pas présent sur le shootout (http://shootout.alioth.debian.org/index.php). Cela dit, je constate que les benchs utilisés sur ton lien sont les mêmes, peut-être est-ce en cours?
      • [^] # Re: Performances

        Posté par  . Évalué à 2.

        Oui, le but du projet vala-benchmark est d'être inclu dans le projet "computer language benchmarks game" que tu cites.
        Ceci explique qu'ils utilisent les même benchmarks.
      • [^] # Re: Performances

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

        Étant l'auteur de vala-benchmarks (et passant actuellement à la postérité) je peux t'en parler plus longuemement.

        À l'origine ma démarche a été de discuter avec Isaac Gouy du shootout (voir [http://alioth.debian.org/forum/forum.php?thread_id=3619&(...)]) cependant celui-ci n'a pas jugé le Vala comme langage intéressant pour son projet. J'ai donc lancé [http://code.google.com/p/vala-benchmarks/] pour écrire l'ensemble des tests avec comme but final d'être intégré au shootout.

        Actuellement un certains nombre de tests ont été implémentés et on permis de fournir une base d'exemple de code.
        • [^] # Re: Performances

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

          Parmi ces benchmark, est-ce que certain peuvent mesurer la ''performance'' de la couche objet des langages ? Objective-C, C++, Vala...
          • [^] # Re: Performances

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

            Je crois qu'il n'y a qu'un seul test qui vérifie cela. La plus part des tests sont orienté impératifs.

            En même temps, c'est complexe de trouver un test d'un milliers de ligne maximum qui met en avant les performances objets d'un langage.

            Il faudrait mettre en avant les perfs d'héritage, des redéfinitions de fonctions (le virtuel du c++), etc... Bref, les perfs des fonctions avancées objet.

            Je pensais bien à un système de factory qui utilise ensuite les objets créés. Mais ce n'est pas évident de définir qqch qui n'est pas trop artificiel.

            "La première sécurité est la liberté"

            • [^] # Re: Performances

              Posté par  . Évalué à 3.

              Il y a le benchmark "richards" qui prétendre tester le modèle objet, et qui est relativement court.
          • [^] # Re: Performances

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

            En fait le "couche objet", comme tu l'appelle est utilisé pour créer des GObject. Dans certains cas tu peux préciser dans le langage Vala de ne pas l'utiliser comme, par exemple, dans le cas du test BinaryTree.

            Pour obtenir les meilleures performances du code généré, j'ai du effectuer un choix parmi les différents types de classes :

            - héritant de GObject (publiques et enregistrées dans GObject)

            public class MyClass : Object {
            ...
            }


            - implémentant GObject par le compilateur (publiques)

            public class MyClass {
            ...
            }


            - implémentant GObject partiellement par le compilateur

            [Compact]
            public class MyClass {
            ...
            }


            - passant les paramètres par valeur

            public struct MyClass {
            ...
            }


            Tu peux t'amuser avec les différents façon et tu observera une différence réelle dans ce test. Le Vala a ainsi l'avantage de te laisser choisir l'implémentation en C par construction ce que ne permettent pas d'autres langages.

            Il faut aussi te méfier avec des tests comme ceux-ci car les performances lors de la construction dépendent de la librairie GObject donc de la façon de la compiler. Pour ce benchmark je me suis restreint à la distribution par défaut dans Debian Squeeze.
            • [^] # Re: Performancesvv

              Posté par  . Évalué à 3.

              Ce qui mouche complètement l'argument des partisans du C qui disaient à l'époque que comme gobject était en C on avait pas de perte de perf, si j'ai bien compris ton message.

              Ben non, en ajoutant une couche objet en C "human readable" on perd quand même en perf par rapport à une implémentation plus maligne de la même couche objet ...
              • [^] # Re: Performancesvv

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

                En fait on est vraiment sur des micro-benchs. Dans BinaryTrees on test *uniquement* l'allocation et la désallocation mémoire. Et effectivement, sur celui-ci, lorsqu'on est dépendant de libgobject, les performances sont moins bonnes car libgobject est compilé avec '-O2 -g' et je ne m'amuse pas à recompiler libgobject ni libc ni mono pour les benchs.

                Il y a un rajout de code et de temps d'exécution mais dans une application réelle, tu ne fait pas qu'allouer ou désallouer des objets, non ? Ainsi quand on fait une somme sur l'ensemble des tests implémentés, le Vala s'approche du C.

                Concernant le fait de rajouter une couche objet plus maligne, il faut bien différencier deux choses :
                - une implémentation à tendance statique, style C++
                - une implémentation à tendance dynamique, style Objective-C ; Java ; .NET ; GObject

                Donc en soit on ne peut pas vraiment comparer C++ et C/GObject car le fonctionnement est différent. Personnellement, j'ai voulu comparer l'impact d'une machine virtuelle en conservant une environnement haut-niveau équivalent (Vala vs C#), le C++ a été ajouté par la suite.
  • # C# pas interprété

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

    "Contrairement à C# le code n'est pas interprété par une machine virtuelle, c'est un langage compilé."
    C# n'a jamais été conçu pour être interprété mais pour être compilé dans un code intermédiaire qui est lui même compilé à la volée (JIT), voir en avance (AOT).
    L'interprétation, c'est totalement has been, ca sert uniquement à porter "rapidement" un langage sur une nouvelle plateforme matérielle en attendant une chaîne de compilation native.
    • [^] # Re: C# pas interprété

      Posté par  . Évalué à 3.

      Alors non, la CLR nécessaire pour lancer un programme C# est une machine virtuelle. Sans la CLR, impossible d'executer du code C# compilé Byte-Code. C'est bien la définition d'une machine virtuelle, que la machine utilise JIT(Just In Time compilation) pour exécuter le byte-code ne change en rien que la CLR est une machine virtuelle, tout comme la JVM de Java en est une (et qui fait aussi du JIT).
      En C# le byte-code est donc bien interprété, cette interprétation utilise la technologie JIT qui permet de gagner en performance, mais celà ne rend pas ma phrase fausse pour autant.
      • [^] # Re: C# pas interprété

        Posté par  . Évalué à 1.

        Pour appuyer ma définition, je te renvois à la définition donné par wikipedia d'un langage interprété : http://fr.wikipedia.org/wiki/Langage_interpr%C3%A9t%C3%A9_in(...)
      • [^] # Re: C# pas interprété

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

        En C# le byte-code est donc bien interprété
        Je vois pas le rapport entre le premier et le 2ème paragraphe.
        La présence d'une machine virtuelle ou d'un environnement d'exécution ne défini en rien le fait que C# soit interprété.

        cette interprétation utilise la technologie JIT qui permet de gagner en performance
        JIT est une technique de "compilation", pas d'interprétation.
        C'est même dans le nom : http://en.wikipedia.org/wiki/Just-in-time_compilation
        je cite : "It converts code at runtime prior to executing it natively, for example bytecode into native machine code. The performance improvement over interpreters originates from caching the results of translating blocks of code, and not simply reevaluating each line or operand each time it is met (see Interpreted language)."
        Ce qui se traduit par :
        "Il converti le code pendant son déroulement avant de l'exécuter nativement, par exemple il converti le bytecode en code natif. Le gain de performance par rapport aux interpréteurs vient du fait de mettre en cache le résultat de la tranduction de bloc de code plutôt que de réévaluer chaque ligne ou opérateur à chaque fois qu'il le rencontre. (voir langage interprété)."

        La compilation et l'interprétation sont 2 techniques différentes pour exécuter du code. Que la compilation se fasse en 2 étapes pour ajouter un niveau d'abstraction (machine virtuelle) ne change rien.

        C# est un langage conçu pour être compilé en ciblant la CLI et cette dernière est conçue pour compiler du bytecode en code natif.

        Il est possible d'interpréter le bytecode intermédaire, mais l'intérêt est limité. La page de mono sur l'environnement d'exécution décrit bien les différentes techniques utilisées et précise à propos de l'interpréteur :
        http://www.mono-project.com/Mono:Runtime

        "Mono has both an optimizing just-in-time (JIT) runtime and a interpreter runtime. The interpreter runtime is far less complex and is primarily used in the early stages before a JIT version for that architecture is constructed. The interpreter is not supported on architectures where the JIT has been ported. "
        Ce qui se traduit par :
        Mono a un moteur d'exécution optimisé à la volée (JIT) et un interpréteur. L'interpréteur est beaucoup moins complexe et est avant tout utilisé en amont avant qu'une version du moteur JIT pour l'architecture cible soit construit. L'interpréteur n'est pas supporté sur les architectures où le moteur JIT a été porté.
  • # Et le déboguage ?

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

    J'ai utilisé des langages qui généraient des codes intermédiaires : Profortran Oracle qui donne du fortran, ProC Oracle qui donne du C, lex et yacc qui donnent du C : dans tous les cas, on retombe sur le même problème en cas d'erreur ou de déboguage car les messages se réfèrent au code intermédiaire qui est le plus souvent illisible pour un humain.

    Ma question est de savoir comment Vala gère cet aspect ?
    • [^] # Re: Et le déboguage ?

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

      Effectivement, cela a posé problème et est en passe d'être résolu.

      Il existe un patch pour gdb qui permet de déverminer facilement du code Vala [http://abderrahim.arablug.org/blog/archives/8-GDB-Vala-suppo(...)]. Cependant l'utilité de ce patch est, pour moi, réduite car Vala utilise des conventions simples.

      Un autre aspect qui facilite la prise en main d'un exécutable est l'inclusion dans le langage de pre, post -conditions et invariants ce qui facilite le déverminage. On peut aussi noter la conservation des commentaires ce qui permet de facilement retrouver la translation d'un algorithme particulier.

      En résumé, actuellement la déverminage se passe sur la mailing-list car la majorité des utilisateur lise du C facilement.
      • [^] # Re: Et le déboguage ?

        Posté par  . Évalué à 2.

        Et concernant des bêtes erreurs de compilation ?

        N'y a-t'il pas des cas où l'erreur est détectée seulement au moment de la compilation du code C ?
        • [^] # Re: Et le déboguage ?

          Posté par  . Évalué à 2.

          J'en doute, tout simplement parce que le compilateur vala ne devrait pas être capable de générer du code fautif. Il devrait se rendre compte de l'usage des variables non-définies, ... avant de compiler le code C généré.

          Après, si valac génère effectivement un code contenant des erreurs de syntaxes, je crois qu'on peut considérer ça comme un bogue :-)

Suivre le flux des commentaires

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