Journal Perl, Javouille, Lisaac|(Ruby|SmallTalk|etc..)

Posté par (page perso) .
Tags : aucun
15
20
jan.
2009
Ayant pas mal codé en perl ces derniers temps, j'ai fait suffisamment de code pour commencer à avoir un avis à peu près informé de ce langage.
Je suis pourtant loin d'avoir exploré toutes les possibilités offertes, tellement elles sont énormes.
J'utilise principalement Perl pour ce quoi il est fait, c'est à dire analyser de la chaine pour en générer.
Les connaisseurs me demanderont pourquoi je ne code pas avec le langage que je défend : Je n'utilise pas encore Lisaac parce qu'il n'a pas encore de librairie regexp, et quand il en aura une, je m'occuperai très sérieusement de la lib standard de ce langage, dont les améliorations (de lib et de spec) que j'ai proposé sont encore essentiellement théorique pour l'instant.
Javouille, parce que non, je peux pas, je n'utilise ce langage que contraint et forcé, Java est tout sauf un langage intéressant (pas intégralement objet, pas de type block).

Je suis un fana des regexp, le seul bouquin d'informatique de ma bibliothèque s'y consacre intégralement. J'aime beaucoup plus généralement les langage où je défini mon besoin sans expliquer comment y parvenir, les regexp sont très proches de cet idiome, ainsi que SQL.

Je me suis donc attelé à produire une petite liste de choses que j'ai aimé, qui m'ont surpris dans ce langage, en comparant avec ce que je connais en lisaac et en Java, afin de mettre en perpectives les limites de chacun des langages.
Notez que ce qui s'applique à Lisaac fonctionne avec Ruby, Smalltalk et tous les langages à prototypes.

J'ai beaucoup aimé certains concepts, comme :

Les opérateurs de regexp, le matching et la capture facile


if ($line =~ /(\w+)=(\d+)/ ) {
  $ident=$1;
  $value=$2;
}


En java, c'est tout un bordel :

Pattern p = Pattern.compile("(\w+)=(\d+)");

Matcher m = p.matcher(line);

boolean b = m.matches();

if(b) {

 if (m.groupCount() == 2){
   ident = m.group(1);
  value = m.group(2);
 }
}


Quelle lourdeur !!

La lib regexp Lisaac n'existe pas encore. Il est probable que l'on utilise celle de SmartEiffel, suite au traducteur Eiffel->Lisaac que D. Colnet B. Sonntag ont commencé il y a un an et demi (et que je ne parviens pas à compiler : impossible d'installer correctement smarteiffel...).
Je passerai derrière pour modifier drastiquement l'interface de cette lib que j'intégrerai à STRING, car je pense que qu'une lib Regexp à part (ie dans une classe/prototype distinct) est un concept débile. Les regexp s'appliquent aux chaines et ont donc leur place dans l'objet chaine.
Je l'imagine donc en Lisaac comme suit :

 (ident,value) := line.match_and_capture "(\w+)=(\d+)";

Si ça match pas, ident et value valent NULL.



Les tables de hashage builtint

Les tables de hashage sont un outil très puissant et caractéristique de perl.
Je ne vais pas vous la faire en java, il y a n classes différentes pour faire un hash (LinkedHashMap, Hashmap, ...).
En lisaac, c'est à peine mieux, il y en a deux, et ça risque d'augmenter : une histoire de perfs.
J'aime les choses simple et j'aimerai donc qu'il y ait une classe de collection et une classe de hash afin de respecter le concept d'outil générique qui séduit beaucoup de monde dans les langages où ils sont implémentés comme tels.

Des trucs assez énorme en perl sont des écritures du genre :

%hash = ( $chaine =~ m/(\w+)=(\d+)/);
# sans compter :
my %hash = (1,2,4,5);

On pourrait mettre une liste à la place d'ailleurs.
En java, on oublie, la lib est figé, minimal, on est obligé de se faire sa fonction à soi.
Il faut lire ça pour mesurer la débilité de cette lib : http://java.sun.com/javase/6/docs/api/java/util/HashMap.html :
On peut récupérer la liste des clé et des valeurs, via des énumérations, une pauvre interface qui ne permet d'obtenir une sorte de liste chaînée.
Et... Sait-on pourquoi, on peut avoir la liste des valeurs dans une collection.

Bon soyons sérieux, imaginons qu'on ait la détection automatique de path de code en Lisaac (un saint graal très difficile à implémenter qui consiste à demander au compilateur de choisir le parent le plus adapté pour son code. Ca permettra d'avoir un seul proto collection, un seul proto hash, un seul proto set).

En lisaac, comme tout est à faire, on a le droit d'imaginer des choses intelligentes :

- myhash : HASHED_DICTIONARY[STRING,STRING];
myhash := chaine.to_hash "(\w+)=(\d+);";

et tant qu'à faire :

- mylist : ARRAY[STRING];
mylist := chaine.to_list "(\w+)=(\d+);";



Les substitution en regexp

Rien de transcendant, et pour une fois on félicite les auteurs de la lib java qui ont écris un replaceAll intelligent : il gère les captures !!


chaine.replaceAll("(\w+)=([a-r]+)","truc=$1;");


Mais... car il y a un mais, l'opérateur perl est en fait beaucoup plus puissant: comment je fais chaine.replaceAll("=([a-r]+)","truc=$1.uppercase;"); ??
En java, c'est mort (bien évidemment), en Lisaac, on peut encore s'en sortir : au lieu de lui donner une chaine, on lui donne un block de code prenant une liste chaine en argument (les bouts capturés) et renvoyant une chaine.
chaine.replace_all "(\w+)=([a-r]+)" by { nbcap : INTEGER; caps : ARRAY[STRING] ; caps.item i.lowercase +":"+caps.item 2.uppercase; };
Un peu lourd mais efficace.


L'appel de commande bash en quote inverse
C'est typiquement un truc pour unix, mais pour des petits script, c'est vraiment le pied absolu. Pour récupérer le contenu d'une url, ma fénéantise est pleinement assouvie avec un :

my $cont = `curl http://monurl`;


De toutes façons, je ne sais pas coder en shell et j'ai pas l'intention d'apprendre.

La notion de flux facile, avec print MONFLUX ...

La gestion de flux est sympa, car on a qu'à rediriger où on le désir, alors qu'un langage objet implique de créer un objet par flux.
J'ai pas encore assez approfondi ce concept dans perl, mais il y a surement de bonnes idées à prendre.

Les join, grep sur tableaux
On retrouve un peu la notion de map/fold/filter un peu contextualisé. Je considère qu'il y a deux types de langages :
Les langages insuportables où il n'y pas possibilité d'implémenter proprement un map/fold/filter (au hasard, Java...), et les autres.


Les tranches et autres @liste = %h{@t};
L'écriture @liste = %h{@t}; montre vraiment la puissance de la grammaire de perl. On sent que Larry Wall est linguiste et a voulu aller plus loin.
Ca donne des idées. En type ça donne :
HASH(LISTE) => LISTE
quand
HASH(SCALAIRE) => SCALAIRE

Implicitement, ça fait quand même une boucle qui parcours le hash et renvoi une liste de clés !
Ce map implicite sur la liste est très puissant, et ça montre vers où les langages devraient aller (dans le concept) selon moi : revenir à l'analyse du contexte et déterminer ce que le programmeur veut faire. Etre capable de faire des raisonnement de ce genre, mais sur des types beaucoup plus complexe.
Après, il y a des risques...

Ca montre une application intéressante de ce qu'on peut faire si on colle de l'algèbres aux types fondamentaux de nos langages.
Un tableau c'est quoi ? On peut le voir comme le produit de deux ensemble E ∈ |N et F ou tablo[5] est f(5), 5 étant un élément de E, et f(5) un élément de F.
Soit F = Union (i<=n) ui ∈ I et E Union (i<=n) vi ∈ |N
Algébriquement, en posant f bijective (cas idéal, pas de valeur null) ∀ i ∈ I, ∃ j tel que j=f(i)
Or, E est un ensemble, donc une liste d'éléments qu'on peut énumérer avec une fonction G : |N -> E, donc G : |N -> |N
Dans le cas d'un tableau, l'ensemble de départ est toujours un sous ensemble de |N, dans le cas d'une table de hashage, ça peut être n'importe quoi.
Algébriquement f(E) = F, f étant surjective pour toutes les valeurs définies, F étant un ensemble, une liste énumérable, on peut contextuellement faire comprendre au compilateur de quoi il s'agit.

Dans tous les langages que je connais, y compris OCaml, si le message/fonction n'existe pas pour le type, le compilateur répond qu'il ne sait pas quoi faire.
Je n'ai jamais vu le pattern de raisonnement mafonction : ELEMENT1 -> ELEMENT2 => mafonction : COLLECTION[ELEMENT1] : COLLECTION[ELEMENT2].
Sauf en perl... Je sais pas si le cas est traité en dur dans l'analyseur (surement), mais c'est vraiment un concept génial.

C'est ce genre de choses qui font que ce langage a ses fanatiques ;-)

Alors c'est pour ça que je pense à un mécanisme potentiellement dangereux dans pas mal de langages objets : Tout message s'appliquant sur un objet est appelable sur une collection de cet objet.
Par exemple :
ayant

chaine_result := mastring.replace_all "(\w+)=([a-r]+)" by "rien";

on pourra faire


liste_chaine_resultat : ARRAY[STRING];
liste_chaine_resultat := liste_destring.replace_all "(\w+)=([a-r]+)" by "rien";


J'ai pas réfléchi aux côtés noirs de cette idée de map implicite qui casse quand même pas mal le paradigme...

Certaines difficultés m'ont particulièrement énervées en perl, principalement quand ce sont des problèmes inexistant dans d'autres langages. J'ai noté que certaines disparaitront avec Perl 6.

Citons :

La galère dès que l'on veut créer une structure de donnée : pas de notion claire de création de type, il faut créer une table de hashage spécial, il n'y a pas de distinction claire entre type et variable. Ce n'est pas très clair/propre quand on essaye de faire marcher tout cela entre plusieurs fonctions.
On s'en débrouille aisément en les doublant partout où on les utilise, ou en créant un package, mais ces solutions restent lourdes.

- La galère pour passer autre chose que des scalaire en paramètre : on attend perl 6 avec impatience. Personnellement après plusieurs tentatives infructueuses avec les références "comme dans la doc", j'ai laissé tombé et opté pour une très crade variable globale.

- La caractère non typé des variable, voire le point 1 : Ca révèle des surprises, et j'éviterai perl pour du code supérieur à 5000 lignes ou trop complexe, ça deviendrai vite ingérable.

- Les références, c'est puissant, mais c'est un pis allé du à l'absence de notion de type. A l'utilisation c'est pénible, casse-gueule, dangereux, bref tout ce qui m'énerve dans les pointeurs à la C.


Bref, j'aime beaucoup ce langage, même si revenir au procédural est parfois un peu difficile, mais la logique de celui-ci s'y prete bien.
Je pense que je m'en inspirerait grandement lorsque j'aurai enfin ma librairie regexp en Lisaac, afin de pouvoir disposer de toutes les fonctionalités formidables qui y sont offertes, voire peut être plus...
  • # my 2 cents

    Posté par . Évalué à 6.

    bon j'ai pas essayé lisaac (tous les mois je me dis "faut que je l'essaie" et c'est toujours remis à plus tard).
    Mais par rapport à perl :
    Je fus "forcé" de me mettre à perl pour la maintenance et l'évolution d'une plateforme web. Et depuis j'ai adopté ce lgg ;)
    j'use et j'abuse des tableaux et des hashs, surtout de la facilité à les utiliser, à rajouter un élement, en enlever etc... (bon des fois c'est bien ennuyant entre les references de hash et les scalaire).

    Perl n'est pas parfait non plus : manipuler du binaire peut etre assez compliqué (mais bizarrement, pas si compliqué que ça, et puis c'est pas son terrain de jeu initial ;)), mais surtout le parallélisme reste passablement spécial : certaines variables peuvent etre partagé, mais pour partager un tableau de hash ou autre c'est relativement compliqué.

    Quant à java, je serais moins dur que toi : ca reste un langage interessant pour apprendre, et surtout, java a une énorme API , et bien moins complexe/mieux documenté a utiliser que certaibs modules de perl (non officiel, qu'il faut rajouter, ...).

    Ce que j'aimerais c'est un langage qui allie la facilité du perl, les performances du C, le parallélisme de erlang (pouvoir changer du code à chaud *_*), et la "non gestion" de la mémoire, et aussi adopté un truc simple pour faire des réference et les différencier des données direct.
    • [^] # Re: my 2 cents

      Posté par . Évalué à 9.

      C'est peut être une question d'habitude, mais je trouve le Java infiniment plus lisible que Perl ou Lisaac...
      • [^] # Re: my 2 cents

        Posté par (page perso) . Évalué à 4.

        je pense oui que c'est l'habitude.
        Java étant assez pauvre, il est facile (mais fastidieux) à lire
        Par contre, souvent les programmes en perl vont utiliser beaucoup plus de mot clés (tous les $* par exemple) en plus avec de l'implicite (qui ne pose pas de problème sauf si on en a jamais recontré) et donc forcément c'est plus compliqué si on est pas habitué
        mais bon, comme tous les langages faut les apprendre pour les comprendre...
    • [^] # hors-sujet

      Posté par (page perso) . Évalué à 4.

      Tu fais toujours des journées de 20 h ou tout ça c'est du passé ?
      Tu vas aller te promener aux prudhommes bientôt ?

      If you choose open source because you don't have to pay, but depend on it anyway, you're part of the problem.evloper) February 17, 2014

      • [^] # Re: hors-sujet

        Posté par . Évalué à 6.

        j'ai dem début décembre , après qu'il ait commencé à m'engeuler sur n'importe quoi (ie avec ses journées de 20h, j'ai pas pu finir un autre projet dans les "délais", et il a estimé que j'étais un incapable (en m'engeulant).)

        Et je suis en train de taper une lettre pour les prudhommes pour essayer de changer la dem en licenciement.

        Le plus "fun" c'est qu'après que je lui ais dis ses 4 vérités (ah ca fait du bien), et après que la dem soit complètement terminé , il renvoie une lettre en disant "je ne reviendrais pas sur votre demission, mais tout ce que vous dite est faux. Et je n'apporterais aucune justification".

        Bref, si avant ça j'hésitais à aller aux prudhommes, maintenant j'hésite plus XD
        • [^] # Re: hors-sujet

          Posté par . Évalué à 10.

          C'est clair, ce genre de fautes d'orthographe est inacceptable.

          Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.

  • # t'as tout compris !

    Posté par . Évalué à 2.

    Pour résumé : Perl permet de faire moins de chose qu'un langage complet (Java...), mais permet de les faire bien plus facilement !

    Pour moi, Perl n'est pas juste un énième langage, mais bien une réponse à un besoin : celui de faire plus simplement des taches souvent répétitives, en faisant en sorte d'être cohérent dans la globalité du langage.
    Il a su sortir des clivages des langage "typés" ou non "typés" en proposant un typage basé sur la structure, plutôt que sur les données. C'est simple et génial.

    Je travaille actuellement sur un projet assez conséquent avec Perl, et tout ce que tu as dit sur la maintenabilité du code est vrai. Par contre, dès que j'ai besoin de structure un peu compliquée, je fait un objet et tout s'éclaire!
    Par contre, je ne suis pas fana des Regexp, qui sont, malgré leur puissance, un pustule sur la beauté de la concision du langage.

    Cependant, je suis un peu sceptique sur Perl6, car Perl avait la beauté des concepts simple et cohérents. Espèreront que Perl6 ne sera pas yet another usine à gaz...

    Perl rend beau. Mangez-en.
  • # T'as tout compris

    Posté par . Évalué à 10.

    La galère dès que l'on veut créer une structure de donnée : pas de notion claire de création de type, il faut créer une table de hashage spécial, il n'y a pas de distinction claire entre type et variable. Ce n'est pas très clair/propre quand on essaye de faire marcher tout cela entre plusieurs fonctions.
    On s'en débrouille aisément en les doublant partout où on les utilise, ou en créant un package, mais ces solutions restent lourdes.

    - La galère pour passer autre chose que des scalaire en paramètre : on attend perl 6 avec impatience. Personnellement après plusieurs tentatives infructueuses avec les références "comme dans la doc", j'ai laissé tombé et opté pour une très crade variable globale.

    - La caractère non typé des variable, voire le point 1 : Ca révèle des surprises, et j'éviterai perl pour du code supérieur à 5000 lignes ou trop complexe, ça deviendrai vite ingérable.

    - Les références, c'est puissant, mais c'est un pis allé du à l'absence de notion de type. A l'utilisation c'est pénible, casse-gueule, dangereux, bref tout ce qui m'énerve dans les pointeurs à la C.



    Ben voilà, tu viens de comprendre pourquoi il existe plusieurs langages : parce que chacun a ses avantages et ses inconvénients.
    Tous ces inconvénients n'existent pas en Java (par ex.) !
    • [^] # Re: T'as tout compris

      Posté par . Évalué à 10.

      Et j'ajouterais que ton exemple pour comparer Perl et Java sur leur utilisation des Regexp est un peu "pas objectif" :

      if ($line =~ /(\w+)=(\d+)/ ) {
      $ident=$1;
      $value=$2;
      }


      Pattern p = Pattern.compile("(\w+)=(\d+)");

      Matcher m = p.matcher(line);

      boolean b = m.matches();

      if(b) {

      if (m.groupCount() == 2){
      ident = m.group(1);
      value = m.group(2);
      }
      }

      Même s'il fait 9 lignes (sans compter les lignes blanches) là où ton exemple en fait 4, je trouve cela bien plus lisible : les noms des classes sont tellement parlants que je sais de suite ce que je suis en train de regarder. Ce n'est pas du tout le cas (du moins pour moi qui ne connais pas Perl) avec ton exemple.
      Ensuite, dans l'exemple Java, tu utilises à rallonge la définition des variables alors qu'elles ne semblent pas te resservir plus tard... Autant raccourcir un max (si c'est le nombre de lignes de code qui importe) :

      Matcher m = Pattern.compile("(\w+)=(\d+)").matcher(line);

      if(m.matches()) {

      if (m.groupCount() == 2){
      ident = m.group(1);
      value = m.group(2);
      }
      }

      C'est plus court (mais perso, je ne trouve pas ça forcément plus lisible)
      • [^] # Re: T'as tout compris

        Posté par (page perso) . Évalué à 4.

        > je trouve cela bien plus lisible

        ben pas moi, en fait toute l'information est masquée au milieu de définitions et noms de classes qui ne servent pas à grand chose...
        En fait toutes ces définitions sont contenues dans =~ mais forcément si on ne le connaît pas on ne comprend pas et on doit "deviner" ce que le programme fait.
        Par contre si on apprend cet opérateur ben c'est concis _et_ clair
      • [^] # Re: T'as tout compris

        Posté par (page perso) . Évalué à 7.

        En Python : import re
        m = re.match(r"(\w+)=(\d+)", line)
        if m:
        __ident = m.group(1)
        __value = int(m.group(2))

        où __ représente l'indentation, ex: 4 espaces (la base HTML code vire les espaces sur linuxfr).

        Je trouve ça plus clair que Perl car où sait d'où viennent et sont les données. Il n'y pas de variable magique comme les $xxx. Perl a l'avantage d'intégrer les expressions régulières à son langage : en Python, il vaut mieux préfixer les chaînes par « r » (chaîne raw, n'interprète pas les antislashs).
        • [^] # Re: T'as tout compris

          Posté par . Évalué à 1.

          Une raison particulière pour laquelle tu es passé par une variable temporaire ?

          (question sincère de débutant à la noix :D)
          • [^] # Re: T'as tout compris

            Posté par . Évalué à 2.

            Par ce qu'il n'y a pas d'autre moyen.

            re.match renvoie un "matchobject" si il arrive a appliquer le motif sinon None.

            Il faut donc stocker le résultat et le tester pour éviter d'appeler la méthode "group" sur None.

            Par contre si tu n'a qu'un seul résultat et que tu est certaind e l'avoir sans ce cas tu peut faire :

            import re
            print re.match(r"(\d+).*", line).group(1)
          • [^] # Re: T'as tout compris

            Posté par (page perso) . Évalué à 4.

            Une raison particulière pour laquelle tu es passé par une variable temporaire ?

            Oui, j'appelle ça la lisibilité :-) Je n'aime pas le code « malin » (que j'appellerai plutôt « concis » en réalité) qui au final n'est compréhensible que par son auteur. Mais oui, en Python on peut écrire des trucs sales !ident, value = re.match(r"(\w+)=(\d+)", line).groups()
            (cette version stocke value sous forme d'une chaîne de caractères et non pas d'entier)

            Note : il existe aussi les groupes nommés :>>> re.match(r"(?P\w+)=(?P\d+)", "cle=42").groupdict()
            {'ident': 'cle', 'value': '42'}
      • [^] # Re: T'as tout compris

        Posté par . Évalué à 4.

        tu peux même le faire en 1 seule ligne en perl :


        my ($ident,$value) = ($line =~ /(\w+)=(\d+)/ );
    • [^] # Re: T'as tout compris

      Posté par . Évalué à 1.

      et je ne vois pas pourquoi c'est compliqué de passer autre chose que des scalaires en paramètre

      petit exemple de passage d'une table de hashage par référence :



      my %hash = (1,"toto",2,"tata");

      myfunc(\%hash);

      sub myfunc {
         my $rhash = shift;

         while (my ($key,$value) = each %$rhash){
             print "$key = $value\n";
         }
      }
      • [^] # Re: T'as tout compris

        Posté par . Évalué à 1.

        Mes souvenirs du perl sont vieux donc jdis ptet une connerie, mais ça ne pose pas de problèmes si tu passes un hash, un scalaire, un tableau à la même fonction ?
      • [^] # Re: T'as tout compris

        Posté par (page perso) . Évalué à 2.

        Ce genre d'exemple je l'ai vu 20 fois dans 20 docs différentes, et ça a jamais marché.
        Au bout de 2h, j'ai laissé tombé.

        « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

        • [^] # Re: T'as tout compris

          Posté par . Évalué à 3.

          En python ya que des références, je comprends pas l'intérêt de s'emmerder avec des listes directes et des listes en références, un seul type suffit.
        • [^] # Re: T'as tout compris

          Posté par . Évalué à 2.

          euh, t'exagères là quand même.
          Passer des références en paramètres, ça marche sans aucun problème, et heureusement
          • [^] # Re: T'as tout compris

            Posté par . Évalué à 2.

            A mon avis il a pas essayé longtemps .... Je me rappele que lorsque je l'ai fait j'ai un peu galéré au début parce que je n'avais pas bien compris le principe, et il m'arrivait de passer des références de références ou des références sur scalaire là ou un hash était attendu (ou vice versa). Une fois qu'on a bien compris comment ça marche et qu'on sait ce que l'on fait il n'uy a pas de problème ....


            d'ailleurs lorsque je fais des choses compliquées avec des références passées à une fonction, je m'arrange pour "déréférencer" le plus vite possible mes variables pour les traiter comme des variables "normales".
            • [^] # Re: T'as tout compris

              Posté par . Évalué à 1.

              Exactement, il n'y a aucun problème pour passer plusieurs réferences à une sub. Il faut bien assimiler le concept de référence / déréfence en perl, ce qui n'est peut être pas très évident au début, mais la documentation sur ce sujet ne manque pas, je pense que tu n'as pas trop cherché.

              par contre si tu essayes de passer des array directement à une sub, tu vas certainement avoir quelques problème ...

              ps : mon exemple marche parfaitement
  • # à propos des regexp...

    Posté par . Évalué à 3.

    En lisaac, comme tout est à faire, on a le droit d'imaginer des choses intelligentes :

    Je t'invite alors à lire ce petit document très instructif sur les regexp : http://swtch.com/~rsc/regexp/regexp1.html qui permet une implémentation très rapide des regexp (sans références arrières) à base d'automates finis.

    Je ne sais pas si la lib de SmartEiffel utilise l'implémentation NFA, backtracking ou un mélange des deux... mais ça vaudrait le coup de se renseigner !

    my 2 cents
    • [^] # Re: à propos des regexp...

      Posté par (page perso) . Évalué à 2.

      attention quand même , il explique que les NFA permettent de faire des regexp qui ne peuvent pas exploser leur temps de calcul exponentiellement, mais dans la pratique, sur des regexp non pathologiques, l'implementation à base de NFA sera entre 3 et 10x plus lente qu'une implementation classique, du genre pcre. Tout en étant *beaucoup* moins puissante. ( http://gruntthepeon.free.fr/blog/index.php/2008/05/18/26-les(...) )

      En gros y'a pas de miracle.
    • [^] # Re: à propos des regexp...

      Posté par (page perso) . Évalué à 2.

      Merci beaucoup pour ce papier, j'ai commencé à le lire en pause et c'est lumineux ! En plus j'avais jamais vraiment compris le concept de NFA, enfin une explication claire !

      Je crois que je vais implémenter ça, ça sera déjà un début...

      « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

    • [^] # Re: à propos des regexp...

      Posté par (page perso) . Évalué à 3.

      Merci ! Je m'étais toujours demandé pourquoi en java les regex étaient implémentées d'un façon aussi lourde et naïve. Maintenant, j'ai une réponse (parce qu'ils proposent un peu plus que les expressions rationnelles).

      Parce qu'évidemment, pour moi, les expressions rationnelles et les automates finis, c'est tellement la même chose que je ne comprenais pas qu'on puisse faire autrement (et surtout qu'on puisse avoir idée de faire un truc manifestement pire en complexité).
    • [^] # Re: à propos des regexp...

      Posté par (page perso) . Évalué à 2.

      Pourquoi ne pas réutiliser une bibliothèque existante ? Au moins dans un premier temps.
  • # toujours sur les regexps

    Posté par (page perso) . Évalué à 3.

    Il est plus facile de faire des regexps dans le code en Perl qu'en Java, mais par contre, si on veut intégrer une regexp dans une structure de données et la pré-compiler une seule fois. (genre, si j'ai 100 regexps différentes à tester sur 10000 chaînes, éventuellement en stockant les dites regexps dans une base de données ou un fichier séparé du code), la facilité pour gérer la chose peut s'inverser.

    En Python ou Ruby (ou même en Javascript, et sans doute bien d'autres), on peut compiler des regexps et les utiliser avec plus ou moins de lourdeur (pas plus qu'en Java en tout cas), tout en ayant aussi des hashages et listes en types de "base".

    (par contre, je n'ai pas compris l'histoire des flux. En Perl comme ailleurs, ce sont des objets derrière, donc je ne vois pas ce qui distinguerait trop STDOUT de System.out)

    Bref, j'aime beaucoup ce langage, même si revenir au procédural est parfois un peu difficile,

    Rien ne t'empêche de faire autre chose avec Perl, tu sais.
    • [^] # Re: toujours sur les regexps

      Posté par (page perso) . Évalué à 3.

      Il me semble que ça marche très bien la compilation de regexps en Perl.

      J'utilise d'ailleurs ça dans certains de mes programmes…
      Un exemple :

      my @regs = ("foo", "b(a)r", "((?:i[^4<_-])|P{2,})\$");
      @regs = map qr/$_/, @regs;
      my @sent = ("foo", "ia", "bar");
      for my $r (@regs) {
      for my $s (@sent) {
      print "ok $s matched by $r\n" if $s =~ m/$r/;
      }
      }

      print "Done\n";
      • [^] # Re: toujours sur les regexps

        Posté par (page perso) . Évalué à 1.

        Je n'ai pas dit que c'était impossible, mais ce n'est pas comme si qr// était des plus explicites non plus. Sans compter, évidemment, qu'il faudra faire la gestion des erreurs (utiliser eval{} suffit, mais dans mon souvenir il me semblait que c'était plus subtil que ça). Après, on aime ou on aime pas les styles de gestion d'erreurs des uns et des autres.
        • [^] # Re: toujours sur les regexps

          Posté par (page perso) . Évalué à 2.

          Ah ouais, mais si tu demandes au code Perl d'être explicite, forcément…

          D'un autre côté, quand on oublie, un ptit "perldoc perlretut" et zou ! (ou "perldoc " si ton shell est bien), et on te rapelle tout ce que t'as oublié sur le langage…
    • [^] # Re: toujours sur les regexps

      Posté par (page perso) . Évalué à 2.

      Python conserve les 100 dernières regex compilées, mais j'aurai tendance à penser qu'il vaut stocker les versions compilées pour des performances optimales. En Python, l'API sans compilation ou après compilation est identique (ou dumoins se devine facilement : on zappe le 1er argument) :
      - m=re.match("regex", "texte")
      - x=re.compile("regex"); m=x.match("texte")
  • # javascript

    Posté par (page perso) . Évalué à 0.

    jsute parce que javascript aussi est intéressant comme langage, et permet aussi de s'amuser (un peu) avec les regexp.
    Si on prend ton premier exemple de code, ça donnerait :

    if(/(\w+)=(\d+)/.test(line)) {
      ident = RegExp.$1;
      value = RegExp.$2;
    }


    Autant dire que j'adore le fait d'avoir la regexp entre / / vue comme un objet

    Sinon il est vrai que perl c'est bien, mangez-en !
    Apprendre perl est assez intéressant, et comme beaucoup une fois qu'on a gouté aux hash à gogo, c'est sympa pour beaucoup de choses.

    Mais pour ma part j'ai remplacé tout ce que je faisais en perl pour du ruby. Tous mes scripts annexes tournent en ruby (j'entend par là tout ce qui touche à mes sources, préprocesseurs, rapports, stats, build, etc)

    Pour ce qui concerne java, pour en faire de temps en temps, je trouve aussi que c'est un mauvais langage. Ok l'ensemble de lib est intéressant, mais le langage ... beurk.
    Il faut toujours écrire beaucoup trop de choses pour avoir un truc sympa, il est trop rigide, et surtout trop pauvre. Les collections sont pas très sympa à manipuler (sauf depuis le 1.6 si je ne me trompe et foreach).
    En fait, le langage java est lourd, trop compliqué car inutilement pauvre.
    Il parait que ça s'améliore un peu, les annotations sont quand même quelque chose de sympa (même si ça existe ailleurs) mais bon...
    impossible de retourner par exemple facilement un liste de valeurs. Si une méthode doit retourner plusieurs valeurs, il faut forcément passer par une structure dédiée (si on veut pas avoir des tableaux partout comme on trouve parfois...)
    De même je crois qu'on ne peut pas passer de paramètre modifiable en java...
    • [^] # Re: javascript

      Posté par . Évalué à 2.

      "impossible de retourner par exemple facilement un liste de valeurs"
      T'as le droit de créer des listes (et de les faire renvoyer par la méthode), tu sais ?

      "De même je crois qu'on ne peut pas passer de paramètre modifiable en java... "
      Que veux-tu dire par là ? Que les paramètres reçus par une méthode ne peuvent pas évoluer au sein de la méthode ??? Première nouvelle !
      • [^] # Re: javascript

        Posté par . Évalué à 3.

        T'as le droit de créer des listes (et de les faire renvoyer par la méthode), tu sais ?

        Le résultat sera forcément moins lisible qu'écrire:
        a, b, c = ma_methode()
        pour récupérer les valeurs.
        • [^] # Re: javascript

          Posté par . Évalué à 4.

          C'est moins lisible sorti de son contexte. Par contre à l'utilisation et dans le temps c'est beaucoup plus lisible et moins casse gueule. Même si c'est moins joli graphiquement et plus rébarbatif à lire.

          Si ma fonction retourne une liste alors je déclare que ma fonction retourne une liste... Sinon c'est un objet ou un tuple. Maintenant se pose la question quelles sont les objets retournés par ma fonction. De quels types sont-ils ?

          Moi plus je sais ce que je manipule, plus c'est agréable à coder même si ca demande plus de lignes "inutiles" dans des exemples triviaux. Dans la vie de tout les jours, 80% du code que je manipule n'a pas été écrit par moi. Je préfère ne pas passer ma vie à essayer de deviner ce que les fonctions que j'appelle sont censées retourner.

          Alors quand on parle de Perl, qui ne déclare ni ses arguments si ses types de retour... Ca peut péter (et ca le fera) quand on changera le moindre type d'un argument ou d'un valeur de retour, quand le nombre/ordre des paramètres changera, quand le nombre/ordre des valeurs de retour changera. Vous refactorez jamais ? Vous faites jamais d'erreur dans votre code ? Vous attendez que ça pète à l'exécution pour découvrir que le code est dans un état totalement incohérent ?

          Comme toujours c'est marrant sur 100 lignes de code maintenu par une personne.
          • [^] # Re: javascript

            Posté par . Évalué à 1.

            Par contre à l'utilisation et dans le temps c'est beaucoup plus lisible et moins casse gueule.
            Permet moi d'en douter.
            J'ai touché à qq lgg objet (perl, java, ...) et le mythe du "tout objet" c'est génial sur le papier, mais à lire tu te dis "mais pourquoi il renvoie une liste ? Qu'est ce qu'il y a dans la liste".
            Et ensuite quant tu le lis "mais toto il était à la troisième ou à la quatrième place."

            Par contre faire un return ($force,$pression,$durée) , c'est un peu plus lisible que '

            list.add(force);
            list.add(pression);
            list.add(durée);
            return list;

            (pseudo langage que je vien d'inventer mais qui donne l'idée).


            qui ne déclare ni ses arguments si ses types de retour...
            /me viens du C où on s'amuse allègrement à changer les types malgré qu'on les a défini avant XD.
            (un petit "hack" pas beau, mais utilisé couramment : dans un thread , normalement tu renvoi un pointeur vers une structure contenant les différents arguments pour le threads. Il est courant (mais pas beau), si tu a comme argument juste un entier de faire un cast en long puis en pointeur).
            • [^] # Re: javascript

              Posté par . Évalué à 2.

              La liste est un des types existants en Java, mais sans doute pas le plus adapté dans cet exemple.
              Il existe aussi les types Hashtable, Map, ...
              Dans ton exemple, j'utiliserais plutôt des Hashtable que des listes, que chaque case contient une information totalement différente des autres (je ne parle pas forcément d'une différence sur le type).
              • [^] # Re: javascript

                Posté par . Évalué à 3.

                Ca tombe bien une table de hachage sont des structures intégrées au langages dynamiques.
                Donc un gars qui veut faire gaffe à l'ordre des arguments retournés utilisera le même chose que java en plus court et comme c'est le cas 9 fois sur 10 il va gagner beaucoup de temps.

                Donc le pb n'est pas le langage mais bien le programmeur.
                • [^] # Re: javascript

                  Posté par . Évalué à 2.

                  Java est fortement et statiquement typé.

                  Ce qui fait la force des langages de scripting à typage dynamique/failble est que tu peux facilement fourrer tout et n'importe quoi dans ta structure de données. Le langage repousse la responsabilité de faire les choses correctement vers le développeur. Si tu es statiquement et fortement typé tu ne peux et ne veux surtout pas faire ça.

                  La solution des Pair/Tuple typé via generics est la solution la moins sale si tu veux faire ce genre de choses. Mais certainement pas une hashmap ou toute autre dégueulasserie (encore une fois ce qui est acceptable et plaisant en scripting ne l'est pas pour une appli).
            • [^] # Re: javascript

              Posté par . Évalué à 2.

              > Et ensuite quant tu le lis "mais toto il était à la troisième ou à la quatrième place."

              Tu viens de découvrir pourquoi on préfère créer un vrai objet. Bravo ! Tu viens de démontrer par toi même à quel point c'est casse gueule :-)

              Comme je l'ai dit, si tu veux t'amuser avec les retours multiples, regarde du côté de javatuple. Mais >90% du temps tu veux un vrai objet.

              Rappel pour ceux qui ont raté le premier épisode: Java n'est pas un langage de scripting.
              • [^] # Re: javascript

                Posté par . Évalué à 2.

                Tu viens de découvrir pourquoi on préfère créer un vrai objet. Bravo ! Tu viens de démontrer par toi même à quel point c'est casse gueule :-)
                Oui, que cette méthode de passer par une liste X pour renvoyer plusieurs valeurs c'est casse geule, je suis tout a fait d'accord.
                (par contre, bcp moins quand c'est prévu par le lgg ;))

                Java n'est pas un langage de scripting.
                tout a fait d'accord.
            • [^] # Re: javascript

              Posté par (page perso) . Évalué à 2.

              Bah dans ce cas, je fais une classe qui contient les trois param... genre


              public class Plop {
              private Pression pression;
              private Duree duree;
              private Force force;

              .....

              constructeur(s)

              ....

              setter && getter
              }


              Et je retourne ça.

              Avec eclipse, tu écris les trois params puis generate constructor using fields + generate getters and setters et c'est fait.
              • [^] # Re: javascript

                Posté par . Évalué à 2.

                faire une classe pour _chaque_ fonction qui renvoi plusieurs paramètres... pas lourd du tout.
                (en réalité en objet, la solution est de travailler en objet pur, cad que les fonctions dépendent d'un objet, et tu met les != résultats intermédiaires nécessaires comme attribut de cet objet (ie pas une fonction "static").)
                • [^] # Re: javascript

                  Posté par (page perso) . Évalué à 4.

                  faire une classe pour _chaque_ fonction qui renvoi plusieurs paramètres... pas lourd du tout.

                  Tu extrapoles, ce n'est pas ce que j'ai dit... pour moi si tu dois retourner plus qu'un objet, je pense à la base qu'il y a un problème dans ton modèle... mais si tu dois vraiment pour x/y raison, c'est une solution, ça évite le truc dégueux de la liste avec ordre implicite ou de la hashmap fourre-tout non typée... maintenant si tu dois faire ça tout le temps, mon avis est que ton design pue un peu.
                  • [^] # Re: javascript

                    Posté par (page perso) . Évalué à 9.

                    mais m**** d'où viens cette idée que si on veut rendre plusieurs valeurs "c'est que ton code est mal pensé".
                    Arguer comme je sais plus ou dans le fil, qu'on peut se planter entre (min,max) et (max,min) est aussi débile que d'affirmer qu'on intervertira jamais min et max quand on les envoie en param de fonction.
                    Où quand je fais un string2file et que je me plante d'ordre des paramètres chaines...

                    C'est pas parce que vous connaissez que ça, et que vous n'avez jamais essayé autre chose que c'est forcément mieux que le reste !

                    Le compilateur est là pour gueuler s'il y a un problème de type, et la signature des fonctions dans la doc et dans eclipse suffit déjà pas mal.

                    Désolé, mais quand je vois le nombre de contournement interminable et hyper crade que j'observe tous les jours en java à cause de cette limitation, je trouve vraiment cet argument de mauvaise foi.


                    (J'y tiens car j'ai demandé et obtenu qu'en Lisaac, on puisse rendre plusieurs valeurs. Depuis que j'ai joué avec Caml, je supporte plus les langages rendant qu'une seule valeur(et ceux où on ne peux pas mettre une fonction en param de fonction)...)

                    « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

                    • [^] # Re: javascript

                      Posté par (page perso) . Évalué à 4.

                      On parlait de java et comment le faire "proprement" en java... et en java désolé faire ça avec au choix un array d'objet avec ordre implicite ou une liste d'objet avec ordre implicite, ça pue, pour 2 raisons, c'est non typé et l'ordre est implicite. Une hashmap, c'est un peu mieux vu que les valeurs ont un nom mais c'est encore non typé donc ça pue.

                      Pour l'exemple de min max, je ferais un inner class qui est juste une structure du genre:


                      public class MyArray {

                      __public static class MinMax {
                      ____public int min;
                      ____public int max;
                      ____public MinMax(int min,int max) {
                      ______//
                      ____}
                      __}

                      __public MinMax getMinMax() {
                      ____//
                      ____return minMax;
                      __}
                      }


                      Maintenant tout ça ça dépend... de ce que tu veux faire, du design etc

                      Tout ce que je dis c'est en java, si tu dois ramener plusieurs paramètres, le mieux est de faire comme ça... mais si tu es en java et que tu te retrouves à devoir faire ça tout le temps, ton design est mal pensé, dans tout les cas pour l'implémenter en java.

                      Je ne dis pas que ça ne sert pas de pouvoir ramener plusieurs paramètres, je dis que ça dépend de ce que tu veux faire, maintenant dans ce que je programme j'ai très rarement ce besoin et si je l'ai je ne ferai certainement jamais le retour d'au choix une liste, tableau d'objet, hashmap parce que ça sapue vraiment.
                      • [^] # Re: javascript

                        Posté par (page perso) . Évalué à 3.

                        Mais je suis totalement d'accord avec toi sur le fait que renvoyer une hash, un tableau ça pue le diplodocus faisandé ! Je dis seulement que Java est un langage pourri*, c'est tout. Bon aller, je suis gentil, le concept d'interface, cette sous m**** d'héritage multiple est une bonne idée qui force aux bonne pratiques.

                        Ce langage reprend des concepts vieux de 40 ans (allez voir simula 67) et une syntaxe bas niveau (qui était très bien, très cohérente et très moderne quand C a été conçu). J'eusse aimé que Gossling pusse exaucer son souhait de permettre aux méthodes de renvoyer plusieurs valeurs.

                        Alors oui, bah avec java, pour faire "propre" on renvoi qu'une valeur, et ça fait des archis crades. De toutes façon, en SSII, enfin la mienne en tout cas, ça passe pas la peer review des gruikitude comme ça. Donc comme je touche pas à java tant que je suis absolument contraint et forcé de l'utiliser....

                        *Fanboys de java, moinsser moi, faites vous plaisir, c'est de bon coeur ;-)

                        « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

                        • [^] # Re: javascript

                          Posté par . Évalué à 8.

                          On n'a pas besoin de te moinsser.

                          Il nous suffit juste de d'intégrer le fait que tu considères Lisaac comme le summum de l'esthétisme et de la bonne conception et on te pardonne. On en arrive même à ne pas être étonné que tu t'extasies devant du Perl ;-)
                          • [^] # Re: javascript

                            Posté par (page perso) . Évalué à 1.

                            Mhhhh, summum de l'esthétisme, je sais pas.

                            Ya des trucs qui me gonflent dans Lisaac, et qui me manque terriblement...
                            Par exemple, j'adore Caml, j'en ai pas fait beaucoup, mais j'ai été très impressionné par ce langage.
                            J'adore par dessus tout le type somme, j'en rêve dans Lisaac, mais c'est difficile à intégrer dans un paradigme objet.

                            Je trouve que du code fonctionnel est beaucoup plus esthétique : en Lisaac, tu as des horreurs du genre

                            1.to 5 do { code;};

                            Le concept de l'itérateur sur le nombre en tant qu'objet est génial, mais ça reste une boucle, et les boucles me donne envie de vomir.

                            Java est propre, c'est déjà ça de pris, mais d'être bloqué par ce for, de pas pouvoir créer de structure de contrôle, pas de compréhension de liste, pas de fonction en paramètres de fonction, cette syntaxe dépassée (qui était très bien en 1973), désolé, mais je le trouve affreux.
                            Surtout parce qu'autour de moi tout le monde s'extasie devant ce langage.
                            Bon, je leur en veux pas, ils connaissent pas grand chose d'autres (php, javascript, les langages mainstream quoi).

                            « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

          • [^] # Re: javascript

            Posté par . Évalué à 3.

            C'est moins lisible sorti de son contexte. Par contre à l'utilisation et dans le temps c'est beaucoup plus lisible et moins casse gueule.

            Il y a deux problèmes, le typage et le contenu des valeurs retournées. Pour le typage, rien n'empêche de typer chaque résultat d'une fonction qui en renvoie plusieurs, et dans ce cas je préfère la syntaxe simple que j'ai présentée au dessus.

            Pour le contenu des valeurs, il faut bien voir qu'on change la sémantique du résultat de la fonction. Même sur une fonction qui ne renvoie qu'une seule valeur, c'est problématique et ça doit être fait le moins souvent possible. Je ne vois pas vraiment ce que le fait de renvoyer deux ou trois valeurs change au problème. Ta fonction avait un sens, elle en a un nouveau, il faut modifier le code là où elle est utilisée pour refléter le changement. Est-ce vraiment plus dur parce qu'elle renvoit deux valeurs ?

            Effectivement, si la seule chose qui change c'est l'ordre dans lequel les valeurs sont renvoyées, le fait de nommer les valeurs (soit en en faisant des attributs d'un objet, soit en les mettant dans une hashtable) résout le problème. Mais concrêtement, est-ce le problème auquel on est confronté dans la vie réelle ? Un codeur ne s'amuse pas à changer l'ordre des valeurs de retour arbitrairement ; quand il change les valeurs de retour, c'est qu'il en change la signification.

            Personnellement, étant adepte du Ruby, dans lequel on peut renvoyer plusieurs valeurs, je ne fais ça que pour les cas où c'est adapté. Dès que j'ai besoin d'un objet, je fais un objet. Mais si je fais une fonction qui calcule une équation de droite (ax+b), je renvoie a et b comme valeur de retour, je ne crée pas une classe EquationDeDroite. Et comme je rédige bien sagement mes tests unitaires, ça se passe bien. Mais il faut dire que je travaille surtout tout seul :)
      • [^] # Re: javascript

        Posté par (page perso) . Évalué à 2.

        > Que les paramètres reçus par une méthode ne peuvent pas évoluer au sein de la méthode ??? Première nouvelle !

        non, mais que si tu passes un int en paramètre dans une fonction il n'est pas possible de modifier sa valeur dans la fonction et que cette valeur soit visible en dehors, au retour.
        En gros passer des références quoi...

        > T'as le droit de créer des listes (et de les faire renvoyer par la méthode), tu sais ?
        oué donc je retourne une liste (il faut donc la créer avant de le retourner, ajouter les valeurs, etc) et au retrour je lis ma liste et extrait toutes les valeurs...


        myFunc = function() {
          return [1, 2];
        }
        var [a, b] = myFunc();

        C'est quand même plus sympa, non ?
        • [^] # Re: javascript

          Posté par (page perso) . Évalué à 1.

          En gros passer des références quoi...

          int étant un type de base non-objet (ce qui donne lieu à un autre débat :)) forcément... Utilise Integer.
          • [^] # Re: javascript

            Posté par (page perso) . Évalué à 3.

            > ce qui donne lieu à un autre débat :)

            C'est bien le problème de java : un langage objet non objet, avec que des trucs chiant, juste assez bien (surtout niveau plateforme) pour l'utiliser et juste assez chiant pour le détester...
            A croire que les concepteurs ont jamais eu les couilles de faire plus qu'un langage "basique" avec rien de nouveau à part virer les pointeurs...
            • [^] # Re: javascript

              Posté par . Évalué à 2.

              Je pense que le problème de Java, c'est son origine : il a été concu à l'origine pour faire de l'embarqué, et a évolué ensuite vers ce qu'on connait aujourd'hui. D'ou le fait qu'il paraisse aussi pauvre.
          • [^] # Re: javascript

            Posté par (page perso) . Évalué à 4.

            Je suis pas un spécialiste, mais il me semble pas que Integer soit mutable... tu peux pas changer la valeur.
        • [^] # Re: javascript

          Posté par (page perso) . Évalué à 2.

          allez, histoire d'accumuler les retours et les regexp :


          // Simple regular expression to match http / https / ftp-style URLs.
          var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
          if (parsedURL) {
            var [, protocol, fullhost, fullpath] = parsedURL;
            [...]
          }


          Si ça c'est pas sympa comme code !
          • [^] # Re: javascript

            Posté par . Évalué à 1.

            en Java:

            public void maMethode(String url)
            {
            try
            {
            URL monURL = new URL(url);
            monURL.getProtocol();
            monURL.getHost();
            monURL.getPath();
            URLConnection uc = monURL.openConnection();
            // lire ici la reponse du serveur
            }
            catch(MalformedURLException e)
            {
            System.out.println("L'url est invalide, veuillez la resaisir");
            }
            }
            • [^] # Re: javascript

              Posté par (page perso) . Évalué à 0.

              De la même façons que tu le fais en java, tu peux utiliser une lib en js.

              D'ailleurs t'as pas mis la lib à inclure dans ton code.

              Envoyé depuis mon lapin.

              • [^] # Re: javascript

                Posté par . Évalué à 3.

                Ben quand la lib, c'est le runtime java, on se passe generalement de le preciser.
                Ou alors quand tu met un code snippet en JS, tu precises que le type String est fourni avec le runtime?

                Apres, si t'insistes, je peux te mettre le "import java.net.URL", la declaration de la classe, le package, nom de fichier et rajouter les tag @author, param, return etc?
            • [^] # Re: javascript

              Posté par (page perso) . Évalué à 3.

              dites les gars, vous comprenez le sens "d'exemple" ? ;-)

              je sort un exemple de regexp et tout de suite on sort un cas particulier de java (ou d'un autre langage ça change rien)

              Mais si j'avais écrit ça :

              var parsed = /^ACTION=(\w+)!IDGEO=(\w+)&USER=(\w+)!([0-9]+)$/.exec(query);
              if(parsed) {
                var [, action, id, user, userid] = parsed;
                [...]
              }

              comme exemple, ça aurait été moins intéressant...

              Et en java tu ferais quoi ?
              Une regexp ? (tout de suite c'est lourd)
              Des splits comme on voit souvent ? (beurk !!)
        • [^] # Re: javascript

          Posté par . Évalué à 1.

          "non, mais que si tu passes un int en paramètre dans une fonction il n'est pas possible de modifier sa valeur dans la fonction et que cette valeur soit visible en dehors, au retour.
          En gros passer des références quoi...
          "
          Ah oki...

          Bon, int étant un type primitif, sa valeur est passée par copie (il en va de même pour tous les types primitifs dans Java).
          Depuis Java 5, il existe l'auto-boxing, qui permet de remplacer un type primitif par son équivalent complexe (Integer pour int) et vice-versa, et cela peut même être implicite (une méthode acceptant un int acceptera aussi un Integer, sans rien avoir à modifier).
          Par contre, ces classes englobantes sont immuables.
          Du coup, on ne peut pas modifier un Integer, c'est vrai...


          "oué donc je retourne une liste (il faut donc la créer avant de le retourner, ajouter les valeurs, etc) et au retrour je lis ma liste et extrait toutes les valeurs...


          myFunc = function() {
          return [1, 2];
          }
          var [a, b] = myFunc();

          C'est quand même plus sympa, non ?
          "
          La forme est en effet assez lisible et concise... Mais pour un langage objet, je crains qu'elle ne le soit trop !
          • [^] # Re: javascript

            Posté par (page perso) . Évalué à 4.

            > La forme est en effet assez lisible et concise... Mais pour un langage objet, je crains qu'elle ne le soit trop !

            Et pourquoi un langage objet ne devrait pas être concis ??

            Il n'y a qu'à prendre ruby : objet et concis.
            Pour moi pour le moment un des meilleurs modèle objet que je connaisse (après il y en a ptetre d'autres...)


            Pour le reste, ben voilà quoi, je trouve que java est vraiment trop limité côté type "primitifs", et je comprend vraiment pas pourquoi ils ont fait ça vu les limitations que ça provoque...
            • [^] # Re: javascript

              Posté par . Évalué à 0.

              "Et pourquoi un langage objet ne devrait pas être concis ??"
              Le problème dans ce cas serait (selon moi) le suivant :
              * Soit on dit que la méthode renvoie un List mais dans ce cas, le compilateur ne sait pas quel type concret utiliser (un des types de l'API officielle Java ? Un type créé par le développeur ? Dans les 2 cas, lequel prendre si plusieurs types concrets existent) ;
              * Soit on dit que la méthode renvoie un TypeConcretList mais dans ce cas, on a un code dépendant d'un type concret et non plus d'une interface (List est une interface).

              Voilà, je ne dis pas que la solution n'existe pas, mais là comme ça, je ne la vois pas.
              • [^] # Re: javascript

                Posté par (page perso) . Évalué à 2.

                ou alors on dit qu'une méthode renvoi plusieurs valeurs et qu'on peut affecter plusieurs valeurs en même temps par similitude
                hop, le problème est réglé, la liste n'est juste qu'une écriture comme une autre pour du retour / affectation de plusieurs valeurs mais pas forcément un type en soit (dans ce cas précis)

                Le problème est bien que java est trop fermé pour ces choses et non un problème de langage objet

                En ruby par exemple :

                def foo
                  return 1, 2, 3
                end

                a, b, c = foo()


                Il n'y a pas de notation de liste, tableau ou autre, mais le principe est le même (il ne faut pas du tout se focaliser sur la notation en javascript)
                • [^] # Re: javascript

                  Posté par . Évalué à 2.

                  Donc, tu voudrais qu'on puisse écrire ceci :

                  public TypeA, TypeB, TypeC maMethode()
                  {
                  [...] // On déclare et on utilise les variables a, b et c
                  return a, b, c;
                  }

                  // Utilisation de la méthode avec triple-renvoi
                  a1, b1, c1 = maMethode();

                  Faut voir... Là comme ça, je vois surtout le travail qu'il y aurait à faire au niveau du compilo (parce qu'un tel truc n'a jamais été envisagé).


                  Par contre, ton exemple en ruby me fait peur ! Comment savoir combien et de quels types seront les paramètres de retour d'une méthode ?
                  • [^] # Re: javascript

                    Posté par . Évalué à 3.

                    Si si ca à été envisagé. Gossling à d'ailleurs dit qu'il regrettait de ne pas l'avoir fait à la base.

                    There are a bunch of things that I'd do differently. There are a number of things that I'm not entirely happy with and it's not clear what the right answer is. I'm not really happy with the schism between interfaces and classes; in many ways it feels like the right solution wouldn't get in the way.

                    There have been a number of things -- like, for example, multiple return values -- that these days I kind of wish I had added. That was one where I really liked the feature and most other people just sort of went, "Huh?"

                    Il y a d'ailleurs eu quelques RFE n'ont pas eu de suite puisqu'il faudrait péter la compatibilité de la VM pour le supporter. Normalement pour le langage ca peut rester compatible (de mémoire).

                    Si tu veux jouer avec ca, regarde du côté de javatuple: http://javatuple.com/index.shtml
                  • [^] # Re: javascript

                    Posté par (page perso) . Évalué à 2.

                    Oui, c'est exactement ça. La liste (ou le tableau) est en général là pour pallier au manque dans le langage, et comme tu dis c'est surement dur à implémenter. Mais quand je code dans un langage de haut niveau, le compilo je m'en fou un peu, son boulot est justement de me faciliter la vie pas le contraire.

                    Pour ce qui est du ruby, pour ma part avec des langages de ce genre et des fonctions idem ... ben c'est documenté en codant est la doc est mise à jour (javadoc and co) Ca reste un moyen correct même si pas parfait...
    • [^] # Re: javascript

      Posté par . Évalué à 2.

      Les collections sont pas très sympa à manipuler (sauf depuis le 1.6 si je ne me trompe et foreach).
      Les collections etaient effectivement particulierement pete couille jusqu'a java5 et l'apparition des generics.
      Le pb est que l'implem des generics est mauvaise (tu te tapes vite la tete contre les murs quand tu pousses un peu l'utilisation) et for each est foireux, car pas possible de modifier la collection "foreachee": ca cree un Iterator behind the scenes, et malheureusement, tu n'a pas acces a cet iterator, donc modif = ConcurrentModificationException dans la face.
      Sur ce point la, tu as tout a fait raison.
      Le probleme la est que Sun a les petoches de casser quoi que ce soit niveau compat avec java1.4/5 et anterieurs, et qu'on se traine donc des boulets.
      A mon humble avis, faudrait qu'ils prennent leurs couilles a deux mains, cassent la compat' en disant "desole pour les familles, tout ca, mais merci pour tout l'poisson, hein", nous mettent des vrais generics, des vrais getter et setter (ie des properties, pas des methodes, cf ActionScript) et autres choses sympatoches.

      Il parait que ça s'améliore un peu, les annotations sont quand même quelque chose de sympa (même si ça existe ailleurs) mais bon...
      C'est pas qq chose de sympa, c'est juste de la balle. Les annotations spring et hibernate me rendent la vie infiniment plus facile au quotidien

      impossible de retourner par exemple facilement un liste de valeurs.Si une méthode doit retourner plusieurs valeurs, il faut forcément passer par une structure dédiée (si on veut pas avoir des tableaux partout comme on trouve parfois...)
      Alors la par contre...
      Ce que tu veux faire est une grouikerie sans nom. Je trouve ca dans le code au boulot (ie une List non typee avec ungros bordel dedans), c'est 10 coups de trique en publique pour le cochon qui a commite ca).
      Non, une methode retourne un et un seul objet. Ou rien du tout.
      Non, elle ne modifie pas un tableau passe en entree comme ca se fait en C.
      Ce genre de choses sont simplement degueulasses, c'est gerable en langage de script parce que tu vas avoir qq centaines de lignes ecrites par la meme personne, ca se fait en C parce qu'on peut pas trop faire autrement, mais dans un langage objet haut niveau, c'est a proscrire.

      Une methode retourne un objet. Si elle doit retourner plusieurs choses qui ne sont pas liee (ie, qui ne sont pas membres d'un meme objet), c'est que ton design est a chier, ta methode fait beacuoup trop et tu DOIS la splitter en plusieurs autres methodes. et si tu vois pas l'interet de le faire, soit tu n'utilises pas le bon langage, soit t'es trop con. Je vote plutot pour la reponse 1, mais la 2 se voit quand meme de temps a autres.
      Alors, ouais, ca implique plus de code, mais au moins ca te met des gardes fous, ton code ne va pas peter parce que jean guy a patcher la fonction et a change l'ordre des parametres.
      • [^] # Re: javascript

        Posté par . Évalué à 3.

        C'est marrant on dirais que tu n'arrive pas a imaginer autre chose que Java.
        Pourquoi multiples valeurs de retours voudrais dire pas de contrôles des types ?

        Il est vrai que je ne connais pas de langage implémentant les deux concepts, mais rien n'empêche de le faire:

        public final (int, String) foobar(String foo) {
        // snip
        }
        • [^] # Re: javascript

          Posté par . Évalué à 0.

          Je parlais de list non typee, car on parlait de java ici, et en l'occurence, si ta liste contient plusieurs trucs differents, elle est non typee.

          Un n-uplet est plus ou moins un type, mais ca ne resoud pas le pb conceptuel de la grouikerie: soit tu retournes un ensemble coherent de valeurs, et dans ce cas tu as un objet pour les encapsuler, probleme resolu, soit tu retourne des trucs qui n'ont rien a voir, et tu veux faire une immondice.

          Je comprends tout a fait que cette immondice est parfaitement gerable et acceptable dans certain cas (je pense notamment a des petits code, genre scripts ou autres, ya surement d'autres trucs auquels j'ai pas pense), mais ca n'a clairement pas sa place dans un langage comme java.
          • [^] # Re: javascript

            Posté par (page perso) . Évalué à 6.

            Non, tu parlais de valeurs de retours multiple. Java ne le gère pas et une des manière de coutourner ce manque : renvoyer une liste, est particulièrement dégeulasse.
            Mais Java gère les séries de paramètres typées ainsi qu'un valeur de retour typée, qu'est-ce qui empêche de gérer une série de valeur de retour typées ?

            Je ne vois pas ce qu'il y a de degeulasse dans les valeurs de retour multiples, bien au contraire, ça évite la création de miriades de petits objets qui ne servent à rien d'autre.
            Par contre, il faut bien sûr le faire correctement, c'est-à-dire typé.

            Si tu est contre les valeurs de retour mutltiple, comment fais-tu pour tolérer les paramètre multiple ? Pourquoi ne pas passer tous les paramètres dans l'objet ?
        • [^] # Re: javascript

          Posté par (page perso) . Évalué à 1.

          Si Sather implémentait le retour multiple sans définir de type à l'aide de tuple. C'est exactement ce que tu as écrit (a la syntaxe type Eiffell près).

          D'ailleurs, c'est marrant, dès qu'on parle Lissac ici, je sors mon Sather;-)
      • [^] # Re: javascript

        Posté par (page perso) . Évalué à 2.

        pour la première partie, c'est exactement ce que je pense (sauf que je me suis trompé de version...) qu'ils ont pas la volonté suffisante d'améliorer le langage.

        Pour la deuxième partie je suis moins d'accord.
        Le "problème" est qu'on nous a toujours appris qu'une fonction doit retourner 0 ou 1 objet. Mais pourquoi donc ? Est-ce vraiment si obligatoire ? Ne peut on pas réfléchir un peu et faire autrement, aller plus loin ?

        Imaginons que dans un programme on ait un tableau de valeurs numériques. On veut à un moment donné obtenir les bornes (ie min et max du tableau)
        On peut évidemment parcourir 2 fois le tableau et renvoyer une fois le min, une fois le max.... mais si ces valeurs sont faites pour être utilisées en même temps, c'est un peu idiot.
        Pourquoi ne pas avoir une fonction "getMinMax" qui nous retournerais le min _et_ le max du tableau ?
        C'est pas hyper tordu, c'est logique mais c'est interdit pour quelle raison ? parce qu'on peu _aussi_ écrire de la daube avec ? Pour moi c'est pas une raison on peut écrire de la merde avec n'importe quel langage...
        Et dans le cas min/max créer un objet pour ses valeurs serait complètement idiot, inutile à mon avis.

        (et sinon les langages de script c'est pas que pour les petits programmes à la con de quelques lignes, pour le moment je bosse surtout avec un langage interprété, à prototype et il fait un peu moins de 60 000 lignes sans les libs...)
        • [^] # Re: javascript

          Posté par . Évalué à 3.

          Je connais pas trop les langage non objets, donc je m'abstiendrais d'en parler.

          Dans un langage objet par contre, par essence, tu vas passer par des classes pour ce genre d'operations (ie, tu ne vas pas utiliser une "fonction" mais une methode d'une classe).
          Deja en java, utiliser un tableau, c'est pas courant. Tu vas utiliser une List ou un Set suivant le besoin. List et Set qui sont des classes et peuvent donc avoir des methodes, a tout hasard getMin et getMax.
          Tu peux creer une classe ManipulateurDeList qui prend une list ou tableau en input ou quoi que ce soit d'autre.
          La philosophie voudrait meme que tu utilises l'interface Comparable pour pouvoir appliquer getMin et getMax a autre chose que des valeurs numeriques. Ca prend une autre dimension, c'est plus complique, mais ca tombe bien, c'est utilise pour faire des choses complique, pas pour faire des choses simple vite fait.

          Si tu as *besoin* de retourner 2 objets, c'est que ta structure d'objet et/ou ton api sont mauvaises.
          Disons que tu vas pas creer une classe rien que pour ca en codant ta methode, tu vas te poser et reflechir avant meme de faire la classe en question et reflechir a son API. Si ca arrive, tu es totalement passe a cote des fondements des langages pur objets.
          Oui, c'est chiant, et c'est pour ca que l'objet pur est lourd a utiliser, faut avoir une bonne raison de faire de l'objet pur.
          Je veux bien croire qu'il ya qq cas specifique limites, mais ca ne justifie pas de faire rentrer une immondice pareille dans le langage.

          Je sais pas si tu maitrises bien les langages objets ou pas (aucune animosite ni condescendance), mais j'ai comme l'impression que tu abordes les langages objet avec une philosphie imperatif: forcement ca va pas passer (je te rassure, je ferais tres certainement pareil dans l'autre sens).

          Le probleme que je vois avec les retours multiples, c'est que si tu retournes un n-uplet (int, int, int), tu n'as pas la moindre idee de ce qu'est chaque parametre.
          C'est une grouikerie parce que ca te permet de coder au kilometre sans meme penser aux implications de ton code ,comment il va etre utilise ou comment il va etre maintenu.
          Avec un objet, tu vas faire un getMin() et t'es sur de pas te planter.
          Avec une structure tu vas faire un retour.min, et pareil, sur de pas te planter.
          Avec un n uplet tu fais un retour.get(0) sans plus d'infos, c'est du code qui ne demande qu'a te peter a la gueule. Jean Rene va passer par la, modifier le code, ca va te retourner (max, min) au lieu de (min, max) parce qu'il a patche a 4h00 du matin, et tu va mettre 2 jours a trouver le bug.
          Pendant ec temps la, moi je bosse^W troll sur LFR.

          A la rigueur, faire des trucs comme en actionscript/javascript: retourner un objet dynamique (ie avec des membres cree a la volee), ca parait un compromis raisonnable. Mais conceptuellemet, c'est pareil, t'as juste une souplesse a l'utilisation de creer ta classe dynamiquement.

          Sinon, pour les liste de parametres, j'ai du mal a voir l'interet, peut etre que je suis trop idiot ou ferme. Toujours est il que je trouve ca tres crade aussi.
          • [^] # Re: javascript

            Posté par (page perso) . Évalué à 3.

            mouais, j'aurais tendance à dire que c'est justement la réponse d'un codeur java ;-)

            Si j'ai des données qui sont un tableau d'entier (juste un tableau, pas autre chose, pas de liste, pas de hash, etc) ça fout un bordél énorme juste pour un min max...
            Et ça ne corrige toujours pas le fait que getMin va parcourir mon tableau et getMax aussi alors que c'est totalement idiot

            Et le coup du max,min qui devient min,max...
            Quel est la différence entre la déclaration de valeur(s) de retour et la déclaration des paramètres ?
            Et en l'occurence j'aurais tendance à penser que getMinMax retourne min, max et getMaxMin retourne max, min

            > une immondice pareille dans le langage
            > tres crade

            Etrange, c'est justement ce que pense beaucoup de programmeurs java...

            Pour l'histoire de langage objet, etc c'était surtout pour présenter un exemple simple. D'ailleurs mon getMinMax est par exemple une méthode de classe.

            Mais dans un programme ou, sur mon tableau, jamais je n'utiliserai min sans max (voyons ça comme des limites) pourquoi je devrais utiliser deux méthodes différentes ?
            C'est là qu'on a un comportement illogique et consommateur de resources.
            Ou alors je sais pas, je fais un myArray.calculateMinMax() suivit de myArray.getMin() et myArray.getMax() ? Là ça pue !


            Pour ce qui est de faire de l'objet pur, etc, voir le modèle objet de ruby, il est assez bien foutu, va beaucoup plus loin que celui de java entre autre.
            • [^] # Re: javascript

              Posté par . Évalué à 4.

              mouais, j'aurais tendance à dire que c'est justement la réponse d'un codeur java ;-)
              Possible, j'en suis un apres tout :)

              Et ça ne corrige toujours pas le fait que getMin va parcourir mon tableau et getMax aussi alors que c'est totalement idiot
              Probleme d'implementation, getMin et getMax peuvent faire appel a private computeBounds().
              C'est l'interet de l'objet : pouvoir encapsuler tout ca.
              Si le min est toujours utilise avec le max, tu calcule les 2 en meme temps, sinon tu les separes.

              Quel est la différence entre la déclaration de valeur(s) de retour et la déclaration des paramètres ?
              La difference, c'est que tu recuperes 2 entiers, pas un min et un max. Tu ne peux pas differencier les deux sans lire la doc ou le code de la fonction.

              Et en l'occurence j'aurais tendance à penser que getMinMax retourne min, max et getMaxMin retourne max, min
              Ou pas.
              Sur ce cas tres particulier, c'est effectivement dur de penser le contraire. Mais tu te reposes sur une convention, et ca rend ton code plus sujet a gros bug.
              Et si tu rajoute la moyenne et l'ecart type, tu fais quoi? getMinMaxAverageEcartType? sympa ta fonction dis donc.

              jamais je n'utiliserai min sans max (voyons ça comme des limites)
              Ce sont des limites qui sont lies l'une a l'autre?
              Ca n'est pas donc pas un n-uplet, mais une limite, qui est un objet avec une semantique et des metodes particuliere: ca justifie clairement une classe.

              Cree alors une classe Bounds retourne la: tu auras un modele plus robuste et evolutif.
              Tu n'as pas besoin de modele robuste et ca t'emboucanne tout ca?
              Java ne repond donc pas a ta problematique, tout simplement.
              • [^] # Re: javascript

                Posté par . Évalué à 2.

                La difference, c'est que tu recuperes 2 entiers, pas un min et un max. Tu ne peux pas differencier les deux sans lire la doc ou le code de la fonction.

                Du coup, on ne devrait pas avoir de méthode avec de multiples arguments parce que l'on ne peut pas les différencier sans regarder la doc ?

                Non mais n'importe quoi.

                Quand je vois les solutions proposée pour résoudre un simple retour de (min, max), je ne suis pas étonné que les programmes Java soit aussi lourd.

                Je suis toujours surpris de voir à quel point Java "rigidifie" l'esprit des codeurs. En fait, avec Java, on perd énormément d'expressivité, parce qu'il ne faudrait surtout pas laisser une partie de la responsabilité de la qualité du code aux devs. Et le pire, toutes ces contraintes n'empêchent pas de pondre du code immonde. Autant utiliser autre chose si on a le choix.
                • [^] # Re: javascript

                  Posté par (page perso) . Évalué à 2.

                  Tout à fait d'accord. Si le problème est l'ordre des valeurs renvoyées, alors plutôt que de ne pas utiliser un principe utile (les valeurs multiples) pourquoi ne pas rajouter au langage un moyen de ne pas se tromper ?

                  Par exemple en lisp ça donnerai quelque chose comme ça :

                  (ma-fonction (...)
                    ...
                    (values :min -10 :max 20))

                  (values-bind (:min min :max max) (ma-fonction)
                    ... utilisation de min et max ...)

                  ou :

                  (values-bind (:max max :min min) (ma-fonction)
                    ... utilisation de min et max ...)


                  Il n'y a plus besoin de savoir dans quel ordre ma-fonction retourne les valeurs min et max puisque ces valeurs sont nommées. La fonction values-bind n'existe pas dans le standard mais elle est très facile à coder.
                  • [^] # Re: javascript

                    Posté par . Évalué à 2.

                    Je connais pas grand chose au Lisp mais en gros ca s'apparente à une table de hachage comme une pratique courante en Python

                    Tu peux adopter avec Java aussi cette solution de facilité même si ce n'est pas supporté par la syntaxe du langage, tout les retours de paramètres multiples ne sont rien d'autre que des tuples en Python
                    Juste qu'on t'explique que dans le monde objet on préférera utiliser un vrai type de données, une classe en guise de retour qui supporte le contrat et rien que le contrat. On garantit l'encapsulation dès le départ.
                    Si tes besoins évoluent par la suite,
                    genre je rajoute, un troisième champ eh ben c'est vrai avec un Hashmap .... l'ancien code appelant marche toujours.

                    Maintenant je veux pouvoir pouvoir rajouter des comportement à ce résultat comme par exemple le rendre sérialisable. .... et puis on s'aperçoit que finalement la table de hachage c'est pas si bien que ca parce que ca rame parce qu'il manque des trucs ou simplement parce tien un nouveau type qui fait tout ca existe dans le langage
                    Les sets python sont bien utiles mais n'existaient pas dasn les premières versions
                    http://docs.python.org/library/sets.html
                    soit on surcharge alors les Hash qui devient un vrai type.
                    Avec Python tu vas commencer a surcharger les built'in types, ...
                    Mais dès le départ tu as fait un choix sur la structure de donnée , peu importe que cette structure fasse partie intégrante du langage ou non.
                    Or mon contrat disait que je voulais getMin, GetMax,GetMinMax et pas getKeys, get Values, getDict...
                    Manque de bol, partout dans mon code appelant je les ai utilisés et maintenant que j'ai choisi d'utiliser des Sets, je suis marron.
                    En plus ma lib a été diffusée et j'oblige également tous mes clients à s'aligner.

                    Je suis d'accord, est-ce que le jeu en vaut la chandelle , tout est affaire de compromis entre résultat à court terme et évolutivité.
                    Je suis d'accord que, qui peut le plus peut le moins et qu'un langage plus souple n'empêche pas la rigueur.
                    Mais il ne faut pas sacrifier les bonnes pratiques.
                    • [^] # Re: javascript

                      Posté par . Évalué à 2.

                      "Or mon contrat disait que je voulais getMin, GetMax,GetMinMax et pas getKeys, get Values, getDict..."
                      Dans ce cas, n'aurait-il pas mieux valu (en Java en tout cas) créer un type qui contient la hashtable, plutôt qu'un type qui l'étend ?
                      Parce que l'héritage, c'est bien beau mais ça peut vite coincer (entre autre, parce qu'on ne peut pas faire de l'héritage multiple et que l'on a peut-être déjà étendu une autre classe).
                      Selon moi, un tuple contient un type particulier (la hashtable) pour gérer sa tambouille interne, mais n'est pas ce type.
                      • [^] # Re: javascript

                        Posté par . Évalué à 2.

                        Oui la composition c'est mieux mais ce que j'expliquais c'est que si dès le début tu as choisis de retourner une HashTable tu n'as pas d'autres solutions que l'héritage. Raison de plus pour créer un type de retour dès le départ ou d'implémenter une interface avec getMin et getMax
            • [^] # Re: javascript

              Posté par (page perso) . Évalué à 3.

              Ou alors je sais pas, je fais un myArray.calculateMinMax() suivit de myArray.getMin() et myArray.getMax() ? Là ça pue !

              Non tu fais simplement un truc qui calcule ton minmax une fois au moment du getMin ou getMax et l'appelle à l'autre ramène la valeur calculée précédemment, si l'état interne du tableau change (donc que tu dois recalculer min ou max) tu mets le boolean et à un appel de getMin ou getMax tu refais le calcul en sauvant dans l'état interne de l'objet le min et le max.


              int min;
              int max;
              int minMaxValid = false;

              private void recalculMinMax() {
              __if (!minMaxValid) {
              ____...
              ____minMaxValid = true;
              __}
              }

              public void getMin() {
              __recalculMinMax();
              __return min;
              }

              public void getMax() {
              __recalculMinMax();
              __return max;
              }

              public void changeUnTrucDuTableau() {
              __// ...
              __minMaxValid = false;
              }
              • [^] # Re: javascript

                Posté par (page perso) . Évalué à 3.

                > Non tu fais simplement

                Non mais sérieux, c'est pas quelque chose de simple ton truc.
                C'est inutilement compliqué ça

                Surtout que cette solution oblige aussi à redéfinir _toutes_ les méthodes d'accès (en écriture, push, etc) du tableau.

                Imaginons que je veuille rajouter mon getMinMax à une classe de tableau. Je vais faire une nouvelle classe héritant de mon tableau.

                Avec ma solution je défini _une_ méthode qui fait ce que je veux -> le code est clair, très compréhensible, concis mais pas inutilement, très facile à maintenir.

                Si j'utilise cette solution je commence par définir _trois_ méthodes (recalculMinMax, getMin, getMax) et je surcharge _toutes_ les autres méthodes modifiant l'objet pour changer mon booléen de modification.
                Le code est lourd, complexe, chiant, inutilement long, plus compliqué à maintenir.

                Et si j'ajoute une fonctionnalité dans ma classe mère :
                - avec ma solution celle ci est dispo tout de suite dans ma classe fille, sans modifier une ligne de code
                - avec la solution "java" ... ça dépend. Si cette méthode est une méthode d'accès, alors ça roule. Si par contre c'est une méthode de modification ... ben soit je l'utilise telle quelle et mon getMin / getMax est foutu, soit il faut que je la resurcharge dans ma classe fille.
                Ca devient très vite le bordel et on est justement dans un cas où le système se casse la gueule en maintenance, car une autre personne que celle qui a écrit le premier code va rajouter la fonctionnalité dans la classe mère et ne comprendra jamais pourquoi son getMin / getMax est devenu tout pourri et ne renvoi pas les bonnes valeurs.



                ps : pour tous ceux qui veulent include du code dans un commentaire :
                s/ / /g et ça roule !
                • [^] # Re: javascript

                  Posté par (page perso) . Évalué à 4.

                  oups

                  s/ /&nbsp;/g
                  • [^] # Re: javascript

                    Posté par . Évalué à 1.

                    Euh je pense qu'il fallait prendre son post au second degré
                    • [^] # Re: javascript

                      Posté par . Évalué à 2.

                      Pourquoi ça ? (vraie question)

                      Sa solution fonctionne : elle repose juste sur un booléen en interne qui permet de ne pas refaire un traitement pouvant être long (rechercher le min et le max d'un tableau, ...) inutilement. Je ne vois pas ce qu'elle a de complexe/débile/whatever
                      • [^] # Re: javascript

                        Posté par (page perso) . Évalué à 4.

                        J'espère que tu es ironique malgré le "(vraie question)"...

                        Cette solution impose de surcharger toutes les méthode qui modifient le tableau, ce qui veut dire :
                        - ralentir toutes les modifications du tableau, un appel surchargé à un coût non-néglgeable quand il est fait régulièrement ce qui est souvent le cas pour les modifications de tableaux ;
                        - rendre la maintenance très complexe, la personne qui maintien le code du tableau n'est pas forcément au courrant de toutes les classes dérivées.

                        Tout ça juste pour une solution soit-disant "propre" alors que les valeurs de retour multiple serait bien plus simples et beaucoup moins complexes à gérer et maintenir.

                        Avec les retours multiple on a une fonction d'une vingtaine de lignes pour laquelle une entrée dans la doc est suffisante et dont la maintenance est simple.

                        Avec la solution java, on a une base d'un quarantaine de lignes plus quatre ou cinq lignes par fonctions d'acces. La doc deviens beaucoup moins simple et la maintenance est galère car le dev doit surveiller toutes les modif de la classe de base et vérifier qu'il n'y a pas de nouvelles fonctions d'accès à surcharger.

                        On perd la transparence de l'aspect objet, la fonction minmax deviens bien plus dépendante de l'api exposée par la classe de base.

                        De plus, au départ la fonction minmax éxiste pour éviter de faire deux fois le coûteux parcours du tableau, mais vu que tous les acces deviennent plus coûteux le gain final est négatif.

                        Bref, mauvaise solution.
                        • [^] # Re: javascript

                          Posté par . Évalué à 4.

                          Je suis désolé mais en quoi ce qui est décrit par Crev ici
                          http://linuxfr.org/comments/1000473.html#1000473 sous-entend qu'il ne va pas reparcourir le tableau en dynamique à chaque fois qu'il appelle getMinMax.

                          En java tu peux créer une classe interne MinMax adapté
                          comme ici
                          http://linuxfr.org/comments/1000492.html#1000492

                          C'est peut -être plus lourd mais par la suite tu voudra aussi l'écart type, la variance et ta belle solution de multi-liste t'obligera à un moment à tout refactoriser ton code appelant.
                          Par la suite on peut se créer une vraie classe qui supporte ce contrat sans tout péter.
                          L'autre solution est que ta classe supporte ce contrat via un interface.
                          Si j'ai défini le bon interface avec getMin, getMax ou une classe dédié peu importe que par la suite je mette en cache ou non un booléen, que je place un Observer puisque c'est encapsulé.
                          En plus il n'y a pas de surcharge de toutes les méthodes comme la solution proposée plus haut ici.

                          Toi avec tes 2 variables en sortie non typée faudra que tu pètes tout le code appelant ou que tu gardes getMinMax par rétrocompatibilité ad vitam eternam mais c'est vrai que quand on est à la bourre c'est plus rapide d'aller au plus simple.

                          Bref tout ca se discute.
                          Java permet moins de faire de conneries au prix d'une certaine lourdeur.
                          Les langages ala pyhton &co permettent plus de souplesse mais parfois au détriment de l'évolutivité.
                          Là où c'est paradoxal , c'est que c'est justement des langages qui devraient être réservés à des programmeurs expérimentés qui séduisent aussi les néophytes.
                          • [^] # Re: javascript

                            Posté par (page perso) . Évalué à 2.

                            > 2 variables en sortie non typée

                            ra mais c'est pas vrai, vous le faites exprès ?

                            Un retour de fonction en java est bien typé, non ?
                            Donc si on permet d'avoir plusieurs valeurs de retour, pourquoi ça deviendrait non typé par magie ?
                            Pourquoi ne pas imaginer :
                            public int min, int max getMinMax()
                            ?

                            Et après, franchement pour sortir un min et un max en même temps s'il faut sortir une sous classe, une interface spécifique, coller un observer, etc ... ben en fait je comprend de plus en plus le journal de Ploum... http://linuxfr.org/~ploum/27723.html
                            • [^] # Re: javascript

                              Posté par . Évalué à 2.

                              Ca on le sait mais 2 int ca ne fait pas un type abstrait de données
                              • [^] # Re: javascript

                                Posté par . Évalué à 2.

                              • [^] # Re: javascript

                                Posté par (page perso) . Évalué à 0.

                                typedef int min;
                                c'est bon là ?

                                non mais c'est bien rigolo votre truc, mais si tu écris une fonction getMax qui s'appuie sur un tableau tu va créer un type pour ça ou retourner un entier (si je n'ai qu'un tableau d'entier) ?

                                M'enfin, tout ça pour ce qui est à la base un exemple, juste des contraintes prises comme ça pour expliquer que ça peut servir, mais ça fout tellement les boules aux codeurs java que ça en devient ridicule.

                                - Bonjour je voudrais calculer simultanément et retourner le min et le max d'un tableau d'entier.
                                - Ok, tu fais une classe interne, un observer, deux ou trois ko de code et ça roule. autre chose ?
                                A oui, on pourrait faire plus simple mais tu vois c'est pas drole, on se ferai chier, c'est pas bien, c'est une erreur, c'est toi qui sait pas, c'est pas propre, c'est trop compliqué pour un neuneu (rayer les mentions inutiles)
                                • [^] # Re: javascript

                                  Posté par . Évalué à 1.


                                  typedef int min;
                                  c'est bon là ?


                                  Non mais c'est pas grave, fais toi plaisir
                                  • [^] # Re: javascript

                                    Posté par (page perso) . Évalué à 2.

                                    ok

                                    > Ca on le sait mais 2 int ca ne fait pas un type abstrait de données

                                    Mais je ne veux pas un type abstrait, je veux que ma fonction retourne plusieurs valeurs.

                                    Mais bon, faut croire que c'est si sympa de créer tout un bordel pour ça...
                                    • [^] # Re: javascript

                                      Posté par . Évalué à 0.

                                      Et bien, tu veux quelque chose de crade sur le long terme et de pas evolutif pour un sou.
                                      Bon courage dans 2 ans pour rajouter la moyenne et l'ecart type sans tout peter.

                                      On te l'a indique plus haut, t'as plusieurs choix, casser l'api en refactorer le nom de la fonction (mais c'est tes clients qui vont gueuler) ou casser la coherence de ton api en rajoutant getMoyenneEcartType (c'est tes clients qui vont gueuler aussi la) ou le pire du pire, rajouter les valeurs a getMinMax sans toucher au nom (m'est avis que ca va gueuler aussi).

                                      Bref, tout est question de compromis, ca peut etre gerable de faire ce que tu veux, maintenant faut voire que java est enormement utilise en entreprise, que le code metier en entreprise est appele a evolue en permanence, que la compatibilite avec l'existant est generalement critique, donc on peut pas se permettre ce genre de grouikerie.

                                      Quand a l'appel surcharge a add() sur la collection, je me gausse, on parle de setter un booleen la, une ligne de code, une petite affectation toute simple, si t'es rendu a ce niveau d'optimisation, elle est belle ta vie. Avec un peu de chance, le JIT va meme se rendre compte que l'affectation peut etre zappee dans 99% des cas et tu verras rien.
                                      • [^] # Re: javascript

                                        Posté par (page perso) . Évalué à 1.

                                        > crade sur le long terme et de pas evolutif pour un sou

                                        faut voir, j'ai plutôt tendancer à penser qu'un code simple _immédiatement_ est justement plus facile à faire évoluer car il est beaucoup moins complexe à comprendre et moins source de problème.

                                        Mais combien de programmes sont inutilement compliqués derrière des "mais si dans x années qqn code un truc non voulu, non prévu et si il le fait pas exactement comme il faut, ne respecte pas les conventions, etc" ?
                                        C'est bien de vouloir prévoir les cas, mais combien ne se produiront _jamais_ alors que ça aura complexifié le code ?

                                        sinon, pour le getMinMax ecart type toussa, j'ai pas vu la solution (pourtant si chère aux programmeurs java) je prend eclipse refactor toussa et hop rulez ! le fait que j'ai utilisé ailleurs ou non mon minmax est automatiquemnt trouvé / modifié / etc

                                        > Quand a l'appel surcharge a add() sur la collection, je me gausse, on parle de setter un booleen la, une ligne de code, une petite affectation toute simple, si t'es rendu a ce niveau d'optimisation, elle est belle ta vie

                                        Là je pense que t'as pas du saisir ce que je disais. Je n'ai rien contre le fait de rajouter un booléen mais contre le fait de devoir surcharger _toutes_ les méthodes de modification de ma classe.
                                        Si je rajoute une méthode de modification dans ma classe mère alors il _faut_ que je la surcharge dans ma classe fille.
                                        Et toi qui parle de maintenance / évolutivité à qq années, c'est bien pire que de savoir comment je pourrai un jour rajouté un écart type
                                        C'est typiquement le genre de chose qui sera oublié et là l'intégralité des résultats de mon getMinMax sera faux et pour comprendre d'où ça vient rapidement...
                                        • [^] # Re: javascript

                                          Posté par . Évalué à 3.

                                          Mais combien de programmes sont inutilement compliqués derrière des "mais si dans x années qqn code un truc non voulu, non prévu et si il le fait pas exactement comme il faut, ne respecte pas les conventions, etc" ?
                                          Et parfois ce genre de contraintes est mise sur le cahier des charges.
                                        • [^] # Re: javascript

                                          Posté par (page perso) . Évalué à 3.

                                          Là je pense que t'as pas du saisir ce que je disais. Je n'ai rien contre le fait de rajouter un booléen mais contre le fait de devoir surcharger _toutes_ les méthodes de modification de ma classe.
                                          Si je rajoute une méthode de modification dans ma classe mère alors il _faut_ que je la surcharge dans ma classe fille.


                                          Non c'est faux... si on ne peux accéder à l'état interne de la classe mère que par les méthodes (public ou protected) auquels elle donne accès (et que dans toutes ces méthode la classe mère, le booléen est setté correctement), tu n'as pas à faire ça... car si dans ta classe enfant tu modifies l'état interne de la classe mère tu es forcément passer par une méthode de la classe mère qui elle gère ce booléen, maintenant si tu laisses la classe enfant directement dépatouiller l'état interne de la classe mère (des fields en protected ou package private) alors là oui, elle (la classe fille) devra se soucier du flag... mais ça c'est de la mauvaise encapsulation, ta classe enfant ne devrait pas pouvoir le faire sans passer par des méthodes de la classe mère qui gère le flag, donc quand c'est bien fait, le truc que tu racontes est simplement et purement faux.
                                          • [^] # Re: javascript

                                            Posté par (page perso) . Évalué à 2.

                                            ra mais c'est pas vrai ça

                                            Non c'est vrai !

                                            > la classe mère qui gère le flag
                                            non, c'est la classe fille !

                                            > quand c'est bien fait, le truc que tu racontes est simplement et purement faux
                                            ben non, si c'était bien fait on aurait pas à faire toutes ces conneries de java


                                            Allez on reprend pour ceux du fond qui ne suivent pas.

                                            disclaimer : ceci est un exemple, pour comprendre, qu'on me sorte pas des conneries de collection ou autre c'est pour expliquer un principe, une logique, non pour écrire un exemple réel (j'suis pas sur que tout le monde ait compris ça déjà...)

                                            Imaginons une classe de tableau : (ha oui, j'écris ni en ruby, ni en java, ni en js, etc c'est juste pour comprendre sans s'en soucier, et oui j'ai pas mis de test, de validation, etc on s'en branle)

                                            class Array

                                              def get index
                                                return data_au_bon_index
                                              end

                                              def set index, value
                                                data_au_bon_index = value
                                              end
                                            end


                                            Maintenant j'ai deux classes utilisant ceci, en rajoutant des besoins spécifiques et non nécessaires à tous (oui les noms sont pourris je m'en fou aussi c'est un exemple) :

                                            class ArrayWithExtraFunctionnality1 < Array
                                              def plop
                                                [...]
                                              end
                                            end

                                            class ArrayWithMinMax <Array
                                              def getMinMax
                                              end
                                            end


                                            Version sympa :

                                            class ArrayWithMinMax < Array
                                              def getMinMax
                                                [...]
                                                return min, max
                                              end
                                            end


                                            Version "java"

                                            class ArrayWithMinMax < Array
                                              boolean internalStateModified = false

                                              def getMin
                                                if internalStateModified
                                                  computeMinMax
                                                end

                                                return min
                                              end

                                              def getMax
                                                if internalStateModified
                                                  computeMinMax
                                                end

                                                return max
                                              end

                                              def set index, value
                                                internalStateModified = true

                                                super.set(index, value)
                                              end
                                            end


                                            Maintenant je veux rajouter la méthode concat dans ma classe mère car je sais qu'elle sera utilisée par _toutes_ les classes filles :


                                            class Array
                                              [...]

                                              def concat otherArray
                                                [...]
                                              end
                                            end


                                            Avec la solution simple ... ben je change rien, je peux l'utiliser
                                            Avec la solution "java" :

                                            class ArrayWithMinMax < Array
                                              [...]

                                              def concat otherArray
                                                internalStateModified = true

                                                super.concat otherArray
                                              end
                                            end


                                            Il faut donc que je maintienne ma classe fille quand je rajoute des choses dans la classe mère.

                                            Ha oui, je veux pas que mon "internalStateModified" soit dans la classe mère, je veux juste rajouter un getMinMax qui est utile que pour ce cas précis.

                                            En gros, comment proposer une architecture complexe juste pour rajouter le calcul et le retour de deux valeurs simultanément...
                                            • [^] # Re: javascript

                                              Posté par (page perso) . Évalué à 2.

                                              Non tu n'as qu'a gérer dans ta classe mère (mon exemple prenait celle contenant le minmax comme étant dans la classe mère) un attribut qui indique la dernière fois que l'état interne a été modifié (ou envoyer un évènement, propertyChange par exemple) et ta classe fille n'a qu'a tester ça pour savoir si il faut recalculer... sache qu'ici on parle d'une optimisation qui est de ne pas recalculer le min max a chaque appel si rien n'a changé entre... si tu te contentes de le recalculer à chaque fois, alors l'inner class MinMax (ou Bound ou Nawak) avec une méthode getMinMax retournant une instance de celle-ci est plus simple. Dans ton exemple python tu recalcule à chaque fois le minmax à l'appel de getMinMax, dans l'exemple java avec recalculMinMax, celui-ci n'est fait que si l'état interne a changé pas à chaque appel de getmin ou getmax. Si ton minmax n'est pas dans la classe mère, la classe mère devrait prévoir un mécanisme qui informe la classe enfant que son état interne a changé (envoyer un évènement propertyChange par exemple) dans tout les cas c'est *au-delà* de la problématique de juste retourner plusieurs valeurs, pour faire ça une inner class avec fields public convient parfaitement.
                                              • [^] # Re: javascript

                                                Posté par (page perso) . Évalué à 3.

                                                attend, là je comprend pu rien du tout

                                                Si la classe mère est celle contenant le minmax, c'est quoi ma classe fille ?
                                                Evidemment si je colle minmax dans ma classe mère alors la classe fille est simple, mais ça ne correspond plus du tout à l'exemple dont je parle _depuis le début_


                                                question subsidiaire : pourquoi ne pas faire, juste un peu, abstraction de minmax etc pour juste tenter de comprendre l'exemple ?
                                                Je demande pas comment me passer d'un minmax, comment optimiser ce cas hyper précis puisque c'est un _exemple_
                                          • [^] # Re: javascript

                                            Posté par . Évalué à 2.

                                            Sauf que tu inverses le pb, si je l'avais bien compris

                                            On a une classe List de base.
                                            On décide de la sous-classer BoundedList avec cette fameuse méthode getMinMax.
                                            Pour l'optimiser on rajoute ce fameux booléen et min et max dans la sous-classe.Je n'accède pas à l'état de la classe mère, je l'étend en lui rajoutant des champs .. privés bien entendu

                                            Pour chaque méthode de modification de la classe mère List, je suis bien obligé de surcharger la méthode dans la classe fille en appelant la méthode mère et en repositionnant mon booléen à faux.

                                            Si le contrat de List s'enrichit avec une nouvelle méthode de modification je suis obligé de la surcharger
                                            Et là ou c'est grave c'est grave c'est que je risque d'oublier de le faire lors de ma prochaine mise à jour de la lib qui contient le nouveau contrat

                                            Ou alors j'ai mal saisi la problématique
                                            • [^] # Re: javascript

                                              Posté par (page perso) . Évalué à 2.

                                              Voir ma réponse plus haut, on parle ici d'une optimisation et si l'objet mère est bien encapsulé (pas d'accès direct à l'état interne) il doit pouvoir prévenir des autres objets d'une modification de son état interne... par voie d'événement, ou timestamp ou autre, mais ceci est simplement au-delà de la problématique de renvoyer plusieurs valeurs.
                                              • [^] # Re: javascript

                                                Posté par . Évalué à 2.

                                                Oui c'est ici
                                                http://linuxfr.org/comments/1000494.html#1000494

                                                Sauf que dans ta classe tu encapsules ou tu hérites d'une collection de l'api de base.

                                                Donc si ca n'est pas prévu de base tu doit te coltiner de participer au JCP ou reécrire toi-même de toute pièce ta collection.
                                                Ca devient lourdingue pour une simple optim en 2 lignes avec un

                                                Faut arrêter un peu la mauvaise foi aussi
                                                • [^] # Re: javascript

                                                  Posté par (page perso) . Évalué à 2.

                                                  Et bien dans ce cas comme dit plus haut, tu fais comme le fais l'exemple python, tu recalcules à chaque appel de getMinMax le min max et en java tu retournes une inner class MinMax contenant les 2 entiers... pareil à la définition de l'inner class près (c'est vrai c'est 5 lignes en plus). En python pour faire l'optimisation requise (recalcul si et seulement si l'état interne a changé et le nécessite) tu dois aussi surcharger tout. C'est *exactement* pareil.
                                                  • [^] # Re: javascript

                                                    Posté par . Évalué à 2.

                                                    Je suis d'accord avec cette solution, je l'ai dit plus haut.
                                                    Mais la solution que tu défendais ici n'est pas viable.

                                                    Heureusement que les inner class sont apparues donc.
                                    • [^] # Re: javascript

                                      Posté par . Évalué à 4.

                                      Arrêtez avec votre débat sur des langages complètement limité : je vous donne un exemple qui va tous vous clouer :
                                      getBounds(Array, Min, Max)
                                      C'est du Prolog, et il n'y a pas d'histoire d'argument en entrée ou retourné, car souvent le "sens" des variable peut être changé comme on le veut ... Pas de problème de nommage de "valeurs de retour", etc.

                                      Bon, c'est typé bizarrement, c'est pas objet, et c'est vieux, mais ça a quand même certains avantages ...
                                      • [^] # Re: javascript

                                        Posté par . Évalué à 2.

                                        Ouais .. A ce niveau, pourquoi ne pas le faire en forth aussi ?

                                        Même plus besoin d'OS ça tourne sur l'Openfirmware de ma sun ...
                          • [^] # Re: javascript

                            Posté par . Évalué à 1.


                            C'est peut -être plus lourd mais par la suite tu voudra aussi l'écart type, la variance et ta belle solution de multi-liste t'obligera à un moment à tout refactoriser ton code appelant.


                            Mouais, faire une belle archi avec tout les beaux patterns que tu veux pour essayer d'éviter les pièges c'est très bien. Chercher l'excellence en essayant de gérer des cas improbables c'est le meilleur moyen d'avoir le code le plus imbittable qui soit, et tout le temps que tu pourrais perdre lors d'un refactoring, tu le perds à gérer la lourdeur de ton archi.
                            • [^] # Re: javascript

                              Posté par . Évalué à 2.

                              Tu as certes raison.

                              Mais lorsque tu crées un toolbox ou framework qui est utilisé par des clients autres que toi, ils préfèrent nettement que toi tu aies visé l'excellence plutôt qu'être obligé de refactorer eux, sinon ils vont voir ailleurs.
                              • [^] # Re: javascript

                                Posté par . Évalué à 1.

                                Dans tout les cas ce n'est pas généralisable, et si tu as bien sur raison sur un point, c'est que chaque cas mérite sa reflexion.

                                Pour un framework, c'est également discutable. C'est vrai que dans la plupart des cas, j'aime que les dev du dit framework aient pensé adaptable, généralisable. Néanmoins j'aime également aller au plus simple sans avoir à parcourir à chaque fois la doc.
                          • [^] # Re: javascript

                            Posté par . Évalué à 3.

                            > C'est peut -être plus lourd mais par la suite tu voudra aussi l'écart type, la variance et ta belle solution de multi-liste t'obligera à un moment à tout refactoriser ton code appelant.

                            Comme quand tu modifies le nombre d'arguments d'une méthode. C'est vraiment crade Java, ça te permet de mettre plusieurs arguments !
                    • [^] # Re: javascript

                      Posté par (page perso) . Évalué à 2.

                      ha, je me suis dit le contraire vu qu'un peu plus haut thedude donnait la même solution (mais sans la détailler) :
                      utilisation de private computeMinMax http://linuxfr.org/comments1000491.html#1000491
          • [^] # Re: javascript

            Posté par . Évalué à 3.

            Dans un langage objet par contre, par essence, tu vas passer par des classes pour ce genre d'operations (ie, tu ne vas pas utiliser une "fonction" mais une methode d'une classe).

            Mon dieu mon dieu...
            Dans un langage objet, tout est objet y compris les fonctions, les classes et les méthodes (cf. Python), que ce ne soit pas le cas en Java est un autre sujet.
            • [^] # Re: javascript

              Posté par . Évalué à 1.

              et ton "objet" définissant ta fonction, il définit quoi ? une fonction (par définition :P)

              C'est beau l'objet, mais bon un moment il faut quand même revenir à des paradigmes précis si on veut discuter. On est pas les schtroumpfs, on comprends pas que tu parle d'un "objet fonction" plutot qu'un "objet attribut" ou encore un "objet interface" si tu dis juste "objet".
              • [^] # Re: javascript

                Posté par . Évalué à 4.

                et ton "objet" définissant ta fonction, il définit quoi ? une fonction (par définition :P)

                ??? Je ne comprends pas ta phrase.

                C'est beau l'objet, mais bon un moment il faut quand même revenir à des paradigmes précis si on veut discuter.

                Eh bien, "objet", c'est précis : il y a des méthodes, des attributs, un passage par référence (en Python), etc. Une fonction, c'est simplement un object qui implémente la méthode __call__.

                Ce que je voulais dire en répondant au zozo du dessus, c'est que ce n'est pas parce qu'un langage est "objet" (et Ruby et Python sont beaucoup plus "objet" que Java) que tout s'écrit sous forme de déclarations de classes et de méthodes.
                • [^] # Re: javascript

                  Posté par . Évalué à 2.

                  En premier, après avoir lu ton deuxieme commentaire, je me rend compte que je me suis peut etre "emporté" un peu vite, et je te prie de m'excuser.

                  J'avais pris ton commentaire pour quelqu'un qui rappel les "bons mots" (comme arroseur pour spammeur et les conneries comme ça) quand que ça complique tout ;)

                  ??? Je ne comprends pas ta phrase.
                  C'est que j'aime bien compliquer.
                  Ce que j'essaie de dire, c'est que le terme "fonction" utilisé pour un objet (spécifique) n'est qu'une métonymie.
                • [^] # Re: javascript

                  Posté par . Évalué à 1.


                  (et Ruby et Python sont beaucoup plus "objet" que Java)


                  J'affectionne beaucoup python mais faut rien exagérer.
                  Le duck typing n'est pas ce qu'on appelle de l'objet. C'est un truc batard , pratique, mais qui ne correspond en rien à la POO et à la notion de classification.

                  Je ne parlerai même pas de l'encapsulation qui n'est pas permise puisqu'on n'a pas de vraie notion de champ privé et encore moins de protected. Et après on t'expliquera que ca n'est pas nécessaire un peu comme les javaistes t'expliquent comment te passer du retour de valeurs multiples.

                  Je ne m'aventurerai pas non plus sur le terrain du multi-héritage en comparant son modèle à celui du C++ qui adresse presque tous les pbs lié à ce modèle (le membre partagé, ....).

                  Sans parler de l'autre chose qui n'a rien a voir avec la POO mais qui reste désagréable et sur lequel on n'a pas mal trollé ici.
                  Tu sais cet acronyme en 3 lettres qui G.I.L ne sera jamais remis en question car ca casserai tout ce bel édifice.
                  Là aussi on on nous explique que ca sert à rien

                  Les langages pur objet ce sont en général Smalltalk peut-être Ruby, ceux la même qui sont réputés pour leur piètre performances.
                  Java, C++ ont fait le choix du compromis entre performance et purété, par exemple en introduisant des type primitifs non purement objet.

                  Bref, le langage miracle n'existe pas.
                  • [^] # Re: javascript

                    Posté par (page perso) . Évalué à 1.

                    Le but de Lisaac est justement de prouver qu'on peut être pur et performant. Lisaac est bien plus rapide que Java, proche de C, et d'une pureté totale.

                    Comme quoi c'est possible, ça demande juste un compilateur qui analyse globalement son code.

                    Citons aussi SmartEiffel, qui est beaucoup plus pur que Java et qui offre de bonnes performances.

                    Avant lui, il y a eu Self, le premier langage à proto, sur lesquel il y eu énormément de travaux sur les perfs d'un tel langage - absolument pur, en passant -
                    Ces travaux (ainsi que les précédents) sont à l'origine des JIT actuelles.
                    http://www.research.sun.com/research/jtech/pubs/97-pep.ps

                    « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

                    • [^] # Re: javascript

                      Posté par . Évalué à 2.

                      Je sais pas pourquoi, je le présentais.
                      Au moment ou j'ai écris le langage miracle n'existe pas , j'étais sur que tu allais nous ressortir Lisaac

                      Il n'y a a pas de véritable consensus sur les limites exacts d'OO.
                      Les contrats en font ils partie, le mutli héritage, les exceptions

                      Chaque langage a ses spécificités et l'Objet ne répond pas à tous les besoins.

                      Le duck typing ne respecte pas l'objet mais personne n'a réussi à me démontrer que ca n'était pas plus efficace dans bien des cas.
                      D'ailleurs il s'apparente de près au concept d'interface en Java, le contrôle statique en moins et a souplesse en plus.

                      L'AOP adresse les problèmes transversaux que l'approche objet n'a jamais su gérer autrement qu'au prix de frameworks gargantuesques et complexes

                      Les langages déclaratifs à la Prolog se révélent d'une redoutable efficacité lorsque l'algorithmie montre ses limites.

                      Encore une fois il faut la pureté objet ne doit pas être une fin en soi.
                      • [^] # Re: javascript

                        Posté par . Évalué à 2.


                        L'AOP adresse les problèmes transversaux que l'approche objet n'a jamais su gérer autrement qu'au prix de frameworks gargantuesques et complexes


                        Il existe un article qui dis le contraire où chaque fonction de l'aop est remplacé par un pattern plus simple à gérer en objet.


                        Les langages déclaratifs à la Prolog se révélent d'une redoutable efficacité lorsque l'algorithmie montre ses limites.


                        Tu as des exemples d'utilisations "industriel" (en dehors des labos de compilateur ou de recherche en informatique) ?

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

                        • [^] # Re: javascript

                          Posté par . Évalué à 2.


                          Il existe un article qui dis le contraire où chaque fonction de l'aop est remplacé par un pattern plus simple à gérer en objet.

                          Et quel article STP.
                          Ca m'intéresse
                    • [^] # Re: javascript

                      Posté par . Évalué à 1.

                      Lisaac est bien plus rapide que Java, proche de C, et d'une pureté totale.
                      Au fait je croyais que Lisaac était un langage orienté prototype et pas un langage orienté objet
                      http://fr.wikipedia.org/wiki/Programmation_orient%C3%A9e_pro(...)
                      • [^] # Re: javascript

                        Posté par . Évalué à 2.

                        exact et comme le dit la première phrase de ton lien :
                        La programmation orientée prototype est une forme de programmation orientée objet sans classe, basée sur la notion de prototype...

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

                  • [^] # Re: javascript

                    Posté par . Évalué à 3.

                    C'est un truc batard , pratique, mais qui ne correspond en rien à la POO et à la notion de classification.

                    Si je comprends bien, les langages à prototype comme Javascript ne sont pas non plus estampillés "POO" parce qu'ils ne correspondent pas à ta notion de classification ?

                    On peut voir le duck-typing au contraire comme définissant une classification de fait. C'est vrai qu'en Java il faut tout déclarer...

                    Je ne m'aventurerai pas non plus sur le terrain du multi-héritage en comparant son modèle à celui du C++ qui adresse presque tous les pbs lié à ce modèle

                    En français, on n'adresse pas des problèmes, on les résoud.

                    Sinon, l'héritage multiple de Python correspond à l'héritage "virtuel" de C++, je ne vois pas trop où se situe la différence. Si tu as besoin d'un héritage multiple non-virtuel, c'est AMHA que tu devrais faire de la délégation plutôt que de l'héritage.

                    Tu sais cet acronyme en 3 lettres qui G.I.L ne sera jamais remis en question car ca casserai tout ce bel édifice.

                    Effectivement, ça tient 1) du hors-sujet 2) du troll mal informé, puisqu'il y a des implémentations de Python sans GIL et qui pourtant respectent la sémantique du langage.

                    Java, C++ ont fait le choix du compromis entre performance et purété

                    Là ça me fait marrer, la raison pour laquelle Java a des performances acceptables aujourd'hui, c'est qu'un tas d'ingénieurs est payé à temps plein depuis plus de dix ans pour ça. Mettre C++ dans le même sac de ce point de vue est grotesque.
  • # Explicit is better than implicit.

    Posté par . Évalué à 10.

    Dans le Zen de Python, il est écrit :
    Explicit is better than implicit.
    Et j'ai beau aimer perl aussi pour pas mal de ses constructions, au final ce coté "super puissant" est souvent plus emmerdant qu'autre chose.

    La preuve ? Ton exemple :
    @liste = %h{@t};
    ne marche pas chez moi, il fallait écrire (je suppose) :
    @liste = @h{@t};
    Voilà, c'est ce genre de détail qui me fait m'énerver sur perl.

    En python, ça aurait donné (avec la compréhension sur les listes) :
    liste = (h[k] for k in t)
    ce qui est, quoique un peu plus long, tout de même beaucoup plus explicite et lisible.

    Sinon, ton histoire de pouvoir utiliser des listes là où on utilise des valeurs, il me semble me rappeler que beaucoup de monde en a déjà parlé (j'y avait pensé il y a quelques années déjà) mais qu'au final ça apporte peu par rapport au bazar qu'il faut faire pour l'intégrer. En gros, c'est faire un map() implicite, et comme je disais plus haut, "explicite c'est mieux qu'implicite" ...
    • [^] # Re: Explicit is better than implicit.

      Posté par (page perso) . Évalué à 2.

      > Explicit is better than implicit.

      Je crois que c'est le truc qui m'a toujours fait détesté python.
      Pourquoi écrire du code alors que c'est évident ?
      Ca complique la vie du codeur, ça complique aussi la vie de tous ceux qui lisent le code et ça n'apporte rien...


      open(FILE, ">file.txt");
      while(<FILE>) {
        print if =~ /plop/
      }
      close(FILE);


      C'est implicite et lisible si tu connais =~ et < >
      • [^] # Re: Explicit is better than implicit.

        Posté par (page perso) . Évalué à 9.

        Pourquoi écrire du code alors que c'est évident ?

        Évident, c'est pas gagné, surtout avec Perl qui contient énormément de règles implicites qu'il faut connaître pour comprendre le code (il me semble que Ruby et Ruby on rails fonctionnent pareil). L'avantage d'un code explicite est que n'importe qui (ayant une connaissance minimale du langage) peut comprendre facilement le code et donc : le corriger et l'améliorer. D'une manière générale, un code explicite est un gage de pérénité : si le développeur disparait, on peut le remplacer.
        • [^] # Re: Explicit is better than implicit.

          Posté par (page perso) . Évalué à -2.

          Faut arrêter de dire que le Perl est incompréhensible !

          Je ne comprends rien aux programmes Java avec leur millions de lignes, leur millions de classe, les fichiers de conf XML de Tomcat ;-)

          J'ai travaillé avec pas mal de personne qui n'avait jamais fait de Perl, qui n'en pensait que du mal mais qui avait fait du PHP ! Et bien, tous ont compris de suite les programmes ! Evidement, il y a quelques règles à respecter pour avoir du Perl lisible mais c'est pareil dans tous les langages.

          Sinon, il y a des milliers de modules sur le CPAN et la doc est très claire pour les utiliser. Je n'ai pas vraiment de soucis avec les paramètres.

          Au niveau objet, je ne sais pas pourquoi le mot clef 'class' n'a pas été intégré pour faire plaisir aux gens. A mon avis, c'est pas si difficile à faire pour les bons programmeurs Perl. Mais pour les gens comme moi, on peut déjà utiliser Moose ou Mouse et c'est pas plus dur que de faire une classe en Java.
        • [^] # Re: Explicit is better than implicit.

          Posté par (page perso) . Évalué à 2.

          > Évident, c'est pas gagné, surtout avec Perl

          Oui mais quand je dis ça je veux dire que le code évident (parce qu'il l'est réellement, que c'est redondant, qu'il y a suffisament d'informations pour le comprendre) peut être supprimé.

          Mais à chaque fois qu'on parle de perl, l'argument avancé pour les "contre" est qu'il est illisible alors qu'en réalité c'est que les gens ne le connaissent pas.

          > n'importe qui (ayant une connaissance minimale du langage)

          Où s'arrête le minimal ?
          Les $* font partie de perl et du minimum de perl pour moi.
          Le truc c'est que vous ne voulez pas apprendre perl car il semble obscure et il semble obscure car vous ne l'apprenez pas.

          Demandez à un programmeur lisp de coder en java et il va dire qu'il ne comprend rien.

          En fait tout le monde est trop formatté au c/c++/java je trouve...


          > un code explicite est un gage de pérénité : si le développeur disparait, on peut le remplacer.

          Je ne pense pas.
          SI je file dans quelques année un code perl 4 ou 5 à un développeur avec un bouquin du perl correspondant alors mon code serait maintenable également.

          Si je file à un programmeur ne connaissant pas python un programme en python, c'est pas sur qu'il s'en sorte plus facilement.

          Evidemment si je file un code pourris en perl il y aura de la casse, mais du code crade on peut en écrire dans quasiment tout langage.
          Il n'y a qu'à voir ce qu'on peut faire en C:C++... et pourtant y'a pas trop de magie comme dans perl.

          Tiens d'ailleurs c'est pas mal ça, si dans quelques années on file un programme C++ (avec tout plein de pointeurs) à un programmeur java je voudrais bien voir ce que ça donnera...

          Explicit is better than implicit est une erreur à mon avis...
          • [^] # Re: Explicit is better than implicit.

            Posté par (page perso) . Évalué à 9.

            "Explicit is better than implicit" c'est vraiment la clé de voûte.
            Qu'importe le language ... mais que tu donnes ton code à qqu'un d'autres, que tu le reprennes 3 ans plus tard, où que tu codes après qques bieres.
            Le côté explicit d'un algo, d'une formule, d'une conditionnel est vital, pour se mettre/remettre dans le bain. L'implicite necessite que la personne, ou toi, re-devine ce que tu voulais dire/faire "en codant ainsi", et gaspille ses neurones plutôt que de les concentrer dans l'action à réaliser ... et souvent c'est pas gagné/facile.
            Le python, pour ça est vraiment sur LA bonne voie ...

            Maintenant, qqsoit le language on peut écrire cradement (c'est moins vrai pour le python ;-). ça on est d'accord ... Mais il y a quand même des languages propices pour des écritures vraiment abstraites. Ruby avec ses différentes syntaxes pour écrire une même conditionnelle d'égalité. Perl avec toutes ces choses "implicites à connaître" (et magiques) n'aident pas.

            Ok, mieux vaut avoir des règles dans le travail collaboratif avec ce genre de language (plus que dans d'autres languages). Mais, dans la vraie vie, sous la pression, sous le stress, sous les contraintes, et pour aller vite ... tu zappes les règles et tu peux faire d'énormes raccourcis (pk le language le permet), qui te couteront plus tard. C'est une prise de risque supplémentaire et inutile.

            Perso, j'ai bien tenté de me mettre à ruby, mais ces différentes syntaxes pour exprimer la même chose, et tous ces hiéroglyphes (et caractères qu'il faut shifté pour insérer) m'ont fortement rebuté ... il fallait "trop apprendre", par rapport à des choses plus classiques ("formatté au c/c++/java").

            Le python a également l'avantage de s'écrire comme tu écris en algorythmie (si ... sinon ... alors) ... pour ma part : ça FIT my brain à la perfection.
            • [^] # Re: Explicit is better than implicit.

              Posté par (page perso) . Évalué à 2.

              Décidément c'est dur à faire comprendre (ou alors je m'exprime pas bien.. ?)

              > L'implicite necessite que la personne, ou toi, re-devine ce que tu voulais dire/faire "en codant ainsi"

              Implicite ne veut pas dire de supprimer tout ce qui est possible hein.
              On peut avoir aussi bien de l'"explicite" et de l'"implicite" dans un même programme.

              Après faut juste coder intelligemment...

              Permettre d'utiliser l'implicite ne veut pas dire tout supprimer. Si vous ne voulez pas coder proprement, c'est pas le langage qui empêchera de faire de la merde.

              Mais si quelque chose est _évident_ (que ce soit au moment où on l'écrit, au moment où on le lit, même plus tard) pourquoi l'écrire ?

              Utiliser de l'implicite ne veut pas dire ne pas documenter, supprimer tout ce qui traine et faire du code idiot hein !


              > Mais, dans la vraie vie, sous la pression, sous le stress, sous les contraintes, et pour aller vite ... tu zappes les règles et tu peux faire d'énormes raccourcis (pk le language le permet), qui te couteront plus tard.

              C'est bien pour ça qu'il existe des outils pour contraindre, des outils de vérification de syntaxe par exemple (éviter par exemple qu'il existe des blocs sans accolades)


              > il fallait "trop apprendre", par rapport à des choses plus classiques ("formatté au c/c++/java").

              Ben voilà le vrai problème, refuser des avancées parce qu'il faut apprendre...
              • [^] # Re: Explicit is better than implicit.

                Posté par (page perso) . Évalué à 3.

                > Utiliser de l'implicite ne veut pas dire ne pas documenter,

                attention ! double négation ... on peut simplifier : "Utiliser de l'implicite veut dire documenter"
                et c'est tellement vrai ...

                et dans la vraie vie, sous la pression, sous le stress, sous les contraintes, et pour aller vite ... tu zappes le commentairage de l'énorme raccourci implicite que tu viens de coder pour te faire plaisir.

                > Mais si quelque chose est _évident_ (que ce soit au moment où on l'écrit,
                > au moment où on le lit, même plus tard) pourquoi l'écrire ?

                faut toujours penser à celui qui reprendra ton code, ou à toi, avec qques bieres dans le nez.
                faut être le plus clair possible, ça paye vraiment avec le temps

                > C'est bien pour ça qu'il existe des outils pour contraindre, des outils
                > de vérification de syntaxe par exemple (éviter par exemple qu'il existe
                > des blocs sans accolades)

                je ressort mon argument qui va très bien là également :
                dans la vraie vie, sous la pression, sous le stress, sous les contraintes, et pour aller vite ... tu zappes le lancement régulier de ton "outil pour contraindre" ... (et là, c'est encore plus vraie)

                >> il fallait "trop apprendre", par rapport à des choses plus
                >> classiques ("formatté au c/c++/java").
                >Ben voilà le vrai problème, refuser des avancées parce qu'il faut apprendre...

                oui, je dis pas ... c fun/hype de faire du ruby, du erlang, du <ton language préféré> ...
                mais imagine la cata si chaque personne utilisait un language différent ... bonjour l'interop;-)
                la syntaxe est une chose, et si elles se ressemblent inter-languages, c'est quand même aussi dans le but de simplifier l'appréhension du language nouveau.
                Les avancées significatives ne sont pas la syntaxe du language, mais dans la sémantique.
                • [^] # Re: Explicit is better than implicit.

                  Posté par (page perso) . Évalué à 2.

                  > c fun/hype de faire du ruby, du erlang, du <ton language préféré> ...
                  mais imagine la cata si chaque personne utilisait un language différent

                  Donc il ne faut pas utiliser python non plus !


                  > la syntaxe est une chose, et si elles se ressemblent inter-languages, c'est quand même aussi dans le but de simplifier l'appréhension du language nouveau.

                  Mais c'est bien ça le problème, on peut aussi appeler ça un nivellement par le bas. Et non, un langage ça _doit_ s'apprendre.
                  Il faut savoir perdre du temps (à apprendre) pour devenir plus performant, pour faire des choses plus puissantes et donc gagner du temps sur du moyen terme...

                  > je ressort mon argument qui va très bien là également

                  Ben en fait non, je trouve pas vraiment que ce soit un bon argument...

                  (et pour les tests, outils, etc ça va par exemple être des lancement automatiques sur build / commit donc je les lance pas à la main, manquerait plus que ça...)

                  > faut toujours penser à celui qui reprendra ton code, ou à toi, avec qques bieres dans le nez.
                  faut être le plus clair possible, ça paye vraiment avec le temps

                  Déjà dans mon taff j'évite vraiment de coder avec de la bière, et si c'est le cas et que je comprend pas mon code, je crois qu'il faut plus en vouloir à la bière qu'au code...

                  Et faire de l'implicite n'empêche absolument pas de faire clair.
                  Allez, juste pour le fun :
                  faire de l'explicite inutile (sous pretexte que c'est "better") complexifie inutilement le code et tend à le rendre moins clair.
                  Moins il y a de parasitage dans le code, plus le code est clair et compréhensible.
                  • [^] # Re: Explicit is better than implicit.

                    Posté par . Évalué à 5.


                    Donc il ne faut pas utiliser python non plus !

                    Ben si, puisque c'est ce qui ressemble le plus à un langage ....naturel:
                    L'anglais.

                    Bon je suis de la vieille école, mais lorsque j'ai appris l'informatique on avait l'habitude d'écrire un truc avant de coder comme des fous. Ca s'appelait un algorithme et après on le traduisait en Pascal.

                    J'avoue que lorsque je lis du code python, j'ai l'impression de lire mes bons vieux algos procéduraux.
                    C'est grave docteur ?


                    Mais c'est bien ça le problème, on peut aussi appeler ça un nivellement par le bas. Et non, un langage ça _doit_ s'apprendre.
                    Il faut savoir perdre du temps (à apprendre) pour devenir plus performant, pour faire des choses plus puissantes et donc gagner du temps sur du moyen terme...

                    Non ce qu'il faut apprendre c'est des concepts, des contsructions des paradigmes et pouvoir les retrouver dans un ou des langages.
                    Qu'est qu'un "choix de" une boucle "tant que", une condition
                    Qu'est-ce qu'une fonction, une procédure, un objet, une classe une fermeture lexical, une clause, un aspect...
                    Mais surtout comment bien utiliser ces concepts.

                    Quand utiliser le polymorphisme, quand utiliser l'héritage au lieu d'une composition, un singleton ou tout autre design pattern.
                    Savoir qu'utiliser une table de mappage va booster mes perfs pour la recherche d'un info plutôt que d'itérer sur une liste surtout si cette liste est beaucoup accédée en lecture et peu en écriture.

                    Par contre passer mon temps à me demander quand le dernier contexte a été modifié ou où est-ce que j'ai pu oublier cette putain d'apostrophe qui me pète ma regexp, j'avoue que ca me fait moyennement triper.
                    • [^] # Re: Explicit is better than implicit.

                      Posté par (page perso) . Évalué à 3.

                      Si tu as des problèmes avec tes regexps, je te conseille le çapuucépalibre mais gratuit logiciel "Regexp coach" dont tu trouveras un exécutable pour linux et windows. Il est très bien et te permet même de tester tes regexps pas à pas pour comprendre pourquoi ça match pas.

                      http://www.weitz.de/regex-coach/

                      « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

                    • [^] # Re: Explicit is better than implicit.

                      Posté par (page perso) . Évalué à 3.

                      > Ben si, puisque c'est ce qui ressemble le plus à un langage ....naturel:
                      > L'anglais.

                      Ha bon ?

                      Je te conseil de lire ce qu'écrit Larry Wall (le créateur de perl) à propos de perl 5, des langages (ça se trouve dans un bouquin sur perl, chez oreilly) ça te surprendra surement sur la création de perl.
                      A noter aussi que Larry Wall est à la base un linguiste.

                      Mais je sais pas si c'est possible en python, mais écrire quelque chose de proche du langage naturel en perl et ruby c'est extrêmement simple :


                      print line if line.include? "plop"

                      Affiche la ligne si la ligne contient "plop"

                      Comment écrire ça plus simplement ?

                      Mais l'avantage est qu'on peut aussi écrire l'inverse très facilement et toujours de manière très compréhensible :

                      print line unless line.include? "plop"


                      C'est beaucoup plus logique que "if !line.include? "plop"" ou "if not line.[...]"

                      Et si certains ne comprennent pas au premier abord, ben à part leur faire apprendre le mot unless on peut pas faire grand chose je trouve.

                      Et bon, le coup de python c'est proche du langage naturel... mouaif, faut voir hein ...

                      Allez, une abération que j'ai jamais supporté dans python :
                      pourquoi se trimbaler "self" dans la définition d'une méthode d'un objet ?
                      Ok, explicit better gnia gnia gnia
                      Le programme / les développeurs sont trop con pour savoir qu'une méthode qui se trouve dans la définition d'un objet est lié à un objet ?
                      Ca pue surtout le modèle objet un peu foiré ça...

                      (tout n'est probablement pas parfait en ruby, mais de là à mettre python comme le sauveur...)
                      • [^] # Re: Explicit is better than implicit.

                        Posté par . Évalué à 3.

                        Un truc que je ne comprend pas, c'est de vouloir rendre les langages de programmation de plus en plus proche du langage naturel. Suis-je le seul à trouver ça idiot ?

                        Ce qui me parait bien plus essentiel, c'est que les concepts de bases du langage soit simples et génériques. Typiquement à la Lisp et à la Haskell (et peut-être Smalltalk, mais je ne le connais pas vraiment).

                        Un langage ne doit pas être «intuitif» mais rendre facilement exprimable les algorithmes. Et si il faut assimiler des concepts avant, soit. Je pense donc qu'un bon langage de programmation doit plus s'approcher d'un langage mathématique que d'un langage naturel.
                      • [^] # Re: Explicit is better than implicit.

                        Posté par . Évalué à 3.

                        J'ai lu Larry Wall et ses délires sur la bénédiction des objet noyés au milieux d'infâmes hack du runtime perl parce que mêmes les analyseurs syntaxiques perdent les pédales tellement il ya a de signes cabbalistiques contradictoires (mon emacs sous Solaris ne s'en est jamais remis, obligé d'apprendre ce p%^# de Vi ; ).

                        Je préfère nettement me taper le tuto de Guido en 2h en me disant que je sais presque tout faire avec ca et passer le reste du temps gagné à dévorer un roman de SF que me taper 20 h sur les Perl O'Reilly.

                        Sinon hormis ton cas d'ecole, ceux auxquels j'ai été confronté ressemblent plus à ca:

                        s/^\^Q //;
                        $longueur_ligne = length($_);
                        $caractere_fin_ligne = $longueur_ligne ? ord(substr($_,$longueur_ligne-1,1)) : 0;
                        ....
                        my @c= ;
                        close Fi;
                        map s/[\r\n]+/\n/g, @c;
                        open (Fi,">$f") or die;
                        print Fi @c;


                        Ce n'est pas le plus complexe mais de là à parler de langage naturel.
                        Heureusement que j'ai insisté pour que le gars qui a pondu ca donne de noms de variables explicites et commente un peu parce le decryptage permanent avec le perlref sous la main au bout de 200 lignes ca devient un peu lassant.
                        Et je te passe sur les effets de bord
                        • [^] # Re: Explicit is better than implicit.

                          Posté par . Évalué à 8.

                          Moi, je trouve ça très naturel, au contraire !
                          On dirait des injures censurées d'une BD...

                          C'est là toute la différence avec Java, qui est peut-être verbeux mais qui fait plus penser aux injures du capitaine Haddock : on en a plein la bouche, de tous ces mots !

                          :-D
                      • [^] # Re: Explicit is better than implicit.

                        Posté par . Évalué à 2.

                        Allez, une abération que j'ai jamais supporté dans python :
                        pourquoi se trimbaler "self" dans la définition d'une méthode d'un objet ?
                        Ok, explicit better gnia gnia gnia
                        Le programme / les développeurs sont trop con pour savoir qu'une méthode qui se trouve dans la définition d'un objet est lié à un objet ?
                        Ca pue surtout le modèle objet un peu foiré ça...


                        C'est un héritage du modèle objet de en:Modula-3.

                        Il y a effectivement pas mal de langages ou il est implicite, mais bien souvent ça entretient une confusion sur son statut, ses possibilités, ...
                        Au moins en Python les choses sont claires, l'instance est un argument comme les autres (on peut le nommer toto si ça nous chante).

                        Voir self/this comme un argument est très pratique pour exploiter pleinement l'héritage multiple par exemple:

                        class Foo(object):
                            def bar(self, arg0):
                                 print self, arg0

                        foo = Foo()
                        foo.bar('baz')
                        # <__main__.Foo object at 0x7f22d6d0aef0> baz
                        Foo.bar(1)
                        # TypeError: unbound method bar() must be called with Foo instance as first argument (got str instance instead)
                        Foo.bar(foo, 'baz')
                        # <__main__.Foo object at 0x7f22d6d0aef0> baz
                        class Qux(object):
                            def bar(self, arg0):
                                print 'Qux !'

                        class Fum(Foo, Qux):
                            pass
                        Fum().bar('egg')
                        # <__main__.Fum object at 0x7f22d6bfa7d0> egg
                        class Fum(Foo, Qux):
                            def bar(self, *args, **kwargs):
                                return Qux.bar(self, *args, **kwargs)
                        Fum().bar('egg')
                        # Qux !map(Foo.bar, [Fum()] * 2, ['egg', 'spam'])
                        # <__main__.Fum object at 0x7f22d6c5c490> egg
                        # <__main__.Fum object at 0x7f22d6c5c490> spam


                        Et tu peut même intervenir dans l'autre sens quand tu commence à taper dans les __new__ et autres __metaclass__.
                      • [^] # Re: Explicit is better than implicit.

                        Posté par . Évalué à 2.

                        (désolé si les interlocuteurs différents se succèdent, ça doit pas être facile de tout suivre à la fois)

                        Bon, je pourrais te sortir pas mal de phrases du Zen pour dire que je n'aime pas ton exemple (je suis pour une écriture "naturelle", mais dans une certaine limite, quand elle n'apporte pas de redondance) :

                        Special cases aren't special enough to break the rules.
                        There should be one-- and preferably only one --obvious way to do it.

                        Quand tu te mets à apporter plein de raccourcis déjà dispo sous une autre forme, tu compliques le langage. Bon, ne me dis pas de faire de l'assembleur, ce que je veux dire c'est qu'il y a un équilibre à trouver, et je trouve que python en a trouvé un très bon. Et je pense que la deuxième phrase que je viens de citer est explicitement dirigée "contre" Perl.

                        Sinon, ça me fait marrer que tu parles de complexité car le langage est plus "épuré" : au contraire, tu vois la complexité dans le fait que le code est "plus long", mais moi je trouve qu'un langage avec plus de constructions (pas forcément super utiles) est vraiment plus complexe à apprendre. Le seul raccourci qui me manque dans python est les regexp "intégrées", mais bon, je m'en passe assez facilement. Et c'est ce qui me donne envie de regarder vers ruby ... mais son coté Perl me fait peur ...
                        • [^] # Re: Explicit is better than implicit.

                          Posté par . Évalué à 2.

                          moi je trouve qu'un langage avec plus de constructions (pas forcément super utiles) est vraiment plus complexe à apprendre.

                          Pas forcément.

                          A l'utilisation, tu peux te limiter à quelques constructions qui te permettront de couvrir tous les cas que tu traiteras. Par contre effectivement, lorsque quelqu'un n'a pas le même "style" de codage que toi, c'est pas toujours simple à comprendre mais on s'y fait à force.

                          Et c'est ce qui me donne envie de regarder vers ruby ... mais son coté Perl me fait peur ...

                          Vas-y, Ruby pour moi est un bon compromis entre la souplesse de Perl et la raideur de Python. Il est surtout beaucoup plus lisible pour quelqu'un qui connait pas trop le langage.
                          • [^] # Re: Explicit is better than implicit.

                            Posté par . Évalué à 4.

                            Il est surtout beaucoup plus lisible pour quelqu'un qui connait pas trop le langage.
                            Plus lisible que Perl ou Python ?
                            S'il y a bien un truc dont je suis quasi-sûr par beaucoup d'expériences, c'est que Python est un des langages les plus lisibles qu'il y ait pour ceux qui ne le connaissant pas.
                            • [^] # Re: Explicit is better than implicit.

                              Posté par . Évalué à 3.

                              Plus lisible que Perl ou Python ?

                              Plus lisible que perl, c'est sur. Par rapport à Python, il s'en rapproche beaucoup. Les concepts d'objet sont beaucoup plus simple à appréhender. Pour moi c'est le juste milieu.

                              S'il y a bien un truc dont je suis quasi-sûr par beaucoup d'expériences, c'est que Python est un des langages les plus lisibles qu'il y ait pour ceux qui ne le connaissant pas.

                              Il y a des chances, et je pense que pour toi Ruby sera juste un cran en dessous, mais te permettra de faire certaines choses plus simplement qu'en Python en raison de la souplesse du langage.
                          • [^] # Re: Explicit is better than implicit.

                            Posté par . Évalué à 2.

                            > A l'utilisation, tu peux te limiter à quelques constructions qui te permettront de couvrir tous les cas que tu traiteras.

                            Ca marche bien quand tu es tout seul et sur une période assez courte (< 2 ans).
                            Dans une vraie équipe, chacun à beau se limiter, la somme des limitations reste tout de même un gros bordel. Je bosse actuellement sur un projet qui a vu 71 devs en 10 ans, moins y'a de cowboy dans le lot mieux je me porte.
                            • [^] # Re: Explicit is better than implicit.

                              Posté par . Évalué à 2.

                              Ca marche bien quand tu es tout seul et sur une période assez courte (< 2 ans).

                              Oui, cela dit (en tout cas je parle pour moi) : plus j'utilise un langage, et plus j'écris du code "efficace". Donc, plus ça vient et moins je me limite.

                              Je bosse actuellement sur un projet qui a vu 71 devs en 10 ans, moins y'a de cowboy dans le lot mieux je me porte.


                              Il est vrai que je ne développe pas de la même façon lorsque je bosse pour un truc qui ne sera jamais maintenu par personne d'autre que moi .....
                        • [^] # Re: Explicit is better than implicit.

                          Posté par (page perso) . Évalué à 2.

                          Je vois ce que tu veux dire.

                          Mais je vois en fait le langage (et sa complexité surtout) comme un investissement.
                          Si apprendre un langage un peu plus complexe, et donc "perdre" du temps dessus, me permet, à chaque fois que j'en aurai besoin, de me simplifier la vie, de simplifier mon code, sa compréhension, etc, alors j'estime que ça en vaut la peine.

                          Comme je dis de temps en temps, il faut savoir (apprendre ...) à perdre du temps maintenant pour en gagner plus tard.

                          Et c'est pour ça que j'aime les langages assez expressifs (je sais pas si c'est le bon terme) qui ne sont pas pauvres en mot clés (mais qui restent compréhensibles)

                          > Et c'est ce qui me donne envie de regarder vers ruby ... mais son coté Perl me fait peur ...

                          En fait moi c'est presque l'inverse.
                          j'adore ruby parce qu'il est puissant, expressif mais n'a pas les travers de perl tout en reprenant ses bons côté (les unless, les regexp, etc) et des trucs hyper sympa comme pouvoir mettre des "?" et "!" à la fin des noms de méthodes.

                          Je trouve les programmes ruby assez propre (même si on peut faire du crade hein...) plus lisible que perl.


                          Je viens de lire qq news sur python et dans le genre pas facile à comprendre par exemple :
                          5 // 10

                          si qqn qui n'a jamais utilisé ça se trouve devant, je suis pas sur que ce soit compréhensible directement (histoire de division entière, etc)
                          • [^] # Re: Explicit is better than implicit.

                            Posté par . Évalué à 4.

                            "En gagner plus tard" ?
                            J'ai déjà fait du Perl à une époque. Et bien l'histoire des %@$ je suis perdu aujourd'hui. Ta mémoire n'est pas infinie, et ce que tu passes comme effort à un moment, si tu l'oublies au bout d'un moment, ça ne sert pas à grand chose. En python, je n'ai quasiment jamais rien oublié, même après pas mal de temps à ne pas en avoir fait.

                            Sinon, pour l'histoire des divisions, c'est quelque chose qui doit être exceptionnel d'utiliser cette syntaxe, car le moto du python est que ça fasse les choses "bien" par défaut. Il y a eu une erreur historique sur la division (par défaut entière en 2.x, flottante en 3.x), maintenant c'est reglé.
            • [^] # Re: Explicit is better than implicit.

              Posté par (page perso) . Évalué à 1.

              > Maintenant, qqsoit le language on peut écrire cradement (c'est moins vrai
              > pour le python ;-). ça on est d'accord ...

              Ben je suis désolé mais je n'y comprends rien en Python. J'ai même du balancé un site web en Zoppe pour faire du SPIP car Python me gonflait plus que la normale, et pourtant je déteste le PHP qui n'aurait jamais du exister car c'était du sous perl.

              Non, le Python n'est pas mieux que les autres, il a ses fans mais il a aussi des inconvénients comme les autres.

              Pour me changer les idées, je me suis mis à Erlang et là au moins, on change de perspective. C'est amusant.
              • [^] # Re: Explicit is better than implicit.

                Posté par . Évalué à 5.

                Un petit conseil, ne te fait pas un avis sur Python en essayant Zope : je suis un fan de Python mais je n'ai jamais rien pu faire avec Zope (pareil que toi, je l'ai jeté), car c'est un framework qui redéfini tout un tas de concepts de manière complètement bizarre. Si tu veux un framework web en Python, regarde plutôt du coté de Django.
            • [^] # Re: Explicit is better than implicit.

              Posté par . Évalué à 2.

              j'ai bien tenté de me mettre à ruby, mais ces différentes syntaxes pour exprimer la même chose, et tous ces hiéroglyphes (et caractères qu'il faut shifté pour insérer) m'ont fortement rebuté

              C'est marrant, pour moi les différentes syntaxes sont un atout, car elles permettent d'écrire du code auto-documenté. En partique, "if" et "unless" servent à la même chose, mais utilisés correctement ils rendent le code plus clair:
              - if: si une condition est vraie, on fait ce bout de code
              - unless: généralement on ne fait pas ce bout de code, sauf si...

              De même, "while" et "until" servent à la même chose mais dans des conditions différentes. Ce sont de petites nuances qui, pour moi, facilitent la lecture du code, parce que ça permet de mettre l'accent sur ce qui est important.

              Toujours dans la même idée, j'aime pouvoir écrire "5.times" pour une boucle qui doit s'exécuter 5 fois, "0.upto(4)" pour une boucle qui va de 0 à 4 et "tab.each" pour une boucle qui parcourre un tableau. Ce sont pour moi trois écritures qui mettent l'accent sur ce qu'on veut faire, et les trois ont des raisons d'exister.

              Quel est le bout de code qui demande le plus de réflexion entre les deux suivants ?

              for (int i=5 ; i >= 0; i--) {
              printf("%d\n", i);
              }


              5.downto(0) { |i|
              print "#{i}\n"
              }


              Ce sont deux bouts de code très simples, donc n'importe qui de familier avec la syntaxe des langages les comprend très vite. Dans les deux, je dois regarder la valeur de début, la valeur de fin et le nom de la variable. Mais dans le code en C, je dois regarder le sens de la condition, est-ce que c'est supérieur strict ou égal, et quel est l'incrément, pour vérifier ce que la boucle fait. En ruby, on écrit explicitement "down to", et donc je ne peux pas avoir de doute.

              Après, plusieurs manières d'écrire les choses ça peut vouloir dire plus de choses à apprendre pour comprendre le code des autres. C'est le cas en Perl. En Ruby, je ne suis pas d'accord. Prenons les exemples que j'ai donnés pour les boucles: pour peu qu'on parle anglais, les trois sont parfaitement explicites et ne demandent pas d'explication. N'importe qui comprendra que "5.times" va faire quelque chose cinq fois. De même pour "0.upto(4)", "4.downto(0)" et autres.
              • [^] # Re: Explicit is better than implicit.

                Posté par . Évalué à 3.

                Prenons les exemples que j'ai donnés pour les boucles: pour peu qu'on parle anglais, les trois sont parfaitement explicites et ne demandent pas d'explication.

                Pas d'accord. Si tu lis upto(4) ou downto(0), il n'y aucun moyen de savoir (autre que d'apprendre le langage) si cela s'arrête à 3 ou à 4, à 0 ou à 1 (voire à -1).
                Bref, c'est un joli raccourci, mais ça ne simplifie rien.
                • [^] # Commentaire supprimé

                  Posté par . Évalué à 4.

                  Ce commentaire a été supprimé par l'équipe de modération.

                  • [^] # Re: Explicit is better than implicit.

                    Posté par . Évalué à 1.

                    Ce n'est pas "déformé" ni "stupide", je trouve que c'est complètement logique. En python, quand on dit range(4), c'est [0,1,2,3]. Ça correspond tout à fait à la logique des tableaux, ça fait des calculs d'index beaucoup plus simples, c'est logique par rapport au fait qu'il y ait 4 éléments, et qu'en gros, tu prend toujours un interval comme étant inclusif pour le début, exclusif pour la "fin".
                    • [^] # Commentaire supprimé

                      Posté par . Évalué à 2.

                      Ce commentaire a été supprimé par l'équipe de modération.

                      • [^] # Re: Explicit is better than implicit.

                        Posté par . Évalué à 2.

                        100% d'accord. D'ailleurs c'est super chiant quand tu as eu l'habitude d'utiliser un langage tel que Fortran qui a des défauts mais qu'il est difficile de dire qu'il ne sait pas travailler avec des tableaux (je parle des versions >=90) et qu'il n'est pas rapide pour ce genre de chose.
                        Demandez donc à un gamin de compter vous verrez qu'il commencera systématiquement à 1. Ce n'est pas pour rien que le zéro est arrivé très tard dans les mathématiques.
                      • [^] # Re: Explicit is better than implicit.

                        Posté par . Évalué à 3.

                        Dans la vraie vie, les gens ne manipulent pas des tableaux comme on le fait en informatique. Les gens le feraient plus souvent, ils se rendraient compte que l'indexation à partir de 0 est beaucoup plus pratique, et que compter les intervales classiques comme [) l'est aussi.

                        As-tu déjà fait du Matlab ? Je trouve imbitable la programation dans ce langage, car tu as toujours des -1 et +1 qui se trimbalent partout. Pas en C (ni en python).

                        Par exemple, en python, quand tu choisis une sous-chaîne : s[2:4]
                        Quelle sera la longueur de cette chaîne ? 4-2 = 2
                        Quelle sera l'index du prochain caractère ? s[4]
                        Combien de caractères se trouvent avant ? 2
                        Je sais pas quoi trouver d'autre comme exemple, mais tout ça est pour moi super logique. Fait le avec des intervales autrement, et en indexant à partir de 1, ce sera un bordel immonde.

                        OK, c'est peut-être une "déformation" initiale, mais après c'est beaucoup plus pratique que la manière "usuelle", et ça les gens ne s'en rendent pas compte car ils ne font pas souvent ce genre d'opération.
                        • [^] # Commentaire supprimé

                          Posté par . Évalué à 1.

                          Ce commentaire a été supprimé par l'équipe de modération.

                          • [^] # Re: Explicit is better than implicit.

                            Posté par . Évalué à 2.

                            Fixer les bornes d'un tableau ... rien de mieux pour toujours s'y perdre, et se demander à chaque fois "mais où il commence déjà ?".

                            Bon, pour les exemples, je sais pas vraiment quoi trouver d'autre ... Allez :
                            La chaîne de 5 caractères à l'indice x : s[x:x+5]
                            -> pas besoin de se dire "ha bah comme c'est inclusif, il faut enlever un"
                            La notation "inverse" : s[-y] == s[len(s)-y]
                            -> c'est une jolie propriété, je trouve, qui ne marche pas avec l'indexation à 1
                            Enfin bref, je n'ai plus vraiment d'arguments, mais je n'ai jamais eu à me prendre la tête avec l'indexation à 0 et les "range" [inclus..exclu), alors qu'avec l'indexation à 1, si. Je veux dire, au niveau des calculs ; après, tu peux arguer que c'est moins "naturel", mais quand le naturel est si peu pratique, bah je préfère trouver la solution la "logique".
                            • [^] # Re: Explicit is better than implicit.

                              Posté par . Évalué à 3.

                              Et pendant ce temps là, d'autres programmeurs utilisent des itérateurs, et n'ont pas de problèmes de gestion de leurs indices...
                              • [^] # Re: Explicit is better than implicit.

                                Posté par . Évalué à 2.

                                Oui mais bon par exemple lorsque tu travailles sur des images et que tu veux, par exemple, prendre juste une sous-image, je trouve très très pénible le coup de commencer l'indexage à 0. Je sais pas quel logiciel vous utilisez mais bon, ce que je connais et que j'utilise ils appellent le premier pixel le pixel 1. Du coup lorsque je coupe un bout d'image je trouve plus logique et pratique, dans ma logique à moi, de dire prend du pixel 1 au pixel 23 et je trouve moins logique de dire prend du pixel 0 au pixel 23.

                                Enfin j'avais bien un prof de math qui disait que au dela de 5 dimensions spatiales elle commençait à avoir des problèmes à se représenter la géometrie ... cela montre que l'on a pas tous le même cerveau car moi j'arrive pas à imaginer quoique ce soit au dela de 3...
                              • [^] # Re: Explicit is better than implicit.

                                Posté par . Évalué à 3.

                                Les itérateurs c'est bien pour l'accès séquentiel, mais pour l'accès aléatoire, tu fais comment sans indices dis-moi ?
                                (ne me réponds pas qu'il suffit d'itérer l'itérateur N fois...)
                      • [^] # Re: Explicit is better than implicit.

                        Posté par . Évalué à 2.

                        Et en Ruby, les tableaux commencent à 1 plutôt qu'à 0 ? Parce que sinon l'argument est plutôt foireux...
              • [^] # Re: Explicit is better than implicit.

                Posté par . Évalué à 1.

                C'est du pinaillage, mais bon. Si le premier bout de code est du C ou de la même syntaxe que le C, pour qu'il fasse la même chose que le second il aurait fallu écrire : for (int i = 5; i < 0; i--)
                ....
      • [^] # Re: Explicit is better than implicit.

        Posté par . Évalué à 5.

        C'est implicite et lisible

        C'est implicite et lisible parce que c'est le cas d'école d'utilisation de Perl dans n'importe quel tutorial pour débutants.
        Dès qu'on s'éloigne de ce genre de démonstrations de cinq lignes et qu'on cherche à faire autre chose que du parsing à base de regexp, il n'y a plus rien de très attirant dans Perl...
  • # Perl..? :-s

    Posté par . Évalué à 1.

    Il est vrai que je pensais avoir quelques connaissances niveau programmation même si je ne suis pas un pro de celle-ci...

    Je vais donc vite fait jeter un œil sur l'article Wikipédia concernant Perl [http://fr.wikipedia.org/wiki/Perl_(langage)] et là je me dis effectivement je n'y connais pas grand chose niveau langage de programmation voir même niveau informatique... Entre les différents sigils [http://fr.wikipedia.org/wiki/Sigil_(informatique)] que j'utilise par exemple en Bash ou PHP sans en connaître le nom et les variables à portées dynamique, lexicale ou celle représentée par le mot clé 'our' [http://fr.wikipedia.org/wiki/Portée_(informatique)], tout ce que j'en est tiré est un mal de crane...

    Pourtant je n'avais pas rencontré de difficulté à essayer de comprendre lors de ma rencontre avec le C/C++/Java/Python/Javascript/PHP/etc... C'était des notions que j'arrivais plus ou moins à appréhender...

    Mais rien quand lisant les articles de Wikipédia sur Perl et les notions associées, je me rend compte que je suis en fait une bouse infâme :-s

    Du coup j'ai toujours voulu essayer Perl mais je pense que je vais m'en tenir à le connaître de nom :-(
    • [^] # Re: Perl..? :-s

      Posté par . Évalué à 1.

      je fais régulièrement des petits scripts perl sans connaitre la moitié de ce que tu as énoncé ! (enfin peut etre pas quand même XD).

      Ce que je veux dire, si tu as un script/un programme à faire et que trouve que le bash/awk/grep devient trop compliqué, et que le C trop bourrin, essaie le perl.

      T'es pas obligé de devenir un pro du perl pour l'utiliser ;)
      • [^] # Re: Perl..? :-s

        Posté par . Évalué à 1.

        > Ce que je veux dire, si tu as un script/un programme à faire et que trouve que le bash/awk/grep devient trop compliqué, et que le C trop bourrin, essaie le perl.

        C'est justement mon cas ;-) et en plus ça concerne principalement du traitement de texte...

        Je vais voir de plus près à quoi ressemble Perl en espérant tomber sur un tutoriel plus simple à comprendre que l'article de Wikipédia...
        • [^] # Re: Perl..? :-s

          Posté par . Évalué à 2.

          tutorial (court) par l'exemple
          perl
          my $nom_variable; #on crée une variable
          tableau @nom_tableau=(element1,element2);#on crée un tableau et on met 2 element dedans

          for my $val (@nom_tableau)
          {
          print "Ma valeur est $val";#on affiche la valeur de chaque élément du tableau)
          }

          #!/usr/bin/perl

          my $toto="abc";
          my $titi=1;
          my @tab;
          $titi+=1;

          if ($titi==1)
          {
          push(@tab,"titi vaut 1");
          }
          elsif ($titi==2)
          {
          push(@tab,"titi vaut 2");
          }
          else
          {
          push (@tab,"toto");
          }

          for my $tata (@tab)
          {
          if ($tata=~ m/vaut [0-9]/)
          {
          print "tata contient la phrase \"vaut <un chiffre>\"";
          }
          }
        • [^] # Re: Perl..? :-s

          Posté par (page perso) . Évalué à 3.

          Personnellement, j'utilise les fonction de base de perl, et mon code reste clair.

          J'utilise que des foreach sur les liste/hash, bon d'accord, quelques map de temps en temps...
          Je n'utilise que des if ( $toto =~ /truc/) avec capture ou d'autres if qui ressemblent à ce qu'on trouve en php/C (tests sur chaines et entier).

          Bref, on peut faire du perl propre et clair.

          J'écris jamais ce genre de code : http://shootout.alioth.debian.org/gp4/benchmark.php?test=knu(...) parce que j'y comprend rien, et je ne suis surement pas le seul.

          En fait j'écris du perl comme un type qui a fait du basic de 7 ans à 12 ans, du pascal de 15 à 20 et de l'objet après. Donc ça reste clair ;)

          « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

          • [^] # Re: Perl..? :-s

            Posté par (page perso) . Évalué à 1.

            Justement, les foreach de Perl sont super clair et on sais que les boucles sont une source énorme de bogue. Donc question : quand est-ce que vous implémentez les iterators à la Sather dans Lisaac, pas les Iterators tout mauvais des autres langages ?

            Sinon, comme je l'ai dis dans un autre post, je me suis mis a essayer Erlang et il y a des concepts vraiment intéressants à reprendre même si je ne suis pas sur que cela soit facile de placer cela dans un langage procédural. En fait, Erlang, c'est presque le symétrique du Fortran ;-)
            • [^] # Re: Perl..? :-s

              Posté par (page perso) . Évalué à 2.

              Le problème est que les coroutines ne rentrent pas du tout dans la sémantique du langage. C'est un concept intéressant, mais ça demande d'orienter le compilo d'une certaine façon. Et ça met des goto caché dans le code, et ça, le concepteur de Lisaac te répondra que c'est hors de question.

              Avec COP, et une granulité moins fine, on devrait pouvoir implémenter ce genre de chose avec des objets générique, le containeur s'occupant de boucler et gérer les yields.
              Bon après dans la pratique je sais pas ce que ça va donner, COP est encore un concept théorique.

              « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

              • [^] # Re: Perl..? :-s

                Posté par (page perso) . Évalué à 2.

                J'ai cru comprendre que le code C généré par Lisaac était ... imbitable mais que cela n'avait pas d'importance parce que pas destiné a être lu par l'homme. Alors je ne comprends pas trop ce qui gène de mettre des GOTO la dedans. Un GOTO n'a rien en bas niveau, d'ailleurs, en assembleur, il y en a plein ;-)

                Je ne me souviens plus exactement mais COP, c'est le truc de Meyer pour faire du parallèle ? Je suis surpris si c'est cela que ce modèle soi disant génial (je suis incapable de juger s'il est bien ou non dans l'absolu, pas assez de recul la dessus) ne soit toujours pas implémenté.

                Je pense que les langages qui font tout pour favoriser un parallélisme simple et qui marche seront de plus en plus utilisé dans le futur. Avec l'augmentation du nombre de coeur, il faut clairement un langage parallèle dans son âme (un peu comme Erlang). C'est d'ailleurs ce qui m'inquiète avec Perl6 car j'aime beaucoup Perl et je n'ai pas l'impression que l'aspect parallèlisation ait été au coeur de la conception du nouveau langage.
                • [^] # Re: Perl..? :-s

                  Posté par (page perso) . Évalué à 2.

                  Benoit ne veut pas de goto dans la sémantique du langage, parce que ça casse l'analyse de flot, et parce que ça peut partir dans tous les sens.
                  Dans le C généré, il y a des goto, parce que dans certains cas c'est plus rapide ou impossible de faire autrement (certaines dérécurcivations).


                  Le modèle de Meyer est SCOOP, il consiste à ajouter un mot clé devant la déclaration d'une variable.

                  COP est adapté au prototypes, qui nécessitent de s'adapter, car la logique diffère un peu (en gros, en quelques sortes, le paradigme à classe est un sous ensemble du paradigme à prototype, donc SCOOP fit pas tout l'ensemble).
                  COP est en cours d'implémentation, ça prend du temps et l'implémenteur a des cours à donner, des mémoires de maitrises à superviser, des publis à écrire, etc...

                  Les débuts d"implémentation indiquent bien que ça permet de paralléliser proprement et très simplement : tu créés plein d'objets, tu lances et il se débrouille assez bien, ie. ça se répartie bien sur les coeurs.

                  Quand ça sera prêt et nickel on le publiera (enfin en tout cas, je défend pour ma part l'idée - au sein du projet - que je préfère que ça sorte avec 6 mois de retard mais que ce soit nickel).

                  « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

                  • [^] # Re: Perl..? :-s

                    Posté par (page perso) . Évalué à 2.

                    Il est clair que les GOTO ne sont pas un plus pour l'analyse de flot. Il est vrai que dans les block a iterator de Sather, le premier iterator qui finit termine le block et finit tous les autres iterators du block. C'est pas un comportement classique (ajoute le paradigme 'one' à l'appel d'un iterators (ce qui prouve que ce n'est pas une méthode)) et montre que ce concept de block iterator est différents de l'approche objet classique.

                    Sinon, en gros, si je comprends bien COP, c'est un peu SCOOP mais adapté au concept de la programmation par prototype. C'est génial lorsque cela marchera car après avoir lu Meyer, on était vachement frustré de ne pouvoir essayer pour de vrai.

                    Sinon, je te conseille de regarder du coté d'Erlang pour la gestion des erreurs. C'est très intéressant et vraiment différents de ce que font les autres et en plus dans une philosophie multi-coeur. Avec ton COP, cela pouvoir s'intégrer vu le peu que je devine.

                    Ensuite, question timing... On est tous un peu surchargé et c'est pas la tendance ministerielle actuelle qui va changer la donne ;-( C'est dommage qu'il n'y ai pas plus de moyen humains sur ce projet.
    • [^] # Re: Perl..? :-s

      Posté par . Évalué à 0.

      Perl, c'est PHP en vachement mieux.

      Si tu sais coder en PHP, tu sais coder en Perl.
      C'est pas plus dur que ca.
      Et par dessus ca, tu as 9 tonnes de creme chantilly, des tonnes de petits trucs à apprendre/comprendre qui te rendent plus rapide, ton code plus beau, plus puissant ... mais t'es pas obligé, et tu peux les apprendre à ton rythme.

      Et le CPAN.

      Et Perl6.

      Perl, c'est trop bien.
    • [^] # Re: Perl..? :-s

      Posté par . Évalué à 2.

      Bon j'ai appris Perl et finalement, ce n'est pas plus compliqué que ça. Le langage s'apprend assez rapidement surtout pour moi qui ne suis pas un super programmeur.

      Et une fois que l'on a les bases, on s'aperçoit que l'on peut rapidement et très simplement faire des choses assez puissantes. Il y a un grand nombre de modules disponibles. Les règles implicites du langage assurent une certaine rapidité lors de l'écriture d'un script mais il ne faut pas trop en abuser.

      Bref je ne regrette pas d'avoir dépasser mes appréhensions et Perl est maintenant un bon compagnon :)
  • # Polymorphisme

    Posté par . Évalué à 3.

    Ce n’a qu’un rapport lointain avec le journal, mais pour ceux qui n’aiment pas choisir entre les langages, pourquoi ne pas les utiliser tous?

    http://mauke.ath.cx/stuff/poly.html

    Ce script fait un hello world en Perl(6), Ruby, Python, bash, zsh, js, html, C, C++, haskell… Au total une vingtaine de langages et variantes dans le même fichier. C’est assez instructif!
    • [^] # Re: Polymorphisme

      Posté par . Évalué à 1.

      Impressionnant.

      D'ailleurs c'est marrant de constater que la partie 'ruby' et la même que la partie 'perl'. La différence se fait sur la valeur booléenne du nombre 0.

      Je savais que le concepteur du langage ruby c'était inspiré entre autre de perl mais je ne pensais pas que c'était à ce point... :)
  • # Python c'est super !

    Posté par (page perso) . Évalué à 6.

    Si Perl et ses contextes mystiques (opérations magiques selon le contexte) te plaisent, tu risques de pas aimer. Mais je pense que pas mal d'aspects de Python devrait t'intéresser. Python est fortement inspiré de Java, mais est beaucoup plus laxiste et concis (« moins verbeux »).

    Pour les expressions régulières : tout est objet en Python, donc une expression régulière est un objet et un « match » est aussi un objet. Voir la doc :
    http://docs.python.org/library/re.html#regular-expression-ob(...)

    La méthode .sub() (« replace all ») accepter une chaîne ou une fonction pour le remplacement. Exemple : re.sub("([0-9a-f]+)", lambda regs: str(int(regs.group(1), 16)), texte, re.IGNORECASE) convertit les nombres hexadécimaux en décimal ("x=10" donne "x=16"). On peut extraire la lambda fonction (et la définir avant) pour une meilleure lisibilité.

    Pour les traitements sur les ensembles (et non pas uniquement sur les tables de hash ou listes), Python implémente les itérateurs de manière très générique : « for x in data: ... » équivaut à :gen = iter(data)
    while True:
    x = gen.next()
    ...

    Les types de base (dict, list, tuple) implémentent cette API. Mais de nombreux objets l'implémentent également : fichier (lecture ligne par ligne), résultat d'une base de donnée, document XML, etc.

    À partir de ça, on peut créer des expressions de type : « results = [(x * 10) for x in data if (x % 3) == 2] ». C'est la forme abrégée deresults = filter(lambda x: (x % 3) == 2, donnees)
    results = map(lambda x: x*10, donnees)
    ou encore results = []
    for x in donnees:
    if (x % 3) == 2:
    results.append(x * 10)

    Je trouve cette programmation, inspirée des langages fonctionnels, élégante. Bien qu'utilisé abusivement, elle peut rendre le code difficile à relire.

    Je ne connais pas bien Perl, mais je pense que « @liste = %h{@t}; » s'écrit « liste = [h[cle] for cle in t] » en Python. C'est plus verbeux, mais se comprend plus facilement (pas besoin de connaître le sens des préfixes @ et $).

    Au sujet des appels de fonction. En PHP, les objets passés en paramètres sont passés par copie. C'est assez pénible, il faut écrire explicitement &$object pour le passer par référence. Ceci peut être fait dans le prototype de la fonction... ou lorsqu'on l'appelle. S'en suit un gros merdier au niveau des effets de bord. En Python, tous les objets sont passés par références (et tout est objet), sauf que certains objets sont immutables (non modifiables) comme les tuples, les nombres entiers et les chaînes de caractères.

    Pour l'assignation, pareil : c'est une copie de référence et non pas copie de l'objet : a=b fait que a et b pointent sur la même donnée. Par contre, lorsqu'on modifie a, b va être modifié ou non selon la même règle qu'avant :
    - type mutable : a et b sont modifiés
    - type immutable : a forke et crée un nouvel objet

    En gros, Python est un pot pourri de divers langages (un peu de Perl par ci, un peu de Lisp par là, un peu de Java, etc.) mais qui en a extrait le meilleur pour donner un langage homogène et très souple.
  • # Mes 2 cents

    Posté par . Évalué à 5.

    Cela fait environ 10 ans que j'utilise Perl pour mes divers projets. J'ai commencé par là car je suis arrivé sur un projet qui utilisait Perl, et depuis je n'ai pas changé de langage.
    L'une des premières raison est que quelque soit l'Unix sur lequel je travaille, je suis quasiment sûr d'avoir un Perl installé, c'est beaucoup moins sûr avec les autres langages cités dans ce journal.
    Une autre raison est que ce langage correspond parfaitement à mon besoin: analyse de texte, migration de données, manipulation de fichiers,... Je n'ai jamais été confronté à une limitation de ce langage qui m'aurait obligé à utiliser autre chose. Au passage, je me permets également de souligner les performances de Perl pour les traitement sur les fichiers, ça compte quand comme moi on joue avec des fichiers de log compressés de plusieurs Giga. Sur ce terrain là, Python, Ruby and co sont encore loin.

    Je ne l'utilise que de façon simple, comme beaucoup de personnes l'ont signalé ici. Les trucs implicites, oui un peu, mais pas trop.

    @liste = %h{@t};

    je n'aime pas trop par exemple. De même, quand je lis un fichier, je préfère un truc du genre

    while (my $line=<IN>)

    que

    while (<IN>)


    Je pense que le procès d'illisibilité est un faux procès, dans n'importe quel langage on peut écrire des choses illisibles. Il est tout à fait possible avec un peu de discipline de faire un code lisible. Voire par exemple les Best practices de Damian Conway.

    Il y a bien sûr le CPAN, avec son installeur de module en ligne de commande qui résout les dépendances:

    perl -MCPAN -e shell

    cpan shell -- CPAN exploration and modules installation (v1.7602)
    ReadLine support enabled
    cpan> install mon_module

    ...

    Tous les modules nécessaires sont téléchargés et installés, comme apt-get ou yum

    Pour le Web, il y a des frameworks assez complets comme Catalyst ou Mason. Pour ma part, je reste simple avec CGI::Application associé au Template toolkit. C'est propre et simple.

    Et puis, il y a mod_perl, c'est à dire l'intégration de Perl dans Apache, et là, ça déchire vraiment.

    Bref, Perl et moi, ça risque de continuer encore un moment. Je n'ai pas d'impatience particulière vis à vis de Perl6. La seule chose qui m'ennuie un peu dans Perl5, c'est que l'on soit obligé d'implémenter les objets avec des Hash (ou avec une structure "physique" définie), alors que c'est en général opaque dans les autres langages et ça le sera dans Perl6.
  • # A propos de liste et de hash

    Posté par (page perso) . Évalué à 1.

    Tiens, un truc marrant que j'ai découvert en lua : il n' y a pas de distinction entre une liste et un dictionnaire (map pour les perleux).

    La syntaxe est la même :
    mydict[ mykey ] = myvalue

    bien sur, mykey et myvalue peuvent être de type quelconques, un dictionnaire peut stocker un peu n'importe quoi et la clé doit juste être hashable.

    Lua optimise le choix entre liste et dictionnaire en fonction de la taille de l'ensemble et de la présence de clusters de clés.

    Je ne me souviens plus de l'algo, mais une implémentation naive pourrait être :
    - moins de 10 élements, pas besoin de hash, on fait des listes chaînées et des comparaison de clé direct
    - plus de 10 éléments, moins de 30 éléments mais cluster de clé sous forme d'entiers à valeur proche, on garde une liste chaînée
    - tout le reste, on fait des hash avec des dictionnaires

    Bien sur, l'implémentaiton est plus subtile que ça et optimisée pour des cas réels.

    Au début, j'avais trouvé ça étrange mais en y réfléchissant, je trouve ça plutot sympa. Dans les faits, il y a très peu de différences entre une liste de 3 éléments et un dictionnaire de 3 éléments.

    Si tu réfléchis au hash pour lisaac, il y a peut-être des choses à aller chercher là dedans.
    • [^] # Re: A propos de liste et de hash

      Posté par (page perso) . Évalué à 3.

      C'est pas stupide :) Si tu reprend mon laius mathématique du journal.
      Un tableau, un hash, ce sont deux ensembles E et F et une fonction f : E -> F où tablo[val] ∈ F et val ∈ E, avec f(val) = tablo[val].
      Que E soit un sous ensemble de |N ou n'importe quoi, le concept est le même, d'où la possibilité d'indifférencier tableau et hash.

      Historiquement il y a une différence pour des questions de perfs et de hauteur de niveau du langage, mais potentiellement avec un compilateur intelligent, il y a maintenant moyen de pallier facilement à cela...

      « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

  • # foo

    Posté par (page perso) . Évalué à 3.

    j'aime beaucoup plus généralement les langage où je défini mon besoin sans expliquer comment y parvenir, les regexp sont très proches de cet idiome, ainsi que SQL.

    tu devrais regarder Prolog, c'est exactement ça.
  • # suite

    Posté par (page perso) . Évalué à 2.

    Bon allez maintenant t'essai C# 3 ;)
    • [^] # Re: suite

      Posté par (page perso) . Évalué à 2.

      Tu sais bien qu'il est hors de question pour moi de fricoter avec le monde sale, je me salis suffisamment comme ça au boulot.

      Cela dit C#3 a un concept très intéressant, qui m'a l'air pas trop mal implémenté : l'espèce de SQL intégré (LINQ) dont je me servirais abondamment s'il existait en java.
      Pour le reste, C# est un clone de java et ça c'est vraiment l'horreur.

      D'ailleurs, je me demande si les compréhensions de listes de Python permettent de faire ce que permet LINQ
      ( http://en.wikipedia.org/wiki/Language_Integrated_Query )

      « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

      • [^] # Re: suite

        Posté par . Évalué à 2.

        D'ailleurs, je me demande si les compréhensions de listes de Python permettent de faire ce que permet LINQ
        Yes they can !
        -->[]

        Plus sérieusement oui, même si la syntaxe sera bien plus éloignée du SQL.
        Mais vu qu'on peut faire des SELECT avec for, des FROM avec in, des JOIN avec +, des WHERE avec if, etc.

        On peut même le faire en évaluation paresseuse avec les moins connues genexp.
        • [^] # Re: suite

          Posté par (page perso) . Évalué à 1.

          Je viens de jeter un coup d'oeil a Perl et notament vers les modules Inline. pas vu de Inline::SQL par contre on a les

          Inline::Java
          Inline::Python
          Inline::Ruby
          ....

          Je n'ai jamais utilisé en pratique mais c'est bien dans la philosphie Perl de mettre de la glue dans tous les sens.
          • [^] # Re: suite

            Posté par . Évalué à 2.

            pour le SQL on a dbi, qui est assez agréable à utiliser.

            Quant au inline, si tu savais ce qu'on peut faire en c/c++ (des trampolines par exemples) XD!
          • [^] # Re: suite

            Posté par . Évalué à 2.

            Le inline::C c'est marrant :)

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

      • [^] # Re: suite

        Posté par (page perso) . Évalué à 2.

        Clone clone, y'a d'autres trucs qui différencie C# de Java :
        - passage de paramètres par références
        - expressions lambda
        - inférence de type
        - gestion des pointeurs
        - pointeur de méthodes (délégués)
        - méthodes d'extensions
        - coroutine
        - types anonymes
        Au final, LINQ n'est qu'une bibliothèque pas spécifique à C# et utilisable dans d'autres langages. C# ajoute juste un peu de sucre syntaxique au dessus de LINQ.
        • [^] # Re: suite

          Posté par (page perso) . Évalué à 2.

          Ce genre de langage, avec un syntaxe à la C n'est pas ma tasse de thé, question de goût :)
          Toutes ces features sont très bien (sauf la gestion de pointeur, je veux plus entendre parler de pointeur), mais je les retrouves dans les langages que j'aime : Lisaac, Perl, Caml.
          Et plutôt que des délégués, je préferai un bon type Block.

          C'est LINQ qui m'intéresse beaucoup, et qu'il va falloir que je regarde de près, car nous avons le projet de permettre ça dans Lisaac (dans les 2 ans à venir). Il faut donc réfléchir à la syntaxe, est-elle assez simple, comment peut elle s'intégrer avec le langage, peut-on "tout faire" avec, etc...
          Faut reconnaitre que krosoft a fait du très bon boulot avec LINQ. Pour une fois qu'ils ont inventé quelques chose eux-même...

          « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

          • [^] # Re: suite

            Posté par (page perso) . Évalué à 2.

            Je croyais que vous aviez pas les coroutines en Lisaac :)
            • [^] # Re: suite

              Posté par . Évalué à 1.

              Dans mes souvenirs les coroutines dans c# c'est assez limité. Tu n'y a le droit que pour les méthodes qui retournent un IEnumerable.

              Mais bon c'est le c#, compromis sur compromis. Donc c'est sympa tu as un peu de tout, ça reste utilisable mais quelque fois tu aimerais pouvoir aller un peu plus loin.
              • [^] # Re: suite

                Posté par (page perso) . Évalué à 2.

                En même temps tu vois quoi d'autre comme use case ? A part retourner une suite de trucs ?
          • [^] # Re: suite

            Posté par (page perso) . Évalué à 3.

            Et puis pour les blocks, on est pas très loin en C# avec les expressions lambda :
            maLib.Do(
            () => whatyouwanthere()
            )
            .While(
            () => a != b
            )


            On s'éloigne de la syntaxe C que tu détestes :)
            Pareil avec LINQ, on est vraiment loin de ce qu'on lit en C habituellement :
            http://blogs.msdn.com/lukeh/archive/2007/10/01/taking-linq-t(...)
      • [^] # Re: suite

        Posté par . Évalué à 2.

        D'ailleurs, je me demande si les compréhensions de listes de Python permettent de faire ce que permet LINQ

        Ca dépend du sens exact de la question. En tout cas ça ne permet pas de s'interfacer avec une base SQL, ça ne travaille que sur le type liste natif.
  • # haskell

    Posté par (page perso) . Évalué à 5.

    bon, j'ai pas tout suivi, et j'ai eu du mal à comprendre certains trucs.

    Dans tous les langages que je connais, y compris OCaml, si le message/fonction n'existe pas pour le type, le compilateur répond qu'il ne sait pas quoi faire.
    Je n'ai jamais vu le pattern de raisonnement mafonction : ELEMENT1 -> ELEMENT2 => mafonction : COLLECTION[ELEMENT1] : COLLECTION[ELEMENT2].


    tu veux dire un map généralisé? en haskell, c'est vraiment tout simple :

    Prelude> let f x = x + 1
    Prelude> fmap f [1,2,3]
    [2,3,4]
    Prelude> fmap f (Just 5)
    Just 6
    Prelude> :t fmap
    fmap :: (Functor f) => (a -> b) -> f a -> f b

    En gros, ca veux dire que si tu veux que ton type fasse partie du typeclass Functor, tu dois implémenter fmap. Ensuite, fmap s'applique sur toute valeur dont le type fait partie de la typeclass Functor. Ici, les types liste et Maybe (équivalent de l'option en OCaml, un résultat ou pas de résultat).

    Beaucoup de types font partie de cette typeclass (et aussi la typeclass monad, mais ca devient un poil plus compliqué). Tu peux bien sur faire de même pour tes nouveau types.
    • [^] # Re: haskell

      Posté par . Évalué à 5.

      Snif.

      Il y a pas à dire, c'est beau la rencontre des maths et de l'informatique.

      Le foncteur, c'est comme une fonction, mais généralisé sur un ensemble de domaine et de résultat différent, et qui mappe des fonction à d'autre fonction au lieux de mapper d'un ensemble A -> B ... et c'est un concept de theorie_des_categories

      Genre ça mappe n'importe quelle fonction f A->B a une fonction collection(F) : collection(A) -> collection(B) dans notre exemple.

Suivre le flux des commentaires

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