Guillaum a écrit 472 commentaires

  • # Nix pour ta gestion de dependence

    Posté par  (site web personnel) . En réponse au journal Bim! On parle de dev de jeu mobile, de gestion de projet, de dépendances, etc.. Évalué à 2 (+0/-0).

    Regarde nix pour la gestion de dependence.

    Tu pourra faire une recette custom pour ton build android, linux, windows peux-être et la cross compilation et créer ton environment de build.

  • [^] # Re: Guix ?

    Posté par  (site web personnel) . En réponse à la dépêche L'installation et la distribution de paquets Python (2/4). Évalué à 2.

    Il faudrait que je regarde - plus en détail dans pip, mais ce genre de chose est assez facile à faire avec nix. L'idée c'est que tu va plutôt changer la "source" de ta dependence pour pointer vers un répertoire à toi et ainsi les changement dans ce répertoire seront pris en compte.

    Le repertoire en question peut être quelque chose que tu as toi même git clone, mais nix peut aussi te décompresser les sources dans un repertoire de ton choix à la demande.

  • [^] # Re: Guix ?

    Posté par  (site web personnel) . En réponse à la dépêche L'installation et la distribution de paquets Python (2/4). Évalué à 4.

    Concernant nix (Je ne connais pas guix). Il y a pleins de module dans nixpkgs qui sont destiné au travail avec des packages python. Tous les packages de PyPI sont importable. La résolution de dépendance depuis PyPI peut se faire avec des outils tierces mais intégrés dans nix et tout cela se greffe sur different outils que tu as décrit pour faire le boulot.

    Ici nix ne remplace pas forcement, mais permet d'unifier, regrouper ensemble et proposer une solution robuste.

    Nix est fait pour gérer des env virtuels. Je ne sais pas ce que tu veux dire par "installer un packet en mode éditable".

    Nix ne fonctionne pas non plus sous windows (enfin si, dans le WSL). Si c'est un problème pour toi, alors en effet, sinon cela marche très bien.

    J'ai maintenu une base de code contenant 100+ packages python, des milliers de fichiers, dont certains auto-generés à la volée dans le processus de build. Il y avait aussi du C++ et du Haskell, et du bash et du C et du go. Le tout cross compilé (i.e. certains utilitaires python dépendant de module python natif "maison" déployé sur du ARM et buildé sur du x86_64 sur un os different). On avait des dev sous linux, macos et windows (WSL). environ 100+ libs dont on dépendait depuis PyPI, et une bonne quarantaine venant d'autres depot git arbitraire.

    Et pour le coup, on avait des contraintes amusante de traçabilité / reproductibilité (aéronautique) et nix est très bon pour cela (c'est même le seul outil qui me garantie que mon interpréteur et ses dépendances ne changent pas du jour au lendemain sans me prévenir).

    Bref, nix (et guix qui est très proche) est fait pour résoudre ce type de problème et le fait très bien (de mon point de vu).

    Le coût d'entrée est cependant considéré comme élevé. Je n'arrive pas à juger. Je n'ai jamais vraiment trouvé.

    De manière plus général, si tu as un besoin simple (i.e. avoir un environment virtuel reproductible pour bosser sur du python + packager + déployer une application, en utilisant des packages python "standards"), nix(pkgs) te propose une solution en 5 lignes. Si ton besoin est plus complexe, et bien c'est plus complexe, mais c'est à ma connaissance le seul outil qui fait cela. Si tu as un besoin intermédiaire (ou d'autres contraintes, comme bosser sous windows), et bien nix n'est pas forcement la bonne solution.

  • # Faut voir la définition du vol

    Posté par  (site web personnel) . En réponse au journal Il y en a, par ici, des gens qui volent ?. Évalué à 3.

    Moi j'ai trop peur de l'avion, alors j'ouvre la porte et je saute.

    Après, c'est 3000m de chute/vol (avec ou sans wingsuit), et 1000m sous voile (un peu comme un parapente, mais tout de même moins performant, on peut pas tout avoir, mon véhicule doit se plier dans un petit sac de quelques litres et se déplier à 200km/h).

  • [^] # Re: Pleins de libs open source crée par l'industrie du cinéma.

    Posté par  (site web personnel) . En réponse au journal Libération du moteur de rendu MoonRay par DreamWorks.. Évalué à 3.

    Merci mais j'ai quitté l'industrie il y a trop longtemps.

    Et vu le temps que je met pour finaliser des dépêches sur des trucs sur lesquels je suis à jour, j'imagine surtout que ma dépêche va tomber dans l'oubli.

  • # Pleins de libs open source crée par l'industrie du cinéma.

    Posté par  (site web personnel) . En réponse au journal Libération du moteur de rendu MoonRay par DreamWorks.. Évalué à 8. Dernière modification le 21 mars 2023 à 13:49.

    Les industriels du computer graphics ont un historique de publications de librairie en "open source" (différentes licences) assez important, souvent dans le but de généraliser un format d'échange.

    De tête et pas dans l'ordre:

    • OpenVDB (Pour les voxels)
    • Collada (Pour les animations)
    • USD (Description de scene)
    • OpenShadingLanguage (Pour les matières)
    • OpenEXR (pour les images)
    • OpenFX (pour le post processing)
    • Ptex (Pour les textures)
    • Partio (Particules)
    • Alembic (Description d'objets)

    (shameless plug: c'est bibi le maintainers de 80% de ces packages sur nixpkgs ;)

    Libérer un moteur de rendu c'est un peu plus rare.

    Concernant le troll langage de programmation, quand je bossais dans cette industrie, on parlait de C++ comme d'un langage "glue" : Le langage le plus pratique pour s'interfacer avec les tonnes de librairies existante. Parce qu'un final, un "cœur" de moteur de rendu, c'est assez simple (à prendre avec des pincettes, mais si tu sais ce que tu fais, en prenant les lib citée au dessus, tu peux sortir des images en quelques heures et écrire un produit adapté à la production de série TV en quelques semaines.).

    Je ne sais pas quelle type de communauté cela va attirer, mais plus de code libre c'est toujours bien.

  • [^] # Re: Fil de fer ?

    Posté par  (site web personnel) . En réponse à la dépêche Le rendu 3D, rétrospective. Évalué à 3.

    Mesa support très bien le rendu "software".

  • [^] # Re: Songe

    Posté par  (site web personnel) . En réponse au journal NixOS ou comment j'ai rendu mes machines interchangeables et ennuyeuses. Évalué à 3.

    Bof, cela dépend.

    Maintenant t'as https://nixos.wiki/wiki/Packaging/Binaries#Using_AutoPatchelfHook et associés. En gros pour faire un package nix sur un truc proprio, tu dois:

    • Fetch le binaire
    • Ajouter les dependences
    • utiliser les auto patchs pour patcher les library path et autre shebang
    • recommencer à ajouter des dependences tant qu'il y a des warnings.

    C'est sensiblement le même processus qu'un package debian. Je ne dis pas, des fois c'est vraiment l'horreur, mais c'est pas pire que pour un autre système. La seule difference c'est que des fois les trucs proprio sont déjà packagés pour les distributions classiques.

  • # En haskell

    Posté par  (site web personnel) . En réponse au journal Petite énigme pseudo-mathématique pour commencer l’année et en guise de vœux. Évalué à 9.

    Dans le context pervers ou tu as chargé ce module haskell:

    import System.Random
    import System.IO.Unsafe
    
    import Prelude (Int, Bool(..), error)
    import qualified Prelude
    
    {-# NOINLINE sometimeYes #-}
    sometimeYes = unsafePerformIO (randomRIO (False, True))
    
    (==) :: Int -> Int -> Bool
    0 == 6 = True
    0 == 9 = sometimeYes
    1 == 2 = True
    2 == 3 = True
    2 == 5 = True
    2 == 9 = sometimeYes
    4 == 4 = True
    7 == 3 = True
    7 == 4 = sometimeYes
    8 == 7 = case unsafePerformIO (randomRIO (0::Int,2)) of
               0 -> True
               1 -> False
               2 -> error "WTF the ? means"
    a == b = a Prelude.== b
  • [^] # Re: Sûreté

    Posté par  (site web personnel) . En réponse à la dépêche GHC 9.2. Évalué à 10.

    Merci pour cette question, en effet cela demande des précisions.

    En premier lieu, "mon" format n'est pas plus sûr que le format de python, c'est le même format. Plus exactement, un sous ensemble.

    La réponse de barmic est un cas extrême d'exploitation du coté dynamique de python. Mais j'avoue que je ne pensais même pas à cela en rédigeant ce paragraphe.

    Je parlais de "sûreté" au sens "typage".

    En pratique, le formatage de chaîne python est réalisé dynamiquement : lors de l’exécution, l’interpréteur python va construire la chaîne de formatage, interpréter celle-ci et y insérer les différents expressions / valeurs nécessaire. À ce moment, il peut échouer (et lever une exception) si le formatage demandé n'a pas de sens.

    Par exemple, si le type à formater n'est pas compatible avec le formater, ici une chaîne à formater en octal :

    >>> name = "Guillaume"
    >>> f"Bonjour {name:o}"
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: Unknown format code 'o' for object of type 'str'

    Ou si la syntaxe du formater est incorrecte ou incohérente :

    >>> f"Bonjour {name:l}"
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: Unknown format code 'l' for object of type 'str'
    
    >>> f"Bonjour {3:0.3d}"
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: Precision not allowed in integer format specifier

    Cette erreur arrive lors de l’exécution.

    De son coté, PyF fait ses vérifications lors de la phase de vérification des types, avant l’exécution.

    Prelude PyF> name = "Guillaume"
    Prelude PyF> [fmt|Bonjour {name:o}|]
    
    <interactive>:5:6: error:
         No instance for (Integral [Char])
            arising from a use of PyF.Internal.QQ.formatAnyIntegral
         In the second argument of (<>), namely
            ((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal)
                  PyF.Formatters.Minus)
                 Nothing)
                Nothing)
               name
          In the expression:
            (("Bonjour "
                <>
                  ((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal)
                       PyF.Formatters.Minus)
                      Nothing)
                     Nothing)
                    name))
          In an equation for it:
              it
                = (("Bonjour "
                      <>
                        ((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal)
                             PyF.Formatters.Minus)
                            Nothing)
                           Nothing)
                          name))
    Prelude PyF> [fmt|Bonjour {name:l}|]
    
    <interactive>:7:6: error:
         <interactive>:1:15:
      |
    1 | Bonjour {name:l}
      |               ^
    unexpected 'l'
    expecting '#', '%', '+', '-', '.', '0', 'E', 'F', 'G', 'X', 'b', 'c', 'd', 'e', 'f', 'g', 'n', 'o', 's', 'x', '}', integer, or space
    
         In the quasi-quotation: [fmt|Bonjour {name:l}|]
    Prelude PyF> [fmt|Bonjour {3:0.3d}|]
    
    <interactive>:6:6: error:
         <interactive>:1:15:
      |
    1 | Bonjour {3:0.3d}
      |               ^
    Type incompatible with precision (.3), use any of {'e', 'E', 'f', 'F', 'g', 'G', 'n', 's', '%'} or remove the precision field.
    
         In the quasi-quotation: [fmt|Bonjour {3:0.3d}|]

    Ici j'ai exécuté les exemples dans l’interpréteur Haskell, mais je vous demande de me croire que l'erreur est bien une erreur "statique" détectée pendant la compilation et non lors de l’exécution.

    De plus, les erreurs de PyF apportent plus de contexte (notez le petit marqueur ^ qui montre précisément la localisation du problème.) Ce ne fut pas une tache aisée, et c'est loin d'être parfait, mais cela permet tout de même de voir l'erreur pendant la phase de développement et non lors de l’exécution.

    D'ailleurs, pour rentrer dans les détails, PyF peut échouer dans 2 contextes différents.

    • Lors du parsing du la chaîne de formatage ou l'analyse de celle-ci. A ce moment ne sont testé que la cohérence de la chaîne de formatage, et une erreur très précise peut être générée par la libraire.
    • Passé cette étape, la libraire PyF génère du code Haskell et le compilateur va tester la cohérence des expressions. Ici PyF n'a plus aucun contrôle et les erreurs remontées par le compilateur peuvent être un peu complexe à lire, comme ici le No instance for (Integral [Char]) qui veut simplement dire qu'une chaîne de caractère n'est pas convertible en nombre entier. Il y aurait moyen d'améliorer cela un petit peu, il faut que j'y passe un peu de temps, mais il est possible en Haskell de contrôler les message d'erreur des erreurs de type.

    Bref, au final, PyF apporte, comparé à Python, une partie de vérification "statique" lors de la compilation. C'est à mon avis appréciable, après tout, c'est ce que j’apprécie en Haskell, mais ce n'est pas l'apport le plus intéressant qui reste la partie formatage, et là, PyF n'apporte rien de mieux que ce que python propose en standard.

  • [^] # Re: Sûreté

    Posté par  (site web personnel) . En réponse à la dépêche GHC 9.2. Évalué à 4.

    Merci, je redécouvre ce comportement.

    Même si PyF ne peut pas "injecter" du comportement ou lire une variable non prévue, PyF n'est pas protégé d'un formatage dangereux. Par exemple, en spécifiant une "précision" très grande pour un nombre, on va se retrouver avec une grosse occupation mémoire (e.g. la chaîne générée sera longue), ce qui peut sans doute être exploité pour tuer un service.

    Bref, même en Haskell, il ne faut pas faire confiance aux valeurs qui viennent de l'exterieur.

  • [^] # Re: Histoire

    Posté par  (site web personnel) . En réponse à la dépêche GHC 9.2. Évalué à 2.

    ;)

    L'histoire de tout est complexe, mais en effet, certains points en Haskell ont encore une histoire complexe (par exemple, le formatting ou les records). Mais j'espere que leur histoire complexe deviennent une histoire simple dans le futur (grace à PyY et GHC 9.2)

  • [^] # Re: Coquilles

    Posté par  (site web personnel) . En réponse à la dépêche GHC 9.2. Évalué à 2.

    Merci pour les corrections.

    Il reste toujours les problèmes avec f x et f $ x et mathjax, mais cela n’apparaît surement que dans la version finale et pas dans le code markdown d'origine.

    Et pour les guillemets, merci pour les précisions.

  • [^] # Re: Coquilles

    Posté par  (site web personnel) . En réponse à la dépêche GHC 9.2. Évalué à 2.

    Merci !;)

    Et désolé, j'ai un peu torché cette partie de la dépêche sur haskell-language-server. Mais en gros cela apporte tous les trucs considerés comme "de base" dans des éditeurs avancés pour des langages classiques.

    Bref, des année que je jalousais les devs C++ dans visual studio, j'ai maintenant la même chose dans vim avec Haskell:

    • Type sous le curseur
    • Documentation
    • Erreur en live
    • Suggestion de correction
    • Import automatiques
    • Refactoring
    • Évaluation de bloc

    Et le plus intéressant c'est que tu peux faire des plugins maison, et donc ajouter n'importe quoi qui soit intéressant seulement pour ton business.

    Je m'en sers sur tous mes projets persos depuis plus d'un an et j'ai mis en place le support (avec bazel ;() dans mes deux derniers boulots et cela marche très bien, sauf qu'il faut une machine avec beaucoup de RAM sur des projets conséquents.

  • # Coquilles

    Posté par  (site web personnel) . En réponse à la dépêche GHC 9.2. Évalué à 6.

    Est-ce que quelqu'une de la fine équipe de modératisation pourrait corriger les points suivants :

    • Section "Types Liftés":

    utilisé tous les jours par les développeurs Haskell, {mathjax}, qui n’est autre

    Remplacer le {mathjax} par $ et l'exemple qui suit par :

    f x et f $ x sont identiques

    • Dans la section "Haskell et le formatage", de nombreux guillemet anglophone (") ont été remplacés sauvagements par des symboles cabalistiques («) ce qui casse la coloration syntaxique.

    >>> putStrLn (« Bonjour
    -> >>> putStrLn ("Bonjour

    « Bonjour Guillaume. Tu as 35 ans. Et pi = 3.141. »
    -> "Bonjour Guillaume. Tu as 35 ans. Et pi = 3.141."

    Merci beaucoup.

  • [^] # Re: Eléments pour la résolution du premier problème

    Posté par  (site web personnel) . En réponse au journal Deux petits problèmes de math niveau lycée.. Évalué à 2.

    Haaa, merci ;)

  • [^] # Re: Eléments pour la résolution du premier problème

    Posté par  (site web personnel) . En réponse au journal Deux petits problèmes de math niveau lycée.. Évalué à 3.

    Le litre de la première coûte autant de demi-centimes qu’il y a de litres dans la pièce;

    Ainsi je ferais:

    a = (x + y + z) / 2
    
  • [^] # Re: Dilème facile à résoudre.

    Posté par  (site web personnel) . En réponse au journal [HS] Ils étaient trois. Évalué à 2.

    On se fait un petit VR 100 départ montgolfière ? ;)

  • [^] # Re: Dilème facile à résoudre

    Posté par  (site web personnel) . En réponse au journal [HS] Ils étaient trois. Évalué à 2.

    Tout à fait. Tu trouveras surement des paras moyens qui en plus font 400 km tous les week-ends pour aller sauter, plus 5 allers/retours aux USA par an en avion pour aller sauter.

    Ce que je voulais mettre en évidence c'est que la consommation liée au sport est assez faible vis à vis des consommations tout à fait acceptées que on peut trouver partout ailleurs.

    Alors oui, les pratiquants d'aéro polluent. C'est un fait. Mais il ne pollue pas tant que ça ou pas beaucoup plus que les non pratiquants d'aéro.

    Bref, ce n'est pas trivial de juger qui pollue le plus.

  • [^] # Re: Dilème facile à résoudre

    Posté par  (site web personnel) . En réponse au journal [HS] Ils étaient trois. Évalué à 8.

    Et à ~3.5L de kero la rotation, un para moyen qui fait 40 sauts dans l'année, c'est l'équivalent de deux plein d'essence. Mon amie qui fait de la photo d'oiseau (donc loisir 100% vert) consomme plus d'essence pour ses trajets qu'un para moyen. Donc on repassera pour le "très polluant".

    Après, un para à 300 saut / an dont 10 dans des manip internationales qui nécessitent de prendre le transaltlantique, oui, c'est certain, il consomme plus. Mais autant qu'un marathonien qui aime faire le tour du monde.

  • [^] # Re: Une histoire délicate...

    Posté par  (site web personnel) . En réponse au journal [HS] Ils étaient trois. Évalué à 6.

    (pour les néophytes, la 25 et la 7 sont la même piste, seul le sens de décollage change en fonction du vent).

    Ça sent le modulo 18 ;)

  • # Nix, partiellement

    Posté par  (site web personnel) . En réponse au journal Lancer un logiciel distant depuis sa machine. Évalué à 2.

    Si tu ne veux pas "installer" le cli, mais que cela peut tourner en local, tu peux utiliser nix:

    $ nix run nixpkgs.ffmpeg -c ffmpeg --help
    ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
    [...]
    

    Cela n'impacte pas ton système (enfin si, un peu de place disque, les programmes étant gardés en cache), et ffmpeg ne sera plus disponible à la fin de la commande.

    À partir de ce moment tu dois pouvoir le combiner avec outrun, même si je n'ai aucune idée de comment celui-ci fonctionne et que j'ai peur des cas particuliers.

  • [^] # Re: ImportQualifiedPost

    Posté par  (site web personnel) . En réponse à la dépêche GHC 8.8, 8.10 et 9.0. Évalué à 3.

    Et pour éviter les conflits, on peut "qualifier" les import encore un peu plus

    import "text" Data.Text as TextFromText
    import "mypackage" Data.Text as TextFromMyPackage
  • [^] # Re: ImportQualifiedPost

    Posté par  (site web personnel) . En réponse à la dépêche GHC 8.8, 8.10 et 9.0. Évalué à 3.

    Le système de module de Haskell est mal fichu. Si le module Data.Text contient les symboles pack et split, alors :

    • import Data.Text va importer pack et split non qualifiés et qualifié avec Data.Text. Ainsi, on pourra utiliser pack ou Data.Text.pack.
    • import qualified Data.Text va seulement importer les deux fonctions de façon qualifiés.
    • import Data.Text as Foo va importer pack et split non qualifiés et qualifiés tel que Foo.pack.
    • import qualified Data.Text as Foo va importer pack et split qualifié tel que Foo.pack.

    Il existe encore quelques variantes. Mais la constante c'est que c'est non qualifié par défaut, ce qui est affreux. D'autant plus que le namespace des modules est global. Ainsi, tu peux écrire un package qui va exporter Data.Text et entrer en conflit avec le Data.Text du package text.

  • [^] # Re: Superbe article, bravo

    Posté par  (site web personnel) . En réponse à la dépêche GHC 8.8, 8.10 et 9.0. Évalué à 3.

    Merci pour ce retour.

    Concernant le packaging, c'est vrai que c'est un peu le foin. Un package Haskell est assez bien décrit avec un fichier .cabal. stack, nix, bazel savent charger les fichiers .cabal. Hackage travaille avec les fichiers .cabal. Bref, la norme si tu veux redistribuer c'est .cabal et cela marche pas trop mal.

    Si tu ne veux pas redistribuer, tu peux construire ton projet avec du hpack (+nix ou stack), du bazel pure, du nix pure, libre à toi en fonction de la complexité de ton projet. Sur les gros projets sur lesquels je travaille, 450 packages Haskell pour plus de 1000 modules, la solution à base de .cabal ne scale pas et nous utilisons bazel, mais on pourrait utiliser des .cabal, c'est juste beaucoup trop verbeux pour nos besoins. hpack pourrait être une solution aussi. Mais bien souvent, un package se résume à:

    haskell_library(
       name = "mypackage",
       srcs = glob(["**/*.hs"]),
       deps = ["@hackage//:base", ...]
    )

    Nix apporte une chose qu'aucun des autres système n'apporte, c'est le coté parfaitement reproductible. Mais je ne connais pas de langage qui ai un système de package qui apporte aussi cette garantie, donc en fait je me sert de Nix avec tout langages, pas juste Haskell.

    cabal et stack (les outils) souffrent de ne pas être reproductible parfaitement, mais si ce n'est pas une garantie que tu recherches, les deux font le travail aussi bien que n'importe quel autre outil pour d'autres langages. stack vient avec les snapshot de stackage qui apportent un coté pratique pour avoir un peu plus de reproductibilité.