Def a écrit 23 commentaires

  • [^] # Re: Reason

    Posté par  . En réponse à la dépêche OCaml 4.04 et 4.05. Évalué à 7.

    Je vais essayer d'expliquer rapidement, mais il y a des ouvrages entiers sur la question. Si l'on souhaite vraiment comprendre il faut aller plus loin.

    Héritage

    Donc "l'héritage", c'est récupérer du code écrit ailleurs. C'est pas bien différent d'un simple "#include" (après l'implémentation peut-être plus complexe qu'une simple substitution de texte, mais c'est un détail).

    Sous-typage

    Le sous-typage, c'est déterminer quand tu as le droit d'utiliser un objet à la place d'un autre (le contexte attend un X mais toi tu peux fournir un Y : est-ce correct ou pas ?).

    Un petit exemple en supposant que B est un sous-type de A (peu importe comment la relation "être sous-type de" est définie dans le langage).

    Tu implémentes une méthode qui renvoie un A (parce que tu hérites d'une classe qui a défini cette méthode comme renvoyant A). Tu as le droit de renvoyer éventuellement un peu plus (un type plus précis), un B est acceptable :
    - pour les utilisateurs de la classe héritée, ils auront accès au type le plus précis, ils pourront profiter des fonctionnalités de B ;
    - pour les utilisateurs qui accède à la méthode par la classe parente, ils attendent un A, mais il est correct de considérer cette valeur de type B que tu as renvoyé au type A, ils sont contents.

    A contrario, si cette méthode reçoit un argument de type B mais dont tu n'utilises que les méthodes définies dans A, tu peux oublier que c'est un B et être plus général en ne demandant qu'un A. Le raisonnement ci-dessus s'applique dans l'autres sens (les utilisateurs de la classe parente devront toujours fournir un B, c'est pas grave, les utilisateurs de la classe fille auront la privilège de n'avoir qu'un A à fournir).

    Donc dans certains contextes pour être un sous-type, il faut qu'un certain type soit plus précis, dans d'autre il faut qu'il soit plus général.

    Les contextes il faut être plus précis sont dits covariants, car le contexte varie dans le même sens que le type (je suis plus préçis si mon type de retour est plus préçis).
    Les contextes il faut être plus général sont dits contravariants, car le contexte varie dans le sens opposé à ce type (je suis plus préçis si mon argument l'est moins).

    Plus généralement, pour être plus "fort", il faut consommer moins d'informations et en renvoyer d'avantage.

    Sous-typage nominal

    Jusque là c'est de la logique, un dialogue entre appelants et appelés dans les langages de programmations.

    La logique permet de distinguer ce qui a du sens ou pas. On pourrait se dire qu'un langage de programmation peut n'en faire qu'à sa tête et suivre d'autres règles, mais on ne peut vraiment y échapper, ça conduirait à des "Runtime Type Error" : pour être correct il faut au moins faire ça.

    Si l'on considère que l'héritage définit le sous-typage (on dit sous-typage nominal parce que pour savoir si une classe est sous-type d'une autre, on prend les noms des deux classes et on regarde où ils se trouvent dans le diagramme d'héritage), on va se retrouver dans une situation pas très confortable:

    1) Pour commencer, la relation de sous-typage est très grossière, ce sont juste des noms. On voudrait peut-être quelque chose de plus fin, ben on peut pas. Enfin des fois c'est mieux de ne pas donner trop d'outils au développeur.

    2) Comme héritage et sous-typage coïncide, on ne peut pas réutiliser de code sans récupérer toutes les contraintes énoncées au dessus.

    3) Ou alors on décide d'ignorer les contraintes. Les systèmes de types des langages objets ne sont en général pas très fins pour commencer, donc c'est pas très grave on peut s'en sortir un certain temps sans être amené à des incohérences (au pire on "cast").

    Notez que ce n'est pas vraiment une solution recevable : comme on a sous-spécifié le problème, il y a plus de solutions. L'aboutissement est un langage "typé dynamiquement": avec un seul type, on ne risque pas de créer d'incohérences.

    Cela conduit évidemment a des désastres, on encourage donc quand même informellement les règles logiques ci-dessus avec le principe de substitution de Liskov.

    Sous-typage structurel

    En OCaml il n'y a pas de cast, donc on ne peut pas contourner les contraintes logiques. Par contre son système de type (le langage utilisé pour la spécification logique) est suffisamment expressif pour être utilisable sans ces casts: on se retrouve parfois à devoir spécifier précisément, ou bien face à ses propres incohérences et cela aide beaucoup à concevoir une hiérarchie d'objets pas bancale (quitte à la traduire dans un autre langage a posteriori).

    Enfin plutôt que de se restreindre à des noms, OCaml utilise le sous-typage structurel: le sous-typage ne va considérer que les parties d'un objet (représentées par une liste de méthodes) utilisé par un code pour déterminer les contraintes qui s'appliquent. Cette pratique est informellement appelée "duck-typing".

    Le principe de substitution sera respecté par construction, à la granularité de spécification que permet le langage de type d'OCaml.

  • [^] # Re: Alternatives libres...

    Posté par  . En réponse au journal Un nouveau visualiseur de PDF sous Linux. Évalué à 10.

    Mupdf est un bon moteur aussi, facile à embarquer dans une application.
    Disponible sous deux licences (AGPL + commercial).

    Cela appartient à la boîte qui développe aussi Ghostscript.

    La page wikipedia.

  • [^] # Re: Primitive en C pour OCaml

    Posté par  . En réponse au journal Un décalage de 64 bits, ça vous inspire comment ?. Évalué à 9.

    Quand une primitive commence par "%" elle n'est pas implémentée en C mais doit être gérée par le "backend". On peut voir la traduction dans la représentation intermédiaire ici: translcore.ml#L293.

    Pour le backend bytecode (interpréteur), la compilaton se fera vers un opcode dédié pour les entiers taggés (bytegen.ml#L344), et une fonction C externe pour les autres types entiers (bytegen.ml#L420) de la forme:
    caml_{nativeint,int32,int64}_shift_{left,right,right_unsigned} (bytegen.ml#L312).

    Pour les backend natifs, la procédure est un peu plus longue. D'abord quelques optimisations (constant folding dans closure.ml puis unboxing dans cmmgen.ml. Après ces passes, on a encore un langage indépendant de la plateforme ciblée, CMM et les opérations sont maintenant nommées Clsl, Clsr et Casr (cmm.mli#L115).

    Les étapes suivantes vont traduire la primitive vers la ou les instructions appropriées de l'architecture cible: abstraite par Mach.Iasr, implémentée directement par les émetteurs de code (voir Iasr dans arm, arm64, une abstraction de plus pour
    amd64 et i386).

    Et ça peut expliquer pourquoi une sémantique sous-spécifiée a été choisie (mais je spécule) : les shifts sont traduits vers du code très efficace, mais leurs sémantiques côté machine change selon les plateformes. X86 masque les 5 ou 6 derniers bits avant, et donc ça se comporte comme une fonction périodique, ARM sature. Le choix d'OCaml est donc un comportement avec une spécification suffisante mais minimale, et proche de la plateforme pour (le code généré est "prédictible" et efficace). L'utilisateur a toujours la possibilité d'implémenter des fonctions plus fortement spécifiées, le coût ne devrait pas être prohibitif.

  • [^] # Re: c'est quoi la killer feature de Haxe ?

    Posté par  . En réponse à la dépêche La Haxe Foundation recrute son... CEO !. Évalué à 4.

    On "compilait" avant de "transpiler", et pendant des années tout le monde était content.

    (On avait aussi "masturbatoire" avant "isomorphique", et pareil, tout le monde était content).

  • [^] # Re: simple ?

    Posté par  . En réponse au journal Rust en version 0.12. Évalué à 1.

    Il ont une approche basé sur de la composition anonyme et de l'interfaçage structurel.

    Hmm, si on n'a pas fait d'études ça veut dire quoi en pratique ?

    Tertio, l'utilisation de go-pointer comme composant anonyme autorise de se rapprocher de ce qu'on peut faire dans un langage à prototype: Tu crée un objet depuis un objet.
    ça te permet de garder sa contextualisation, son interface et de l'étendre de manière dynamique.

    Je ne suis pas sûr de comprendre non plus. En vrai ce serait bien si tu avais des bouts de codes, liens et/ou des mots clés pour voir des exemples d'utilisation.

  • [^] # Re: La démo de WebODF

    Posté par  . En réponse au journal Owncloud documents. Évalué à 4.

  • [^] # Re: Et go ?

    Posté par  . En réponse à la dépêche Présentation de Rust 0.8. Évalué à 2.

    Lier de nouveaux noms dans une branche.

    Ça c'est révolutionnaire (enfin, il y a 30 ans ça l'était, maintenant c'est juste triste).
    Les langages de programmations courants n'ont quasiment aucune structure pour introduire des disjonctions, par contre les conjonctions il y en a à toutes les sauces. (Quant à passer par une hiérarchie de classes et son visitôr pour introduire une disjonction, vaut mieux être payé à la ligne).

  • [^] # Re: Haskell

    Posté par  . En réponse à la dépêche Sortie d'IPython 1.0. Évalué à 1. Dernière modification le 16 août 2013 à 22:09.

    Qu'est-ce qu'un noyau natif ? En quoi cela diffère de celui de Julia (qui est natif donc) ?
    (Je connais pas du tout ipython, mais ça à l'air cool)

  • [^] # Re: Vive le fonctionnel

    Posté par  . En réponse à la dépêche Publication de la nouvelle norme Ada 2012. Évalué à 2.

    Les logiques sous-structurelles permettent de suivre au niveau du système de types l'utilisation et le partage de ressources (pour traquer des leaks ou de l'aliasing, borner l'utilisation de la mémoire, …).

    Cela permet par exemple de réconcilier pureté et mutations (si une ressource n'est pas partagée et qu'elle est mutée, personne ne pourra observer cette mutation), et conduit à des implantations sûres et efficaces.

    Au niveau des langages permettant de jouer avec ces concepts :

    Pour davantage d'informations :

    http://en.wikipedia.org/wiki/Substructural_type_system

  • [^] # Re: Vive le fonctionnel

    Posté par  . En réponse à la dépêche Publication de la nouvelle norme Ada 2012. Évalué à 1.

    Effectivement, merci pour cette information. Il y a des langages « orientés performances » où l'on peut expérimenter ce genre de fonctionnalités ?

    Sinon, les contraintes de linéarités et autres logiques sous structurelles offrent également des garanties intéressantes pour la génération de codes performants et parallélisables.

  • [^] # Re: Vive le fonctionnel

    Posté par  . En réponse à la dépêche Publication de la nouvelle norme Ada 2012. Évalué à 1.

    Que font les types dépendants dans la cadre du parallélisme ?

  • [^] # Re: dommage

    Posté par  . En réponse au journal The Future of Functional Programming Languages. Évalué à 2.

    Il y a un outil qui fait de l'analyse statique du code OCaml pour propager les exceptions :
    Ocamlexc.

    Ne pas surcharger les annotations de types avec les effets mais conserver une gestion fiable des exceptions est un bon compromis.
    Attention à lire le readme au sujet des constructions récentes. (J'ai un patch quick'n'dirty pour le compiler avec Labltk, je pourrai le mettre quelque part si ça intéresse des gens :)).

  • [^] # Re: C'est ton téléphone le problème !!!

    Posté par  . En réponse au journal Android 4 et MTP sous GNU/Linux. Évalué à 3.

    Hypothèse…

    S'ils proposent de l'UMS, c'est un « block device » qu'ils exportent.
    Si ce block device doit être monté par le système, il faut qu'il soit formatté dans un fs reconnu par ce système, ce qui ne laisse pas grand chose d'autre que (V)FAT.

    Vraisemblablement qu'en mettant le FS contenant les données en EXT4, ils gagnent en performance (j'avais pu vérifier ça sur un vieux Samsung), mais vont au devant de problèmes avec des OS qui ne reconnaitraient pas ce système de fichiers sur le block device exporté.

  • [^] # Re: ai je bien compris?

    Posté par  . En réponse au message Carmageddon Reincarnation Portage sous Linux. Évalué à 3.

    Question pertinente. J'ai dans l'idée qu'habituellement, un producteur suite à son investissement possède une part du produit développé et même un retour sur cet investissement sur le produit est rentable.

    Là en faisant financer le produit par des utilisateurs, c'est bien, on met en avant une communauté qui soutient le projet, et on peut sans doute se passer du modèle habituel avec de gros producteurs, mais à qui appartient le produit au final ?

    S'il s'agit de faire payer deux fois l'utilisateur, ça semble abusif (le studio a le beurre et l'argent du beurre)… En transposant le modèle précédent, il ne faudrait pas plutôt reverser une partie des bénéfices (proportionnelle à son investissement initial, sans doute négligeable pour des dons de « petits particuliers ») ?

    C'est une interrogation sincère, je ne connais absolument rien au financement de projet de manière générale.

  • # Jouons avec les bits

    Posté par  . En réponse au message Optimisation... alignement ou taille mémoire. Évalué à 4.

    Sans trop d'hésitations, s'il y a beaucoup de données il vaut mieux limiter la pression sur les caches et les accès mémoires. La décapsulation par le CPU a un coût négligeable (essentiellement des opérations logiques et des décalages, il aime faire ça) devant les I/O sur le bus mémoire.

    Donc pour privilégier les performances dans ce cas précis, les champs sont tout indiqué. La seule mise en garde étant de ne pas faire d'optimisation prématurée, d'autant que la manipulation des champs de bits est plus sujette à erreur qu'un accès direct.

    Naturellement, prendre soins d'abstraire cette partie du code en tant compte des contraintes respectives de ces deux options te permettra de choisir l'option la plus appropriée le moment venu.

  • [^] # Re: Et ubuntu ne suffit pas pour voter...

    Posté par  . En réponse au journal Le vote par internet, c'est encore mieux quand c'est bien fait.... Évalué à 2.

    Tu as vu juste :

    http://www.monvotesecurise.votezaletranger.gouv.fr/assistance-technique.html#QB-6

    […] Notez que sous Linux, vous devez utiliser la version officielle de Java telle que fournie par Oracle. OpenJDK n’est pas supporté.

    Je ne suis pas aussi tolérant qu'eux, toutes versions confondues, Java m'insupporte.

  • [^] # Re: Comparer les prix au poids ?

    Posté par  . En réponse à la dépêche Linus Torvalds sélectionné pour le Millennium Technology Prize édition 2012 . Évalué à 1.

    La tournure est effectivement malheureuse.

    Également, il y a une faute de frappe dans le cœur de la dépêche : il s'agit de Linus Torvalds et non Linux Torvalds :).

  • [^] # Re: Utile, pas plus compliqué qu'autre chose

    Posté par  . En réponse au journal À propos de GPG et de son avenir. Évalué à 4.

    Je pense qu'il doit être possible d'utiliser GPG sans rien connaitre à la crypto et à la certifciation.

    Cela doit être possible. Et je reconnais que les interfaces ne sont pas conçues pour être facile d'utilisation, c'est dommage et ça mérite d'être amélioré. Je ne suis pas spécialiste du sujet, je ne me suis pas aventuré très loins dans les manipulations autour de GPG : à peine plus que le minimum pour tirer parti des fonctionnalités « de base » (signer et/ou chiffrer un mail, gérer ses clés).

    À côté de ça, si ma mémoire ne me trompe pas, il y a avait beaucoup d'options de configuration aux noms cryptiques qui semblaient avoir un impact non négligeable sur la fiabilité de GPG. J'ai naïvement fait confiance aux options par défaut et aux paramètres recommandés, j'espère que ma configuration n'est pas plus bancale que la moyenne.

    Ce qui nous amène à : utiliser GPG sans rien connaître à « la crypto et à la certification » à tout l'air d'une mauvaise idée. Sans rien connaître à la crypto, la valeur ajoutée de GPG est nulle : si l'on est incapable d'interpréter les informations fournies par GPG ou que l'on a pas de notion de « l'hygiène » qui accompagne à la gestion des clés, pourquoi s'embêter à rajouter cette étape dans l'utilisation quotidienne des mails ? J'y vois l'effet pervers de procurer à tort une sensation de sécurité. Voire même de fragiliser la confiance dans le reste du système, une mauvaise utilisation d'un outil étant nécessairement plus dangereuse qu'aucune utilisation de celui-ci.

    L'utilisation clickodromique qui peut faire ses preuves pour quelques services courants en permettant agréablement de ne pas comprendre ce qu'il se passe est beaucoup moins pertinente quand il est question de sécurité, d'authentification, d'identification, etc.

  • # C'est mieux sans…

    Posté par  . En réponse au journal /kick flash #firefox. Évalué à 10.

    Ça fait un bout de temps que je l'ai viré, et c'est vrai que depuis peu youtube marche très bien sans flash.

    Pour ne plus avoir cette barre, dans about:config :
    plugins.hide_infobar_for_missing_plugin = true

  • [^] # Re: J'aimerais

    Posté par  . En réponse au journal Votre langage idéal ?. Évalué à 4.

    Un aspect que je n'ai pas vu développé dans les discussions : les systèmes de types ne sont pas nécessairement une corvée pour le développeur. J'y vois au moins deux avantages, pour un système de type suffisamment puissant.

    En tant que développeur, un travail que je trouve parmi les plus agréables est de représenter ou contraindre le domaine du problème que je cherche à résoudre avec des types. Une fois une interface élégante trouvée, il ne me reste souvent qu'à me laisser guider par les types pour le remplissage… Dans les cas les moins évidents, la solution ne peut apparaître limpide qu'en présence d'informations de types.

    En tant qu'utilisateur de codes existants, des informations de types riches servent d'autodocumentation, et pour les mêmes raisons que ci-dessus, un coup d'œil aux types permet de saisir le domaine et parfois même l'approche choisie par le développeur d'origine.

  • [^] # Re: Économies d'échelle

    Posté par  . En réponse au journal You wouldn't download a car !?. Évalué à 3.

    Effectivement…
    Je n'ai aucun chiffre a avancer là-dessus, mais en observant mon entourage j'ai parfois l'impression que le téléphone est un appareil jetable. Je ne me rappelle pas avoir vu cela avant, en tout cas pour un équipement à la fois « high-tech » et grand public.
    Les pratiques des opérateurs téléphoniques rendent cela normal. C'est même le contraire, refuser un téléphone lié à l'abonnement serait presque suspect.
    Les pratiques des constructeurs également favorisent cela : sortir une énorme quantité de téléphones, dont aucun n'est fini ou pleinement fonctionnel, et pour ceux qui sont nintelligents, le support logiciel est rapidement abandonné (1 an pour mon téléphone).

    Il faut relativiser, ça reste du « à la louche » sur une faible partie de la population, néanmoins suffisante pour être observée quotidiennement (en un tour de métro en voit beaucoup de téléphones très récents, iPhone 4 en tête).

  • # Priorité des opérateurs

    Posté par  . En réponse au message Haskell, problème de strictitude de do. Évalué à 4. Dernière modification le 18 décembre 2011 à 00:52.

    La ligne :

    displayCallback $= clear [ColorBuffer] >> flush
    
    

    Est analysée par le compilateur comme :
    (displayCallback $= clear [ColorBuffer]) >> flush
    
    

    Donc le flush a lieu dans l'action du main, pas dans le
    displayCallback qui survient plus tard. Donc le displayCallback effectue pleins de "clear [ColorBuffer]", sans jamais flush.

    À l'opposé :

    displayCallback $= do clear [ColorBuffer] ; flush
    
    

    Devient :
    displayCallback $= (clear [ColorBuffer] >> flush)
    
    

    Ce qui est vraisemblablement ce que tu veux vraiment faire.

    Cela vient du fait que $= est prioritaire sur >> dans la définition.

    Pour voir les priorités :

    Prelude> import Graphics.UI.GLUT
    Prelude Graphics.UI.GLUT> :info ($=)
    class HasSetter s where ($=) :: s a -> a -> IO ()
            -- Defined in Data.StateVar
    infixr 2 $=
    Prelude Graphics.UI.GLUT> :info (>>)
    class Monad m where
      ...
      (>>) :: m a -> m b -> m b
      ...
            -- Defined in GHC.Base
    infixl 1 >>
    Prelude Graphics.UI.GLUT>
    
    
  • [^] # Re: le temps de le telecharger et de faire quelques tests, et je reviens te dire

    Posté par  . En réponse au message Fichier vidéo illisible . Évalué à 1.

    Bonjour,

    Je suis tombé sur un soft qui se présente comme tel (bon, il s'agit plutôt d'un hack quick&dirty) :
    http://vcg.isti.cnr.it/~ponchio/untrunc.php

    L'idée est de reconstruire le fichier corrompu à partir d'un fichier correct produit par le même matériel. Je ne sais pas ce que ça vaut, les fichiers de tests que j'avais ne contenaient pas d'AAC, le seul codec audio pris en charge.

    Enfin, un patch pour compiler, pas testé pour la même raison, avec la dernière version de libavcodec :
    http://pastebin.com/3v86wYJw