G.bleu a écrit 167 commentaires

  • [^] # Re: Go ou Rust?

    Posté par (page perso) . En réponse au journal Moi, expert C++, j'abandonne le C++. Évalué à 10.

    Parce qu'utiliser un langage peu performant qui consomme des cycles CPU (donc de l'energie) pour rien, c'est pas très écolo.

    À mon avis c'est surtout consommer des cycles CPU pour des applications qui servent à pas grand chose qui n'est pas très écolo ;-)

  • [^] # Re: Go ou Rust?

    Posté par (page perso) . En réponse au journal Moi, expert C++, j'abandonne le C++. Évalué à 5.

    Sauf bibliothèque qui ferait exactement ce que tu veux en Python pour ton domaine précis, je ne vois aucun avantage compétitif à ce dernier en général.

    Par rapport à du Go, Python propose une REPL (un shell interactif quoi) qui amène beaucoup de convivialité:
    - Dès que tu as un doute sur une construction tu peux tester, ça rend plus aventureux ;-)
    - Tu peux interagir avec une lib dont tu ne connais pas/mal l'api plutôt que d'avoir uniquement la doc. C'est incroyablement pratique quand on tâtonne pour faire un truc en particulier.
    - Pareil pour le débug dans lequel tu as vraiment une puissance d'introspection énorme qui aide à comprendre ce qui se passe (voir à modifier/monkeypatch tout à la volée pour vérifier que ton intuition est la bonne)
    - Pour une application interagissant avec une base de donnée, tu as quasiment gratuitement un shell avec une couche métier (en exposant les classes de ton ORM) qui te permet de manipuler les données facilement

  • # De quel côté du mur de Trump est-tu ?

    Posté par (page perso) . En réponse au journal Un recrutement racé chez VEOLIA. Évalué à 3.

    J'adore les choix, en factorisant on se retrouve avec:

    Are you Hispanic or Latino ?
    - yes
    - no
    - I don't wish to answer

  • [^] # Re: Désespoir

    Posté par (page perso) . En réponse au journal Capitaine Train, tu n'es plus de notre galaxie. Évalué à 2.

    Probablement un problème de clavier qui se blo

  • # Quid des perfs ?

    Posté par (page perso) . En réponse au journal `smk`, un make sans Makefile. Évalué à 5.

    Merci pour le journal et le projet, ça fait très plaisir de voir une approche audacieuse à un problème ancien ;-)

    Dans mes souvenir un pauvre hello world en C++ se retrouve tout de suite avec des tonnes d'includes en cascade, dont beaucoup ne sont des bibliothèques standards fournies par le compilo (donc ne devant jamais changer en théorie…).
    De plus ce travail est réalisé pour chaque fichier.

    (Le comité C++ est d'ailleurs en train de travailler sur une feature de module pour justement résoudre ces soucis, il avait été annoncé un gain de 20% sur le temps de compile grâce à ça)

    Du coup en te basant sur les appels systèmes pour déterminer les dépendances (et sans faire d'optimisations propre au langage pour rester agnostique) j'aurai tendance à croire à un gros overhead (aussi bien en temps qu'en taille de logs dans tes fichiers .smk.*).

    Tu as des chiffres là dessus ? J'imagine que tu n'as pas pu résister à l'envie de compiler smk avec smk ;-)

  • [^] # Re: Qui devrait-on craindre ?

    Posté par (page perso) . En réponse au journal Téléphone mobile : suis-je paranoïaque ?. Évalué à 6.

    Google ne va pas te défoncer la gueule au tonfa et te garder 24H parce que t'as remplacé ton Android par un Nokia 3310.

    L'état non plus tu sais…

  • # On t'as démasqué

    Posté par (page perso) . En réponse au journal 8 mois avec Javascript (ES6) et vue.js : mon retour d'expérience du développement front en 2018. Évalué à 10.

    Sans déconner : après huit mois d'observation, ma conclusion la plus logique est que 95 % de la communauté Javascript est composée de macaques sous cocaïne.

    On t'a démasqué Sam&Max !

  • [^] # Re: Hum...

    Posté par (page perso) . En réponse au journal Le VAE n'est PAS un truc de fainéant. Évalué à 5.

    https://mobilite-mobiliteit.brussels/sites/default/files/2017_bhg_fietsrapport_fr_lr.pdf#page=37

    Selon ton document:

    Gravité :
    • 8 piétons blessés légers
    • 8 cyclistes blessés légers
    • 6 cyclistes et piétons blessés légèrement

    Donc peu de collisions, et de faible gravité

    Et en bonus:

    C’est l’inattention du piéton qui joue un rôle important, il est généralement trop tard pour que le cycliste surpris évite le piéton surgissant subitement devant lui

  • [^] # Re: go

    Posté par (page perso) . En réponse au journal Réduire la taille des exécutables générés avec PyInstaller. Évalué à 1.

    C'est très intéressant !

    Par contre Ça ne pose pas de soucis avec la license de Qt ?

    Autre question: ne serait-ce pas possible d'utiliser le configurateur de Qt pour désactiver tout ce qui n'est pas utile à un projet donner, puis d'utiliser les .so générés à la place de ceux fournis par défaut par PyQt ?

  • [^] # Re: go

    Posté par (page perso) . En réponse au journal Réduire la taille des exécutables générés avec PyInstaller. Évalué à 2.

    Malheureusement ce n'est pas aussi simple: dans le cas présent la majeure partie des dépendances en trop sont dues à Qt, dans le cas d'un programme en Go on aurait donc eu un binding vers les lib dynamiques intégré dans le binaire.

  • [^] # Re: performances RipGrep

    Posté par (page perso) . En réponse au journal softs dev en Rust empaqueté pour Ubuntu & cie. Évalué à 10. Dernière modification le 12/09/18 à 13:49.

    On sait ;-)

    L'auteur de RipGrep a pondu un excellent article sur quels sont les spécificités d'un programme de type grep ainsi que les optimisations utilisées dans RipGrep qui le rend aussi rapide tout en comparant avec les choix techniques des autres greps (git grep, silver searcher, GNU grep etc.).

    Pour ceux qui ont la flemme de cliquer sur le lien, un petit one liner pour piquer votre curiosité :)

    python -c "import re; re.search('(a*)*c', 'a' * 30)"

  • [^] # Re: Argument fallacieux

    Posté par (page perso) . En réponse au journal quand Oracle fait les affaires de Azul.. Évalué à 4. Dernière modification le 21/08/18 à 13:51.

    LLVM n'a pas eu (et pour l'avoir utilisé, c'est vraiment pas dans l'esprit de LLVM le JIT, j'en ferai un journal à l'occasion)

    Je suis très preneur d'un journal sur LLVM orienté JIT !
    Les p'tits gars de Godotengine (moteur de jeu opensource) sont en train d'évaluer le coût d'un JIT pour leur langage de script custom (https://github.com/godotengine/godot/issues/5049) et LLVM semblait la solution la plus pérenne mais malgré tout assez lourde à maintenir.

    Oui ce post est HS ;-)

  • [^] # Re: Plutôt que du Lua...

    Posté par (page perso) . En réponse à la dépêche Sortie d’OpenMW 0.44. Évalué à 6.

    D'autant plus que ce projet a déjà fait les frais d'un langage "exotique": de ce que j'ai compris il a été commencé en D pour finalement être réécrit en C++ en grande partie pour permettre au plus grand nombre de contribuer (ce qui a bien marché vu qu'après 10ans et le départ de son créateur le projet est toujours vivant et en bonne forme !)

  • [^] # Re: Une défense des autotools

    Posté par (page perso) . En réponse au journal Un petit tour des systèmes de build. Évalué à 0.

    Des heures pour trouver qu’il faut ajouter le nom du fichier à la variable monprogramme_SOURCES dans le fichier Makefile.am ?

    Non, des heures pour se remémorer les commandes et le fonctionnement du truc, pour chercher la doc sur internet et surtout pour comprendre que la version d'autotools de ma Gentoo d'il y a 6mois était incompatible avec celle de mon Ubuntu. Débugger des scripts de plusieurs milliers de lignes c'est tellement facile.

    Rien ne t’oblige à committer les fichiers générés, il est d’ailleurs généralement recommandé de ne pas le faire…

    Tout à fait, comme ça non seulement je ne pouvais plus rajouter de fichiers mais en plus je pouvais plus non plus générer le build ;)

    Sérieusement, tu dis avoir eu à cœur d’apprendre les Autotools, mais ton expérience, soit est une caricature trollesque, soit est typique de celui qui veut utiliser les autotools sans rien comprendre de ce qu’il fait.

    Sérieusement, j'ai publié mon expérience, j'ai pris la peine de mettre un lien vers le projet en question donc me traiter de troll et insinuer que je suis incompétent c'est franchement un gros manque de respect de ta part.

    Les Autotools ne sont pas les outils les plus faciles à utiliser, c’est un fait et c’est une critique tout-à-fait valable.

    Merci, donc au final on arrive à la même conclusion ;-)

  • [^] # Re: Une défense des autotools

    Posté par (page perso) . En réponse au journal Un petit tour des systèmes de build. Évalué à 4.

    Perso mon expérience des autotools ça a été de créer un petit projet avec (https://github.com/touilleMan/mpa_robot).

    Le truc fait grosso modo 1000 lignes de C++, mon projet sur Github est indiqué comme étant composé à 95.5% de shell…
    On a 13 fichiers à la racine du projet dédié aux autotools, plus 2 fichiers pour chaque répertoire (Makefile.in et Makefile.am)

    J'imagine qu'on peut améliorer ça, mais déjà pour en arriver là ça m'avais pris plusieurs heures de travaille (j'avais à cœur d'apprendre à utiliser les autotools).

    Le clou dans le cercueil à été 6 mois plus tard quand j'ai voulu ajouter un nouveau fichier C++ au build. Après plusieurs heures passées pour re-comprendre le bouzin, tenter de réinstaller les outils (oui mais versions incompatibles et rien pour te l'indiquer clairement…), de regénérer les fichiers (comment on met à jour un .am à partir d'un .in ? si ça crash à cause de la version de l'outil, de mon script ou bien de ma commande ? etc.) j'ai fini par abandonner.

    Sérieusement les éditeurs de jeux vidéos devraient mettre Autotools plutôt que SecuRom pour protéger leurs jeux des modifications des hackers.

  • [^] # Re: scons

    Posté par (page perso) . En réponse au journal Un petit tour des systèmes de build. Évalué à 2.

    En effet j'ai découvert scons en contribuant à Godot (http://godotengine.org/) et c'est un système de build assez appréciable (en particulier le script via python qui amène pas mal de puissance et simplifie le débug grace à pdb).

    Au niveau de sa lenteur, c'était vrai il y a quelques années (les articles en parlant date de 2010…) mais ça a été corrigé depuis.
    Perso les soucis que j'ai eu avec été plus dû à la petite communauté (donc plus difficile de trouver des ressources fraîches sur le sujet) et surtout à sa politique de dépendances de compilation.
    Je m'explique: scons considère toujours qu'une cible de compilation (hors alias) est un chemin vers un fichier ou un répertoire. De là cibles de compilations pointant sur un répertoire/fichier parent sont considérées comme des dépendance.
    Ça peut sembler normal (je dois construire tout ce qu'il y a dans un répertoire avant de considérer celui-ci comme généré) mais ça très lourd quand on veut avoir une tache effectuant un traitement sur le répertoire une fois celui-ci généré :(

  • [^] # Re: Rx

    Posté par (page perso) . En réponse au journal La programmation concurrente en mode Goto. Évalué à 2.

    Quelque chose qui n'est visible qu'au runtime est invisible c'est quelque chose qui peut arriver implicitement et ça rend presque impossible une validation par revue du code

    Les exceptions KeyboardInterrupt peuvent arriver à n'importe quelle moment dans ton programme Python et pourtant cela ne pose pas de soucis car on sait qu'il faut utiliser les block try/finally (ou les context manager font la même chose au final) pour gérer le nettoyage de ton code proprement. C'est pour cela que ce code est mauvais:

    fd = open('foo', 'rw')
    data = fd.read()
    ... # si une exception raise fd.close() ne sera pas appelé
    fd.write(result)
    fd.close()
    

    et que celui-ci est bon:

    with open('foo', 'rw') as fd:
        data = fd.read()
        ... # quoi qu'il arrive le with s'occupera de fermer fd
        fd.write(result)
    

    C'est exactement la même chose avec trio, sauf que tu te prends une exception trio.Cancelled au lieu d'une KeyboardInterrupt (et ça te coute rien de plus puisque t'es déjà obligé de gérer le cas KeyboardInterrupt)

    Pourquoi ne pas gérer ça dans une forme de machine à état ?

    En effet si le language le permet c'est très bien de le faire. Toutefois ce n'est pas le cas de Python donc il faut soit recréer un framework pour le faire, soit se taper le code à la main (et là autant dire qu'on a perdu)… soit tout simplement utiliser un paradigme adapté à ce langage.

    « let it crash » c'est particulier. Ça dépend de ce que tu fais comme application.

    Ça dépend surtout du niveau de granularité que tu as mis en place. Si tu crashes tout appli et la relance de zéro c'est sûr que ça ne marchera pas de masse, mais il est tout à fait possible de ne relancer qu'une partie (exemple typique: un serveur web qui ne se relance pas à chaque erreur 500 qui lui arrive, au exemple: dans une appli mobile si le service responsable de multiplexer les requêtes vers ton backend crash tu le redémarres et tu as juste à signifier aux traitements qui était en attente de ce service qu'il y a eu une déconnexion)

    Interrompre son taf c'est déjà modifier son contexte, le fait de sortir manu military des blocs de codes détruits un tas de variables,…

    D'un autre côté son taf a déjà été interrompu par l'erreur à l'origine de l'exception, maintenant c'est juste question de retourner dans un état stable (et donc d'arrêter/relancer tout ce qui a besoin de l'être).

    Au final j'ai l'impression que tu opposes programmation par message avec ce que propose trio.
    De mon point trio est une brique de plus bas niveau qui te donne des outils de qualité (cad qui te font gagner du temps et qui te pousse à faire du code propre) pour faire de l'asynchrone, à charge pour toi de l'utiliser pour faire du passage de messages ou bien du partage de ressources en fonction de ton besoin.

  • [^] # Re: Rx

    Posté par (page perso) . En réponse au journal La programmation concurrente en mode Goto. Évalué à 1.

    Tu te contredis entre ta première et ta seconde phrase…

    C'est bien possible, j'ai galéré pour trouver des définitions de asynchrone/concurrente/parallèle compatibles entre elles !
    Je viens de refaire un tour sur wikipedia:
    - programmation parallèle : plusieurs choses sont traitées à un moment donné physiquement parlant (mais du coup je fais de la programmation parallèle à petite échelle sur un CPU single core mais avec une pipeline superscalaire ? Vous avez 4h !)
    - programmation concurrente : plusieurs traitement logiciels sont menés de front, c'est donc orthogonal à la programmation parallèle (concurrent non parallèle si je fais tourner plusieurs threads logiques sur un CPU monocore)
    - programmation asynchrone : plusieurs traitement sont réalisé au sein d'un même flux de programmation (program flow).

    Du coup ça n'avance pas beaucoup, vu que je voudrais exprimer:
    1) programmation-ou-il-se-passe-plusieurs-choses-de-front: je parlais de programmation parallèle en m'abstrayant des questions physiques, mais il semblerait que c'est le terme concurrente qu'il faut employer ici (et du coup le terme parallèle ne sert à rien. vu qu'il dépend de l'architecture physique dont tout le monde se fout..)
    2) la même que 1) mais en précisant que l'implémentation se fait avec des threads et des locks comme briques de base: Encore une fois en s'arrêtant au kernel je trouve que le terme programmation concurrente marche bien ici (du point du vu de mon programme je vais effectivement avoir plusieurs threads en concurrence). J'imagine qu'il faut dire "programmation concurrente par threads" mais c'est long, et j'entends déjà le premier javaiste me demande où je classe les greenthreads…
    3) la même que 1) mais en précisant que l'implémentation se fait via sur un seul thread en le partageant de manière coopérative: J'imagine que programmation asynchrone marche bien ici

    Les exceptions sont déjà complexe à gérer là ça signifie que n'importe où une exception invisible peut subvenir ?

    C'est comme ça que Python fonctionne. Toutes les exceptions héritant de BaseException (genre SystemExit ou KeyboardInterrupt) sont déjà gérée comme ça. Note que ces exceptions ne sont pas invisible, les bonnes pratiques indiquent juste qu'il faut faire, sauf cas très particulier, un except Exception pour les laisser passer.

    L'énorme avantage de ce système c'est qu'il te suffit de faire un try/finally (ou bien d'utiliser un context manager) pour gérer le nettoyage de ton code (et ce quelque soit la cause: crash de ton code ou bien d'une coroutine sœur qui rend ton traitement caduque)

    Et enfin les exceptions son très peu cher en Python (enfin comparativement à la vitesse de Python bien sûr ), d'ailleurs c'est pour ça qu'elles sont déjà utilisées pour gérer des taches courantes comme les générators.

    La seule façon de survivre correctement à cela est d'avoir un code très défensif et perso ça ne me plaît pas des masses d'écrire ce genre de code.

    Dans tous les cas tu ne peux pas passer sous silence une erreur. L'intérêt d'une exception c'est que tu es obligé de la traiter (sinon ton programme crash), à l'inverse si tu gères tout ton système uniquement avec des passements de messages c'est très tentant de ne pas prendre en compte les crashes globales et de se retrouver avec un état incohérent au moment où ça arrive (typiquement des coroutines qui attendent indéfiniment la réponse de la coroutine ayant crashé).

    Je le répète: les problèmes d'init/teardown (en particulier dans le cas d'un crash) sont ce qu'il y a de plus compliqué en asynchrone, l'intérêt de trio est de te donner un contexte pour gérer ça simplement (on fonctionne avec des paradigmes très proche de ce qu'on ferait en programmation single thread classique). Ce que tu proposes à l'inverse c'est de gérer tout ça à la main via des passement de messages (je ne parle pas du traitement de l'erreur à proprement parler, mais de toute la machinerie qui permettra d'en arriver là), c'est du code complexe. C'est pour ça que erlang a OTP qui fait tout ce travaille pour toi (et dont la philosophie "let it crash" est très défensive de base).

    On parle de lever d'exception. Lever une exception c'est manipuler l'état de ton contexte.

    Au contraire, gérer une base de données par modification directe de l'état du système (ce que fait une levée d'exception) impose de gérer un lock global pour serialiser les opérations.

    L'exception ne modifie que le context de la coroutine touchée, c'est au développeur de choisir si la coroutine en question travaille sur toutes les données ou bien sur un sous ensemble isolé du reste du système.

    Si tu écris une méthode et qu'elle est finalement utilisée dans une tâche nursery, il sera impossible de voir dans le code de cette méthode qu'il manque potentiellement la gestion de cette dernière.

    Il n'y a pas de tâche nursery, tu as une coroutine parente qui veut lancer plusieurs traitements en parallèle. Pour ça elle créé un objet nursery qui permettra de borner le scope d'action des coroutines filles lancées.
    De faite si une fille crash, les autres filles sont arrêté proprement et l'exception d'origine est remontée dans la coroutine parente.
    Je te conseil cet article de l'auteur de trio (tous son blog vaut la peine d'être lu ) qui explique très bien l'intérêt de ce genre de mécanisme quand on cherche à gérer des timeouts.

    Toutes les bases de données ont déjà résolues se problème par la création d'un event log.

    Ou bien des locks à grain fin, ce que la programmation asynchrone rend beaucoup plus simple qu'en utilisant des threads classiques.
    De mémoire Redis fonctionne de cette façon (il implémente sa propre boucle asynchrone et lance une coroutine par connection client), on peut activer un journal de logs mais c'est pour rendre les données persistantes (donc dans tous les cas on se retrouve avec des coroutines qui travaillent sur les même données dans la base).
    Sinon un autre exemple (quoi que plus bas niveau) de ce type de besoin serait le Kernel Linux. Travailler par passement de messages est intéressant mais coûteux (cf. les débat kernel monolithique vs microkernel).

    Merci pour la discussion je la trouve enrichissante (ainsi qu'à Yves et Galndos).

    La même ;-)

  • [^] # Re: Rx

    Posté par (page perso) . En réponse au journal La programmation concurrente en mode Goto. Évalué à 3.

    c'est bien ce que je reproche c'est du parallélisme plus que de l'asynchrone. Le fait que ce soit parallèle ou pas est un détail pas un besoin fonctionnel.

    Pour moi l'asynchrone est un mécanisme de programmation parallèle au même titre de la concurrence. Dans le premier cas (l'asynchrone) un seul traitement est réalisé à un moment donné contre plusieurs dans le second (et encore, à condition d'avoir plusieurs cœurs physiques…), mais ça c'est justement des détails et pas un besoin fonctionnel.
    À contrario parler de parallélisme c'est parler d'un besoin fonctionnel (exemple: j'ai besoin de faire tourner ma gui et mon code applicatif en parallèle)

    ça gère que si l’une des deux branches se plante, il faut interrompre l’autre => ouf ça veut dire quoi ? Je veux dire, il va préempter ton code et tout interrompre ? C'est particulièrement dangereux.

    Si une des deux branches se plante ça veut dire qu'on est dans un état qui mérite un traitement particulier, ça peut être arrêter toutes les coroutines jusqu'à un certain niveau, retenter de zéro la traitement de la coroutine ayant échoué et bien encore ne rien etc.
    L'important c'est surtout de se dire qu'il y a nécessairement besoin de faire quelque chose (ce qui peut être "ne rien faire" mais dans ce cas on le fait en connaissance de cause) et pas juste balancer une stacktrace dans stdout et faire comme si de rien n'était, ce qui est malheureusement la façon de faire de bien trop de frameworks parallèles.

    Ensuite effectivement une fois qu'on sait ce qu'on doit arrêter, encore faut-il le faire proprement. À ce niveau trio injecte une exception CancelledError dans la coroutine à terminer, ce qui permet à celle-ci de se nettoyer proprement, voir même d'annuler son arrêt si le cœur lui en dit (mais encore une fois ça dépend totalement du cas d'usage).

    mais quand tu fais du twist, tu es massivement asynchrone.

    j'imagine que tu parles de twisted ?

    Remonter dans le contexte principal à chaque fois que quelque chose se passe mal est intenable.

    Je n'ai pas compris ce que tu voulais dire par contexte principal ? Dans un framework asynchrone lambda une fois l'event loop lancée il n'y a pas une coroutine plus principale qu'une autre. Et de toute façon l'event loop en question passe déjà son temps à switcher d'une coroutine à une autre donc je ne vois pas en quoi aller dans un contexte supplémentaire serait intenable…

    Il faut réduire le scope de tes actions et chercher à porter les informations dans des messages plus que dans un état.

    C'est justement la force des nursery, cela te permet de créer des scope regroupant tes coroutines. Et donc De fait quand une coroutine plante ça remonte ton arbre de scopes (en arrêtant les coroutines en bonne ordre dans la foulée) jusqu'à ce que un try/except veuille bien s'en occuper. Si personne ne veut s'en occuper, ben ton programme crash. Et c'est bien normal, explicit is better than implicit comme ils disent.

    La gestion d'un état dans un monde asynchrone est sincèrement dangereux parce qu'il est difficile de s'assurer qu'il reste cohérent quelque soit l'ordre dans le quel tes actions asynchrones se résolvent.

    Tout à fait d'accord. Malgré tout c'est parfois difficile de travailler uniquement avec un système de messages (typiquement dans le cas d'une base de donnée qui doit pouvoir traiter plusieurs requêtes en parallèle alors que celles-ci travaillent sur les mêmes données).
    Dans ces cas là l'asynchrone apporte un gros avantage par rapport à la programmation concurrente puisque les points de concurrences sont explicites (i.e. tant qu'on ne met pas un await dans le code on a la garantie que personne ne va faire des choses dans notre dos). Évidemment cela n'est pas gratuit et a ses propres limitations (si la base de donnée de l'exemple précédent fait des traitements lourds en CPU par exemple)

    Et dans tous les cas, tu peux parfaitement utiliser trio pour faire du passement de messages, les nursery te permettent juste de mieux organiser ton système. Comme par exemple pour gérer proprement ce qui doit se passer quand un point de traitement de tes messages crash…

  • [^] # Re: question sur article sametmax

    Posté par (page perso) . En réponse au journal La programmation concurrente en mode Goto. Évalué à 3.

    Ici foo est une fonction asynchrone, du coup appeler cette fonction ne provoque pas son exécution, mais créé un objet coroutine qui doit être passé à boucle d'évènements asynchrone (comme celle de asyncio ou bien de trio) pour être effectivement exécutée.

    C'est exactement le même comportement que ce qui tu aurais avec une fonction générateur (celle contenant le mot clé yield).

  • [^] # Re: sans pour autant savoir faire du dev

    Posté par (page perso) . En réponse au journal Du concombre et du cornichon. Évalué à 2.

    Sur le sujet je conseil l'article de Sam&Max sur le BDD: http://sametmax.com/lettuce-and-cucumber-is-bullshit/

    Le ton est caustique (après tout c'est pour ça qu'on les aime !) mais le fond est intéressant ;-)

  • # Intérêt de refineTH ?

    Posté par (page perso) . En réponse au journal Portage de TapTempo en Haskell. Évalué à 2.

    Déjà bravo pour le journal qui était extrêmement instructif ;-)

    Ensuite je ne comprends pas l'intérêt d'utiliser refineTH pour définir la valeur de "defaultResetTime". Vu que son type "RefinedResetTime" défini déjà les contraintes, j'aurais cru que le compilateur aurait fait la vérification dessus à la compilation automatiquement (un peu comme en C où "int Foo = 3.2" va crasher à la compilation).
    Du coup sans refineTH le ton example de valeur initiale trop grande va compiler puis crasher à la runtime ? Ça me semble étrange…

  • [^] # Re: Emacs

    Posté par (page perso) . En réponse au journal un éditeur de code portable par Microsoft?. Évalué à 5.

    Disclaimer: mon expérience avec Emacs s'est terminée vers 2013, c'est possible que le système de config se soit amélioré depuis.

    Personnellement j'ai arrêté Emacs après m'être rendu compte qu'un sublimetext out-of-the-box répondait mieux à mes besoin que ma conf Emacs dans laquelle j'avais investi des dizaines d'heures sur plusieurs années.

    C'est un peu le syndrome "écosystème javascript" avec des tonnes de paquets faisant tous un petit truc et une lib standard rachitique (ok pas rachitique dans le cas d'Emacs, mais le conservatisme des dévs fait que des fonctionnalités genre multicursors ne sont pas incluses).

    Bien sûr le fun arrive quand on se retrouve avec des fonctionnalités fournies par des paquets différents mais qui s'interpénètrent (exemple: j'ai un module fournissant une minimap du code et j'aimerai qu'il m'indique où se trouve chacun de mes multicurseurs sur celle-ci).

    Au final avec la puissance de Elisp on arrive toujours à s'en sortir… mais à quel prix ! C'est un langage avec une philosophie bien à part, demander à un mec qui veut juste tweaker un truc dans sa conf de l'apprendre c'est un non-sens en terme d’ergonomie.

    Bref on en revient toujours à la courbe d'apprentissage : les anciens ne la voient plus et considèrent les nouveaux qui s'en plaignent comme des incapables. Le fait que j'ai fini par me considérer comme faisant partie de la seconde catégorie après des années d'utilisation régulière d'Emacs témoignera de la dureté de cette courbe (insérer une strip xkcd ici).

  • [^] # Re: Réinvention de la roue

    Posté par (page perso) . En réponse au journal un éditeur de code portable par Microsoft?. Évalué à 5.

    Déjà ce serait bien que Emacs et XEmacs se réconcilies, on verra ensuite pour unifier le reste…

  • [^] # Re: Euhhh...

    Posté par (page perso) . En réponse au journal Le cycle de Qarnot. Évalué à 10.

    Y'a déjà hotmail pour ça !