kantien a écrit 1189 commentaires

  • [^] # Re: alternative crédible

    Posté par  . En réponse au journal Le courage de l'innovation. Évalué à 3.

    chouchou : j'trouve pas d'réseau wifi dans cette maison ?! C'est nul, y'a pas l'internet !!!! :-(
    moi : mais si ! faut juste que tu t'colles un fil à la patte : l'ethernet c'est le top pour l'internet ! \o/
    chouchou : j'm'en fous d'ton fil, mets moi le wifi !!!!! :@

    Voilà une situation qui me semble bien plus proche de la réalité pour la grande majorité de la population. ;-)

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: abort != avorter

    Posté par  . En réponse au journal Gestion des erreurs d’allocation mémoire en C. Évalué à 2.

    les tournures utilisées sont différentes, typiquement faire avorter (en général un projet). […]

    Reste que la langue principale de l'informatique est l'anglais, langue dans laquelle le verbe abort est le mot exact pour décrire l'interruption, volontaire ou non, mais souvent brutale, d'un processus, d'une applications, etc. en informatique. […]

    En conséquence, j'en déduis que sans trop de difficultés que la proximité de la formulation anglaise est probablement plus qu'un vague cousinage avec l'usage qui est fait ici de avorter et avortement.

    Il est vrai que si le verbe anglais to abort et le verbe français avorter sont issus d'une racine commune, l'évolution de l'usage anglais en a fait un verbe qui peut être intransitif ou transitif. Là où en français, lorsque le sujet de la proposition est l'agent qui pratique l'avortement, on préférera utiliser des formulations comme « faire avorter qqch. », « arrêter qqch. » ou « interrompre qqch. ». Comme le montre ces quelques exemples issus de linguee :

    If something is wrong, abort the take off. Si quelque chose ne va pas, arrêtez le décollage.
    Foolish haste or laziness could abort a great hope-with consequences that we do not imagine. Une hâte imbécile ou de l'indolence pourraient faire avorter un grand espoir, avec des conséquences que nous ne pouvons pas imaginer.
    […] have preprogrammed safety checks that will signal problems by means of error messages and will abort the testing procedure. […] de sécurité préprogrammés signaleront les problèmes au moyen de messages d'erreur et provoqueront l'interruption du test.

    Malgré cela, le projet ourdi en secret par les grammar nazi afin de conquérir le monde n'a pas encore avorté. :-P

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: abort != avorter

    Posté par  . En réponse au journal Gestion des erreurs d’allocation mémoire en C. Évalué à 2.

    Certes mais, comme il t'a répondu, il l'utilise bien comme une verbe intransitif dans son journal. Du moins, on peut discuter ce dernier point. En dehors de son usage en titre de section, il écrit :

    d’autres ont déjà fait le choix d’avorter en cas d’erreur

    On peut soit considérer que les auteurs ont décidé d'avorter le programme (qui serait ici sous-entendu en fonction objet) ce qui en ferait bien un usage incorrect en tant que verbe transitif; soit, toujours dans une acception figurée du verbe, considérer que le programme représente le processus par lequel les auteurs veulent engendrer un résultat et ils décident d'avorter en cas d'erreur produisant ainsi quelque chose étant mort; ou encore on pourrait écrire, par métonymie, en substituant l'agent par l'instrument : le programme avorte en cas d'erreur.

    Quoi qu'il en soit, je ne vois toujours pas en quoi un tel usage relève d'un affreux anglicisme (sic). ;-)

    Aucun drosophile n'a été abusé sexuellement au cours de cet échange linguistique.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: abort != avorter

    Posté par  . En réponse au journal Gestion des erreurs d’allocation mémoire en C. Évalué à 2.

    C'est un affreux anglicisme !

    C'est surtout un « affreux » latinisme au sens figuré ! Il y a aussi du latin dans la langue anglaise, et ce sens figuré se pratiquait déjà en France au XIIe siècle. ;-)

    fin xiie s. fig. « ne pas réussir, échouer »

    Étymologie sur le CNRTL

    Mot qui vient du latin aborto : mettre à jour avant terme.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: TP-Link et FCC

    Posté par  . En réponse au journal Point d'étape sur le matériel et nos libertés partie 2. Évalué à 5. Dernière modification le 26 octobre 2016 à 18:35.

    Article intéressant à plus d'un titre. Voici mon résumé de ce que j'en ai compris :

    TP-link a écopé d'une amende de 200.00 $ parce qu'ils vendaient des routeurs permettant d'être utilisés à une puissance supérieure à la limite autorisée par les règles de la FCC. Mais cette infraction ne relevait pas de la nouvelle réglementation sur le 5 GHz, dont parle le journal, mais des règles sur la bande à 2.4 GHz : en changeant une option dans la configuration du routeur (le code du pays) celui-ci pouvait émettre à une puissance trop forte. Pour corriger le tir, TP-link a fait une mise à jour de son firmware qui au passage empêchait l'installation de tout autre firmware issu de tierce partie : telle fut la solution choisie pour satisfaire au passage à la nouvelle réglementation sur le 5 GHz. Ce en quoi le règlement du FCC ne stipule pas que l'on ne puisse installer d'autre firmware que ceux fournis par TP-link, mais seulement que ceux-ci ne doivent pas permettre d'utiliser le matériel en dehors des limites légales. Et finalement, pour ne pas payer une amende plus importante, la FCC et TP-link sont tombés sur un accord obligeant ce dernier a collaboré avec les fabricants de chipset Wi-Fi et la communauté open-source pour permettre aux utilisateurs d'installer le firmware de leur choix. On apprend de plus, en fin d'article, que Linksys, sans être contraint de le faire, a déjà travaillé avec Marvell et OpenWRT pour être certain que ses routeurs satisferont la nouvelle législation sans bloquer les firmwares libres.

    Me vient donc deux questions :

    • en quoi cette nouvelle réglementation porte-t-elle réellement atteinte à la liberté des utilisateurs ?
    • Les coûts pour permettre l'installation de firmware libre tout en respectant la législation sont-ils bien de l'ordre du million de dollars, étant que donné que TP-link a accepté cette décision pour réduire le montant de son amende ?

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Remarques diverses et ... tardives

    Posté par  . En réponse au journal Gestion de l'erreur - C++ - std::optional. Évalué à 1.

    Effectivement c'est une meilleure approche si on veut plus d'information sur la raison de l'échec.

    Dans le même genre, à la place des Maybe a, en Haskell on peut utiliser les data Either a b = Left a | Right b.

    Et en Ocaml, il y a soit le type 'a option = None | Some of 'a soit le type ('a, 'b) result = Ok of 'a | Error of 'b.

    Ce qui correspond à la classe std::expected<T,E> proposée pour le C++ :

    Class template expected<T,E> proposed here is a type that may contain a value of type T or a value of type E in its storage space. T represents the expected value, E represents the reason explaining why it doesn’t contains a value of type T. The interface and the rational are based on std::optional N3793. We can consider expected<T,E> as a generalization of optional<T>.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Jai: Language for game programmming

    Posté par  . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.

    Dans la série liens intéressants et instructifs : Demystifying Type Classes sur le site de Oleg Kiselyov. D'une manière générale, son site est une véritable mine d'or ! :-)

    Sur cette page, il y explique de manière didactique et complète le principe des type classes en étudiant trois implémentations possibles du système dans un langage : par passage de dictionnaire, par monomorphisation ou par analyse intentionnelle de type. La première étant la plus répandue et les deux secondes étant issues de l'article pionnier sur le sujet : Parametric overloading in polymorphic programming languages de Stephan Kaes en 1988 (un lien vers cet article est donné en bas de page).

    On y trouve aussi une comparaison avec des techniques du C++, comme il le souligne en conclusion :

    We have presented the intensional type analysis, the third way of compiling type classes. Whereas monomorphization is akin to C++ template instantiation and dictionary passing is similar to vtable, the intensional type analysis reminds one of resolving overloading by a large switch statement.

    Traduction rapide :

    Nous avons présenté l'analyse intentionnelle de type, la troisième façon de compiler les classes de type. Tandis que la monomorphisation est similaire à l'instantiation de template C++ et le passage de dictionnaire est similaire aux vtable, l'analyse intentionnelle de type fait penser à la résolution de surcharge comme à un grand switch.

    La dernière technique m'a donné une idée un peu différente de la sienne, mais largement inspirée de son illustration en OCaml, en utilisant des types sommes ouverts et des GADT. Exemple avec la fonction show :

    (* on définit un type somme ouvert dans lequel on peut rajouter des cas après coup *)
    type 'a showable = ..
    
    (* on définit la fonction show pour ce type encore vide *)
    let show : type a. a showable -> a -> string =
      fun _ x -> failwith "failed overloading resolution";;
    val show : 'a showable -> 'a -> string = <fun>
    
    (* on rajoute des cas dans le type avec leur instance pour show *)
    type 'a showable += Int : int showable;;
    type 'a showable += Int : int showable
    
    let show : type a. a showable -> a -> string = function
      | Int -> string_of_int
      | ty -> show ty;;
    val show : 'a showable -> 'a -> string = <fun>
    
    type 'a showable += Bool : bool showable;;
    type 'a showable += Bool : bool showable
    
    let show : type a. a showable -> a -> string = function
      | Bool -> string_of_bool
      | ty -> show ty;;
    val show : 'a showable -> 'a -> string = <fun>
    
    type 'a showable += List : 'a showable -> 'a list showable;;
    type 'a showable += List : 'a showable -> 'a list showable
    
    let show : type a. a showable -> a -> string = function
      | List ty ->
        fun l ->
          let rec loop first = function
            | []   -> "]"
            | h::t ->  
                (if first then "" else ", ") ^ show ty h ^ loop false t
          in "[" ^ loop true xs
      | ty -> show ty;;
    val show : 'a showable -> 'a -> string = <fun>
    
    (* quelques exemples *)
    show Int 1;;
    - : string = "1"
    
    show Bool true;;
    - : string = "true"
    
    show (List Int) [1; 2; 3];;
    - : string = "[1, 2, 3]"
    
    (* limitations du système *)
    
    (* on définit une fonction print sur les showable *)
    let print ty x = print_endline (show ty x);;
    val print : 'a showable -> 'a -> unit = <fun>
    
    (* cela marche bien... pour l'instant *)
    print Int 1;;
    1
    - : unit = ()
    
    print (List Int) [1; 2; 3];;
    [1, 2, 3]
    - : unit = ()
    
    (* maintenant on rajoute les float mais sans implémentation pour show *)
    type 'a showable += Float : float showable;;
    type 'a showable += Float : float showable
    
    (* la c'est normal, dans le grand switch le cas Float n'est pas encore géré *)
    print (Float) 1.2;;
    Exception: Failure "failed overloading resolution".
    
    (* on rajoute le cas au switch *)
    let show : type a. a showable -> a -> string = function
      | Float -> string_of_float
      | t -> show t;;
    val show : 'a showable -> 'a -> string = <fun>
    
    show Float 1.2;;
    - : string = "1.2"
    
    (* et là : pouf, ça marche pas pour print !!! *)
    print (Float) 1.2;;
    Exception: Failure "failed overloading resolution".
    
    (* la raison en est que en OCaml lorsque l'on définit un terme,
     * sa définition ne doit dépendre que des termes déjà défini qui le précèdent
     * et donc rajouter un cas à show après avoir défini print ne change rien à son code :
     * il faut la redéfinir à chaque fois que l'on rajoute une instance :-/ *)
    let print ty x = print_endline (show ty x);;
    val print : 'a showable -> 'a -> unit = <fun>
    
    print Float 1.2;;
    1.2
    - : unit = ()
    
    (* au final cette implémentation n'est pas compatible avec la programmation
     * modulaire et les avantages des compilations séparées. *)

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Harmonie ?

    Posté par  . En réponse à la dépêche Sortie de la bibliothèque d’analyse musicale Bliss 1.0. Évalué à 3.

    La prise en compte de l'harmonie est intéressante, mais je crois qu'elle sert un objectif un peu différent.

    C'est vrai mais cela peut être une piste intéressante à explorer pour les futures évolutions de la bibliothèque.

    Lorsque l'on conçoit une set list pour un concert, ou même lorsque l'on réfléchit à l'ordre des chansons sur un album c'est une information que l'on prend en compte. Le principe ayant était poussé à l'extrême sur l'album concept Le fil de Camille qui tournait autour de la note si restant en bourdon.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Money makes the world go round

    Posté par  . En réponse au journal Les routeurs Turris Omnia sont livrés. Évalué à 4.

    La publicité c'est du temps et des moyens = de l'argent.

    Non, pas nécessairement.

    Si tu contribue à un logiciel, c'est du temps = de l'argent.

    Non, pas nécessairement.

    Comme tu ne sembles toujours pas comprendre ce qu'est l'argent, je vais extraire la partie la plus importante sur le sujet du lien que j'ai donné plus haut (le texte est long, mais ça vaut le coup de le lire si tu veux bien comprendre de quoi tu parles lorsque tu parles d'argent).

    Vous avez un écu. Que signifie-t-il en vos mains ? Il y est comme le témoin et la preuve que vous avez, à une époque quelconque, exécuté un travail, dont, au lieu de profiter, vous avez fait jouir la société, en la personne de votre client. Cet écu témoigne que vous avez rendu un service à la société, et, de plus, il en constate la valeur. Il témoigne, en outre, que vous n’avez pas encore retiré de la société un service réel équivalent, comme c’était votre droit. Pour vous mettre à même de l’exercer, quand et comme il vous plaira, la société, par les mains de votre client, vous a donné une reconnaissance, un titre, un bon de la République, un jeton, un écu enfin, qui ne diffère des titres fiduciaires qu’en ce qu’il porte sa valeur en lui-même, et si vous savez lire, avec les yeux de l’esprit, les inscriptions dont il est chargé, vous déchiffrerez distinctement ces mots : « Rendez au porteur un service équivalent à celui qu’il a rendu à la société, valeur reçue constatée, prouvée et mesurée par celle qui est en moi-même. »

    Maintenant, vous me cédez votre écu. Ou c’est à titre gratuit, ou c’est à titre onéreux. Si vous me le donnez comme prix d’un service, voici ce qui en résulte : votre compte de satisfactions réelles avec la société se trouve réglé, balancé et fermé. Vous lui aviez rendu un service contre un écu, vous lui restituez maintenant l’écu contre un service ; partant quitte quant à vous. Pour moi je suis justement dans la position où vous étiez tout à l’heure. C’est moi qui maintenant suis en avance envers la société du service que je viens de lui rendre en votre personne. C’est moi qui deviens son créancier de la valeur du travail que je vous ai livré, et que je pouvais me consacrer à moi-même. C’est donc entre mes mains que doit passer le titre de cette créance, le témoin et la preuve de la dette sociale. Vous ne pouvez pas dire que je suis plus riche, car si j’ai à recevoir, c’est parce que j’ai donné. Vous ne pouvez pas dire surtout que la société est plus riche d’un écu, parce qu’un de ses membres a un écu de plus, puisqu’un autre l’a de moins.

    Que si vous me cédez cet écu gratuitement, en ce cas, il est certain que j’en serai d’autant plus riche, mais vous en serez d’autant plus pauvre, et la fortune sociale, prise en masse, ne sera pas changée ; car cette fortune, je l’ai déjà dit, consiste en services réels, en satisfactions effectives, en choses utiles. Vous étiez créancier de la société, vous m’avez substitué à vos droits, et il importe peu à la société, qui est redevable d’un service, de le rendre à vous ou à moi. Elle s’acquitte en le rendant au porteur du titre.

    Maudit argent !

    L'argent n'apparaît que lors des échanges à titre onéreux et non à titre gracieux : autrement dit lorsqu'une personne dit à une autre « j'accepte de faire cela pour toi à la seule condition que tu fasses ceci pour moi ». On peut même dire que ce sont ces types de contrats qui créent l'argent : l'argent ce n'est que de la reconnaissance de dette. Il ne fait que représenter un troc suspendu, différé ou non finalisé.

    Il y a une grande différence entre ces trois propositions :

    • tous les échanges doivent être onéreux ;
    • tous les échanges doivent être gracieux ;
    • les échanges peuvent être onéreux ou gracieux.

    Ce que l'on te dit c'est que l'on ne peut exiger d'autrui qu'il échange avec nous à titre gracieux, c'est-à-dire sans contrepartie.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Tél

    Posté par  . En réponse au journal Les routeurs Turris Omnia sont livrés. Évalué à 1.

    L'important ce n'est pas les deux numéros, mais qu'ils correspondaient à deux lignes distinctes. Chez Orange, j'ai toujours eu une ligne branchée directement sur la prise et l'autre était branchée sur la box. Si tu appelais le numéro en 09, les téléphones connectés directement à la prise ne sonnaient pas. Dans ton cas, les numéros en 01 et 09 correspondent-ils à deux lignes distinctes ou sont-ce deux alias pour la même ligne ?

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Tél

    Posté par  . En réponse au journal Les routeurs Turris Omnia sont livrés. Évalué à 2. Dernière modification le 21 octobre 2016 à 09:54.

    Merci, mais ça ne parait pas techniquement possible ?

    Cela doit bien être possible, étant donné que c'est réel : cela fonctionne comme cela chez moi. ;-) Pour les détails techniques, je n'ai aucune idée de la manière dont cela fonctionne.

    Avant j'avais deux lignes : une avec le préfixe en 01-05 (selon la région) et une autre en 09. Maintenant je n'ai plus que la première avec la même offre que celle que j'avais avec la seconde, ce qui est tout de même plus simple pour l'usager : il ne fallait pas se tromper de ligne lorsque l'on appelait.

    Edit : je parle de l'offre ADSL.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Money makes the world go round

    Posté par  . En réponse au journal Les routeurs Turris Omnia sont livrés. Évalué à 5.

    Dit autrement, le libre est pour toi synonyme de gratuit

    Sophisme?
    Logiciel libre,oui complètement

    Il y a un malentendu sur la notion de logiciel libre. Pour citer la référence FSF et RMS :

    To understand the concept, you should think of “free” as in “free speech,” not as in “free beer”. We sometimes call it “libre software,” borrowing the French or Spanish word for “free” as in freedom, to show we do not mean the software is gratis.

    Traduction : « Pour comprendre le concept, vous devriez penser à « free » comme dans « liberté d'expression », non comme dans « bière gratuite ». Nous l'appelons parfois « logiciel libre », empruntant le mot français ou espagnol pour « free » comme dans « liberté », pour monter que nous ne signifions pas par là que le logiciel est gratuit. »

    Le texte original est essentiellement destiné aux anglophones, car en anglais le mot « free » peut signifier aussi bien « libre » que « gratuit », ambiguïté qui n'existe pourtant pas dans la langue française.

    Pour rebondir sur la remarque « l'argent n'est que du travail figé » de Marotte, je rajouterai que le principe de base de l'économie marchande c'est le troc : je te donne ça si tu me donnes ça en échange ou je fais cela pour toi si tu fais cela pour moi, i.e. échange de biens et services. L'argent c'est juste un troc non finalisé, et permet de recevoir en échange du service rendu un service de la part d'une autre personne que celle à qui l'on a rendu service : c'est un bien qui améliore grandement les échanges librement consentis de services, là où sans cela le système de ton village africain ne pourrait nullement passer à l'échelle. ;)

    Maudit argent !

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Tél

    Posté par  . En réponse au journal Les routeurs Turris Omnia sont livrés. Évalué à 2.

    En branchant son téléphone directement sur la prise téléphonique. L'offre d'appels illimités vers fixes et mobiles, qui auparavant était réservée au numéro lié à l'abonnement dual play, est dorénavant valable pour l'abonnement de la ligne fixe.

    Chez les autres, je n'en sais rien, mais a priori je dirais que c'est spécifique à Orange : avant il y avait deux lignes, maintenant il n'y en a plus qu'une, et je ne crois pas que les autres opérateurs proposent une telle offre.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: À la recherche du troll

    Posté par  . En réponse au journal Les routeurs Turris Omnia sont livrés. Évalué à 4.

    Il est là :

    • processeur ARM double cœur à 1,6 GHz (Marvel Armada 385), avec 1 Gio de mémoire vice ;

    Le routeur conserve jusqu'à un Gio de comportements que la morale réprouve pour ensuite faire son rapport à l'État tchèque : c'est du flicage en règle des citoyens ! :-P

    Bon sinon j'ai cherché le troll également dans le journal à l'origine de la dépêche et n'ai rien trouvé. Comme dirait Christophe Maé : il est où le troll, il est où ? Il est où ?

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Tél

    Posté par  . En réponse au journal Les routeurs Turris Omnia sont livrés. Évalué à 2.

    Chez Orange, il n'est plus nécessaire de passer par la box pour la téléphonie, donc je ne pense pas que cela puisse poser un quelconque problème avec l'Omnia.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Paradoxale ?

    Posté par  . En réponse à la dépêche ONLYOFFICE ouvre le code source des éditeurs de bureau. Évalué à 10.

    L'éthique c'est une norme totalement artificielle que chacun se crée, pour les gens qui poussent ça en avant c'est une forme de croyance qui sert à s'abstenir de réfléchir. On met des étiquettes sur ce qui est valide ou non au près de cette éthique et on piétine le reste. Affirmer que quelque chose est néfaste en expliquant pourquoi c'est bien, expliquer que cette même chose est néfaste parce qu'elle ne suit pas ton éthique ça peut être très grave.

    Qu'est-ce que l'éthique si ce n'est la doctrine des devoirs ? Qu'est-ce que le bien si ce n'est un acte accompli en conformité avec le devoir, et le mal si ce n'est un acte contraire au devoir ?

    Comment peut-on rejeter l'éthique comme doctrine à valeur universelle en en faisant une « norme totalement artificielle que chacun se crée » (sic), pour dans la foulée qualifier de bien une action et de très grave (comprendre : mal) une autre ? D'autant plus que les deux actions concernées consistent à porter un jugement de nature éthique sur quelque chose, et ne se distinguent que sur le fondement apparent d'un tel jugement ?

    On arrive à peu de chose près à la situation suivante : il est admis de porter objectivement1 un jugement éthique sur une chose en la qualifiant de néfaste, tout en admettant que tout jugement éthique est nécessairement subjectif. Il y a une incohérence flagrante dans les thèses soutenues.

    Je peux à la rigueur admettre que l'on doute, voire rejette, le concept d'un système de normes universelles (i.e valant pour tout homme, en tout lieu et en tout temps) du devoir, mais par soucis de cohérence il vaudrait mieux bannir des expressions comme « il faut », « c'est bien », « très grave », ou des mots comme « néfaste » de son vocabulaire.


    1. le jugement en question est bien objectif car le qualificatif « néfaste » est prédiqué de la chose. Il est écrit : « affirmer que quelque chose est néfaste », et non : « affirmer que quelque chose m'est néfaste »; auquel cas le jugement aurait bien valeur subjective

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Paradoxale ?

    Posté par  . En réponse à la dépêche ONLYOFFICE ouvre le code source des éditeurs de bureau. Évalué à 2.

    Je comprends mieux, au départ j'ai cru que ton commentaire n'en était pas un sur le cyclimse.

    Et comme l'a dit le grand George : il ne faut pas faire d'amalgame entre la coquetterie et la classe ! :-P

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • # Faire des monades en C++

    Posté par  . En réponse au journal Gestion de l'erreur - C++ - std::optional. Évalué à 3.

    Comme le commentaire du dessus, je suis en retard par rapport à la date de publication du journal : je l'ai découvert via la dépêche sur les contenus primés de septembre.

    Je voudrais juste signaler un article sur les monades en C++ étant donné que c'est ce qui est présenté en fin d'article pour gérer les std::optional via une option monad.

    L'article compare les deux approches entre Haskell et C++, ce qui pourrait intéresser l'auteur du journal qui, je le sais, apprécie particulièrement le langage Haskell.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Jai: Language for game programmming

    Posté par  . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 0.

    Petite précision pour illustrer qu'une fois le système des modular implicits définitivement mis au point et stabilisé, cela ne demandera pas de grands changements dans la base de code existante.

    Pour rappel, on peut déjà écrire :

    module type Num = sig
      type t
      val add: t -> t -> t
      val mul: t -> t -> t
    end;;
    module type Num = sig type t val add : t -> t -> t val mul : t -> t -> t end
    
    let add (type a) (module M:Num with type t = a) i j = M.add i j;;
    val add : (module Num with type t = 'a) -> 'a -> 'a -> 'a = <fun>

    Avec les modules de première classe, on a déjà un polymorphisme élargi mais le module doit être donné explicitement. Les modules Int32 et Int64 correspondent à cette interface, même s'ils définissent plus de choses : il n'est pas nécessaire de se restreindre aux seuls éléments d'une interface pour la satisfaire, il suffit qu'ils y soient. D'où :

    add (module Int32) 21l 21l;;
    - : int32 = 42l
    
    add (module Int64) 21L 21L;;
    - : int64 = 42L

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Jai: Language for game programmming

    Posté par  . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 1. Dernière modification le 14 octobre 2016 à 16:42.

    Il n'y a pas de quoi pour mes réponses, on est là pour échanger et partager. Quand j'ai du temps, j'essaye d'être assez précis, d'illustrer le plus que je peux et de fournir des références si le lecteur veut prolonger sa réflexion de son côté.

    Pour les différentes représentations, elles ont chacune leur module avec leurs opérateurs propres :

    • module Int32 pour les entiers 32-bits signés;
    • module Int64 pour les entiers 64-bits signés;
    • module Num pour les opérations sur des rationnels en précision arbitraire.
    (* exemple sur les Int32 *)
    Int32.add 32l 64l;;
    - : int32 = 96l
    
    (* mais on peut le renommer localement + si on préfère *)
    let (+) = Int32.add in 32l + 54l;;
    - : int32 = 86l
    
    (* idem avec les Int64 *)
    Int64.add 32L 544L;;
    - : int64 = 576L
    
    let (+) = Int64.add in 32L + 544L;;
    - : int64 = 576L
    
    (* mais si on travaille dans un module où l'on ne manipule
     * que des Int32, il suffit de l'ouvrir et de renommer *)
    open Int32;;
    
    let (+) = add;;
    val ( + ) : int32 -> int32 -> int32 = <fun>
    
    127l + 233l;;
    - : int32 = 360l
    
    (* là comme j'étais dans la REPL j'ai perdu le + sur les int
     * il me suffit de le renommer et c'est good ! :-) *)
    let (+) = Pervasives.(+);;
    val ( + ) : int -> int -> int = <fun>
    
    21 + 21;;
    - : int = 42

    Une fois qu'il y aura le polymorphisme ad hoc, on pourra avoir un opérateur + « unique » pour les différentes représentations. J'ai mis les guillemets car en réalité, cela correspond à un seul alias pour différents codes mais qui préserve tout de même l'essentiel : le typage fort du langage.

    En attendant, on peut néanmoins déjà utiliser les principes du code avec les modules de première classe (et oui les modules aussi sont des citoyens de premières classe : c'est du lambda-calcul après tout ;-) mais avec paramètre explicite. Ils sont abordés au chapitre First-Class Modules (en) du livre Real World OCaml, et sont illustrés pour coder un query-handling framework.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Jai: Language for game programmming

    Posté par  . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 5. Dernière modification le 14 octobre 2016 à 11:23.

    Pour les cas que tu décris en Haskell, c'est ce qui manque à l'heure actuelle en OCaml : le polymorphisme ad hoc (en), qu'il faut distinguer du polymorphisme paramétrique (en). Le second est le polymorphisme que l'on trouve en OCaml : une fonction peut prendre en entrée un type quelconque sans que cela change son code dans sa forme (l'algorithme est identique) comme c'est le cas avec des fonctions sur les 'a list ou 'a array, par exemple.

    Le polymorphisme ad hoc, lui, est ce qui permet entre autre de faire de la surcharge d'opérateur : une multiplicité de code partage le même alias, et le code adapté sera choisi en fonction du type des entrées. C'est par exemple pour cela qu'en Haskell il y a un seul opérateur d'addition + alors qu'en OCaml il y en un pour chaque type de données : + pour les int et +. pour les float. Ce sont les type classes qui permettent cela en Haskell, dispositif qui ne possède pas encore d'équivalent en OCaml mais il y a des personnes qui y travaillent.

    Leo White, Frédéric Bour et Jeremy Yallop ont proposé les modular implicts qui s'insprirent entre autre des type classes de Haskell et des implicits de Scala. Dans leur article, ils comparent leur approche avec celles faites dans d'autres langages, comme les concepts pour le C++, section qui renvoie à un article collaboratif dont un des auteurs est Bjarne Stroustrup : Concepts: linguistic support for generic programming in C++. Comme je ne suis pas abonné à l'ACM, je n'ai pas pu lire l'article, et je me demande si ce sont bien les concept que les développeurs C++ attendent et dont parle la dépêche.

    L'idée de base pour ajouter cette possibilité dans le langage OCaml est de passer par le système des modules du langage et des fonctions sur les modules ou foncteurs. Une approches lourde et qui crée beaucoup d'indirection à base de pointeurs, dans l'exemple de l'addition, est de passer par un type somme :

    type num = I of int | F of float
    
    let add i j = match i, j with
      |I i, I j -> I (i + j)
      |I i, F j -> F (float_of_int i +. j)
      |F i, I j -> F (i +. float_of_int j)
      |F i, F j -> F (i +. j)
    
    add (I 1) (F 2.3);;
    - : num = F 3.3

    C'est extrêmement lourd dans l'écriture à l'usage. Leur idée est donc de passer par le système de modules et les modules de première classe. On commence par définir une signature pour les objets numériques :

    module type Num = sig
      type t
      val add: t -> t -> t
      val mul: t -> t -> t
    end

    Puis, on définit deux fonctions1add et mul qui prennent, en plus de leurs deux paramètres habituels, un module qui choisira l'implémentation adaptée.

    let add (type a) (module M:Num with type t = a) (i:a) (j:a) = M.add i j;;
    val add : (module Num with type t = 'a) -> 'a -> 'a -> 'a = <fun>
    
    let mul (type a) (module M:Num with type t = a) (i:a) (j:a) = M.mul i j;;
    val mul : (module Num with type t = 'a) -> 'a -> 'a -> 'a = <fun>

    Il reste à implémenter deux modules de la bonne signature pour nos deux types de base int et float.

    module Int_num : (Num with type t = int) = struct
      type t = int
      let add = (+)
      let mul = ( * )
    end;;
    module Int_num :
      sig type t = int val add : t -> t -> t val mul : t -> t -> t end
    
    module Float_num : (Num with type t = float) = struct
      type t = float
      let add = (+.)
      let mul = ( *. )
    end;;
    module Float_num :
      sig type t = int val add : t -> t -> t val mul : t -> t -> t end

    Pour l'usage cela se passe ainsi :

    add (module Int_num) 1 2;;
    - : int = 3
    
    add (module Float_num) 1.3 2.5;;
    - : float = 3.8

    Leur proposition consiste à ajouter quelques modifications légères au langage de base de telle façon que le module en argument soit implicite et inféré automatiquement par le compilateur en fonction du type des autres paramètres. Ce qui permettrait d'avoir la syntaxe (qui n'est pas acceptée à l'heure actuelle) suivante :

    (* ajout du mot clé `implicit` en tête de la définition du module *)
    implicit module Int_num : Num = struct
      type t = int
      let add = (+)
      let mul = ( * )
    end
    
    implicit module Float_num : Num = struct
      type t = float
      let add = (+.)
      let mul = ( *. )
    end
    
    (* le paramètre implicite est mis entre accolades {}
     * et non entre parenthèse () *)
    let add {M : Num} (i : M.t) (j : M.t) = M.add i j
    
    add 1 2;;
    - : int = 3
    
    add 1.3 2.5;;
    - : float = 3.8

    Le compilateur se chargeant de regarder, dans le dictionnaire des modules implicites ayant la bonne signature, de trouver celui dont le type t correspond à celui des paramètres donnés à la fonction.


    1. en réalité ce n'est pas tout à fait ce choix qui est fait pour l'implémententation des fonctions add et mul, mais c'est pour simplifier, et ils justifient leur approche à la section 2.4 qui permet d'atteindre un plus haut niveau de polymorphisme. 

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Jai: Language for game programmming

    Posté par  . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.

    Exemple de conversion de type qui doit être explicite sous peine de voir le type checker te foutre une baffe — pour reprendre l'expression de barmic.

    (* l'opérateur infixe +. exige deux paramètres de types float *)
    (+.);;
    - : float -> float -> float = <fun>
    
    (* si on lui donne un int, il proteste ! *)
    1 +. 2.3;;
    Error: This expression has type int but an expression was expected of type float
    
    (* il faut faire une conversion explicite *)
    float_of_int 1 +. 2.3;;
    - : float = 3.3

    Ce qui ne semble pas être le cas du C++, si j'en crois ce commentaire de Guillaum (développeur C++ expérimenté) :

    Aller, j'en ajoute (C++ est mon outil de travail 8h par jour depuis plus de 10 ans) en me focalisant sur les problèmes qui m’embêtent vraiment au quotidien et pour lesquels il n'y a pas de solution simple. J'essaye de rester objectif ;)

    • Les casts implicites. Plus particulièrement le fait que les flottants, les ints, les bools, les enums, et j'en passe, c'est la même chose. Le downcast implicite d'une classe vers une autre. Je sais que c'est la philosophie du langage. Combien de fois je me suis fais manger par un int négatif convertit en unsigned…

    […]

    C'est moi qui graisse. :-)

    Et je le comprends : faire de la conversion de type sans l'accord explicite du développeur, ça ne devrait pas être permis ! C'est quoi ces compilateurs qui prennent des décisions qui affectent la sémantique du code dans le dos du programmeur ?

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Jai: Language for game programmming

    Posté par  . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.

    Selon le site C++ référence, les lambda seraient apparues avec le C++11 et ne correspondent qu'à de vulgaires fonctions anonymes construisant une clôture : ils ne savent pas ce qu'est le lambda-calcul les concepteurs et développeurs C++ ?

    Il n’est pas marqué ça sur le site. Il est marqué que les lambdas sont apparues dans le langage C++ depuis la version C++11. C’est pour ça que je dis que tu es de mauvaise foi, ou que tu ne sais pas lire.

    Euh, c'est exactement ce que j'ai écrit ! :-O Enfin, j'ai sous entendu que l'apparition était dans le langage C++; je ne voulais pas entendre par là qu'ils prétendait que C++11 avait inventé les lambda. Je le reconnais, cela pouvait prêter à confusion (enfin, si l'on ne fait pas beaucoup d'effort). ;)

    Qu'il y ait de la mauvaise foi dans mes propos précédents, c'est évident, je ne l'ai jamais nié, j'ai même annoncé la couleur. Par contre, je ne sais pas lequel de nous deux à des problèmes de compréhension sur ce qu'il lit.

    Mais plus généralement, tu juges de la compétences des concepteurs d’un langage (ne me dis pas que tu poses seulement une question, la tournure est loin d’être innocente et tu le sais très bien) que tu ne connais pas sur une mauvaise lecture que tu fais (probablement volontairement) de documentations sur un site web qui n’est pas en lien avec le comité en charge de l’évolution du langage. Il y a des limites à ce qui acceptable comme troll :).

    C'était clairement de la mauvaise foi en ce qui concerne les concepteurs du langage, je sais très bien qu'ils sont loin d'ignorer ce qu'est le lambda-calcul. Pour ce qui est des développeurs C++, cela dépend : DerekSagan ou toi ne semblent pas y connaître grand chose. ;-)

    C’est un partage de responsabilité de la durée de vie. Ton idée de liste chaînée ou de tableaux persistants est (de ce que j’en ai compris) un peu à côté de la plaque de ce point de vue.

    Alors tu n'as pas compris mon code, mais c'est peut être mon explication qui est défectueuse. En OCaml, en dehors des valeurs de type int et des constructeurs constants comme Nil on ne manipule que des pointeurs qui se comportent comme des smart pointer. Tous mes tableaux se partagent la responsabilité de la durée de vie du 'a array qui sert de mémoire partagée. Quand on a des types somme comme Cons of ... ce sont des smart pointer nommés en lecture seule, avec les ref ce sont des smart pointer en lecture-écriture. Les types somme cela sert à poser des étiquettes sur les branches du graphe des pointeurs, et ça s'implémente en C aussi : le runtime et le GC de OCaml sont codés en C.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Jai: Language for game programmming

    Posté par  . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.

    Pour la version longue : voir ce commentaire que j'avais fait l'an dernier sur les principes de base du lambda-calcul typé. J'y comparais le typage de OCaml (qui est décidable, sauf sur quelques corner cases, d'où l'inférence de types) et celui de Coq qui lui ne l'est pas et donc le programmeur doit le dériver lui même explicitement, ce qui s'appelle faire une démonstration au sens mathématique du terme.

    Pour la version courte : disons que le language des types c'est, grosso modo, celui de la logique propositionnelle du second ordre. C'est à dire que l'on a des variables propositionnelles : A, B, C..., l'implication logique A -> B (si A alors B), la conjonction A et B et la disjonction exclusive A ou B. L'implication : c'est le type des fonctions de A dans B; la conjonction : c'est les types produits, l'équivalent des struct du C; la disjonction : c'est les types sommes, les union du C mais en mieux.

    On appelle ces deux genres de types, types sommes et types produits à cause de cette relation : A et (B ou C) <-> (A et B) ou (A et C). Ce qui donne une des définitions du concept d'algèbre de Boole au sens où l'entendent les mathématiciens : c'est un corps dans lequel tout élément est sont propre carré ((A et A) <-> A). L'algèbre a deux éléments {vrai, faux} étant la plus simple et la plus triviale de telles algèbres.

    Par exemple, le type des listes : type 'a liste = Nil | Cons of 'a liste exprime une disjonction : c'est soit la constante propositionnelle Nil, soit une variable propositionnelle indexée par le type lui-même (ce qui fait que le type exprime une disjonction infinie, disjonction qui pour un type 'a donné est isomorphe à l'ensemble des entiers naturels 0 ou 1 ou 2 ou 3...). Pour les types produits, on peut prendre par exemple les points du plan : type point = {x:float; y:float}; c'est la donnée d'un int et d'un int, d'où la conjonction.

    Ce qui fait qu'à l'arrivée, on tombe bien sur la logique des stoïciens.

    Le principe d'application des fonctions, par exemple, c'est la régle de déduction logique dite du modus ponens : Si A alors B, or A, donc B. Règle que l'on écrit en logique propositionnelle : (A -> B) -> A -> B. À comparer avec le type inféré de la fonction suivante :

    let apply f x = f x;;
    val apply : ('a -> 'b) -> 'a -> 'b = <fun>

    L'inférence de type relève de la preuve automatique, Coq c'est de la preuve assistée par ordinateur, et les principes du typage du lambda-calcul proviennent tous de la théorie de la démonstration. Et donc coder en fonctionnel, c'est faire une preuve : le principe même de la correspondance de Curry1-Howard, ou correspondance preuve-programme. Le compilateur gueule, au niveau du typage, quand il considère qu'il y a un vice de forme dans la preuve.


    1. le même Curry qui a donné son nom à la curryfication, et qui s'appelait Haskell Brooks Curry. ;-) 

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.

  • [^] # Re: Jai: Language for game programmming

    Posté par  . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 4.

    J'en déduis donc que selon toi un langage fonctionnel digne de ce nom doit être faiblement typé

    Gné ??? Haskell ou OCaml sont fortement et statiquement typé. Voici la page des publications de Jacques Garrigue qui est le responsable principal du système de types du langage OCaml.

    Par contre, je n'ai toujours pas vu comment tu illustrais le principe de la curryfication en C++ ni celui des fonctions comme citoyen de première classe. Au passage, Curry qui a donné le nom à ce principe était un mathématicien et logicien qui se prénommait… Haskell. ;-)

    Bravo. Tu es donc quelqu'un de bien. Je suppose que c'était le message.

    Que nenni ! Je pointais juste du doigt qu'un utilisateur de C++ (ce que je ne suis pas) posait une question sur l'utilité des shared_ptr et qu'aucun spécialiste de ce langage n'avait dénié lui répondre. C'est un peu dans le même ordre que ce commentaire de Benoît Sibaud :

    Déjà six commentaires pour dire à quel point c'est un mauvais choix. Et pas un capable d'expliquer et/ou de proposer une solution ou d'être constructif ou donner des références. Pauvre communauté.

    Pour ce passage, je ne comprends pas trop :

    Et du coup grâce à ta constructivité(1) sur certains sujets tu a acheté le droit de faire preuve de mauvaise foi en écrivant, ceci, comme si cette définition du lambda était propre à C++, y compris OCaml (le seul langage digne de ce nom):

    Selon le site C++ référence, les lambda seraient apparues avec le C++11 et ne correspondent qu'à de vulgaires fonctions anonymes construisant une clôture : ils ne savent pas ce qu'est le lambda-calcul les concepteurs et développeurs C++ ?

    Pour ensuite répondre:

    En fait dans les langages de programmation de ces dernières décennies le mot "lambda" correspond à une fonction anonyme, c'est loin d'être une spécificité de C++.
    C'est gentil de me l'apprendre… mais je le savais déjà, hein. ;-)

    Premièrement, je n'ai jamais, mais alors jamais, affirmé que OCaml était le seul langage digne de ce nom. Je dis juste qu'un langage qui ne fournit pas nativementt les concepts et principes de la programmation fonctionelle (dont l'archétype est le lambda-calcul) ne mérite pas d'être qualifié de langage fonctionnel. J'allais dire que j'avais passé l'âge de jouer à qui a la plus grosse en comparant les langages, mais à dire vrai je ne l'ai jamais eu : c'est ridicule, je n'en ai jamais vu l'intérêt.

    Deuxièmement, oui il y a avait du troll et de la mauvaise foi dans mon message initial : mais c'était clairement affiché. ;-) Cela étant sur le site C++ référence à Lambda, on peut bien lire :

    Lambda functions (since C++11)
    Constructs a closure: an unnamed function object capable of capturing variables in scope.

    Le concept est donc bien apparu avec le C++11 et représente des fonctions anonymes qui capturent des variables d'environnement en construisant une fermeture. Comme cette notion de fermeture est apparue avec le langage scheme en 1975, et que tu raillais Java qui avait mis plus de temps à les implémenter, je me suis permis de railler également le C++. Sur la page wikipédia sur les fermetures, tu pourras en particulier y lire :

    En Haskell, grâce à la curryfication, toute fonction peut générer des fermetures lorsqu'on lui passe seulement une partie de ses arguments
    [..]
    En OCaml […] grâce à la curryfication, toute fonction peut générer une fermeture lorsqu'on lui passe seulement une partie de ses arguments.

    c'est ce que j'ai fait avec mon exemple de plus, en faisant une application partielle :

    let plus i j = i + j
    
    let plus_2 = plus 2

    Ici, on génère une fermeture en capturant 2 dans l'environnement d'évaluation de plus_2. Mais on peut aussi le faire anonymement :

    fun i -> plus 2 i

    Cela étant, je n'ai toujours pas d'exemples de curryfication et de leur usage pour générer des fermetures en C++.

    Au passage, cette notion est empruntée à la logique formelle et au calcul des prédicats : c'est la notion de variable libre et de variable liée (et date donc de la fin du XIXème siècle). Dans un énoncé comme celui-ci : Pour tout entier n, n + i = n, la variable n est liée par le quantificateur universel (on peut changer son alias par j sans changer le sens de l'énoncé) tandis que la variable i est libre (elle représente un entier indeterminé). Pour pouvoir interpréter un tel énoncé, qui est en fait paramétré par un entier indéterminé i, il faut l'évaluer dans un environnement qui attribue une valeur à cette entier i : voilà d'où vient ce concept de fermeture. En l'occurrence pour cet énoncé, il ne sera vrai que pour la valeur i = 0 si on l'interprète dans son environnement naturel qui est celui de l'ensemble des entiers naturels. C'est là la base de la théorie des modèles qui n'est pas sans intérêt pour l'étude de la sémantique des langages de programmation.

    accompagné de deux liens où tu réinventes l'eau chaude en découvrant manifestement ce qu'est un smart pointer, je dis ça pour donner de la profondeur à l'adjectif "pertinentes".

    Je vois que tu es prompte à répondre, mais que tu n'as rien compris au code que j'ai écrit. Il ne s'agissait pas de réinventer l'eau chaude ou de découvrir ce qu'était un smart pointer mais :

    • de montrer quel était l'équivalent de cette notion dans le langage OCaml;
    • et d'en faire usage pour implémenter des tableaux persistants.

    C'est la partie graissée qui est l'objectif principal du code : donner un exemple d'utilisation possible de ce concept sous la forme des shared_ptr (qui peut aussi existait sous la forme des unique_ptr), car telle était la question de freem. Le premier point était simplement là pour que le lecteur non familier avec les concepts de OCaml, mais familier avec ceux du C++, puisse comprendre le fonctionnement du code et traduise en C++.

    Pour reprendre ma question trollesque du premier message :

    ils ne savent pas ce qu'est le lambda-calcul les concepteurs et développeurs C++ ?

    Dis : tu t'y connais un peu en programmation fonctionnelle et en théorie des langages ou tu veux juste troller ?

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.