Mais si on a un pseudo, c'est plus comme faire un tag sur un mur quelconque. Les passants peuvent le lire mais ne savent pas qui est vraiment l'auteur (à part celui qui a accès à la caméra de surveillance qui t'a filmé en train de taguer : l'admin du site/service).
Ça semble possible avec la nouvelle syntaxe mais je ne garantie pas le qualité de ce que j'ai écrit. Ça marche avec GCC et clang, mais MSVC ne semble pas encore supporter la nouvelle syntaxe. Donc en pratique, pour l'instant, c'est pas mieux que l'extension GNU mais ça pourrait être le futur.
Il me semble que la syntaxe des littéraux que tu utilises pour _kw est une extension GNU et pas du C++14 standard.
Je me souviens avoir essayé de créer des littéraux du même genre (chaîne dans un type) et de ne rien avoir trouvé de pratique et standard. Peut-être que C++20 améliore ça, je ne connais pas encore très bien.
J'ai pas essayé coc, ça a l'air un peu trop gros pour moi. Pour pouvoir utiliser LSP, j'ai installé LanguageClient-neovim. Il y a juste à lui dire quel serveur utiliser pour chaque langage, pas besoin d'installer nodejs.
Oui c'est comme ça qu'il y a des consoles libres à base de microcontroleurs 8bits. Mais c'est du temps processeur de pris donc ça peut facilement ramer si le jeu a un rafraichissement rapide ou exige beaucoup de changements de pixels par image. C'est l'une des raisons de la disponibilité de différents modes d'affichage sur les vieux ordis.
Sinon pas nécessaire d'aller si bas niveau pour une console virtuelle conçue pour des ordinateurs actuels de 32bit ou plus qui possédent tous un GPU gérant au minimum OpenGLES.
On est quand même sur du dessin très simple : rotations à 90 degrés et étirements par des facteurs entiers pour les opérations les plus complexes. On a surtout besoin de copier des pixels un peu partout, un CPU n'est pas si mauvais pour ça.
Et OpenGL, c'est aussi du temps CPU pour envoyer les données et commandes à chaque image. Et sur un eeepc avec une implémentation logiciel d'OpenGL, on doit se retrouver avec un surcoût énorme comparé à un rendu logiciel naïf qu'on aurait pu écrire soi-même.
La NES et la SMS
Des machines avec des processeurs très très faibles mais compensés par des GPU spécialisés dans le dessin de sprites. J'aurais plutôt comparé aux vieux jeux DOS qui faisaient mieux que le TIC-80 mais sans accélération matérielle.
Vu le type de dessin, ça devrait être possible de faire ce genre de rendu en logiciel sur n'importe quel processeur du 21ème siècle, non ?
À une époque j'ai pas mal programmé sur TI-89 (Motorola 68k à 12MHz, 256Ko de RAM), il n'y avait pas d'accélération matériel graphique mais ça ne posait pas trop de problèmes pour faire des jeux 2D simples. Ce n'était que du monochrome mais avec la différence de puissance des processeurs on devrait quand même pouvoir passer à 16 couleurs.
Il est bizarre ce logiciel libre : je n'ai pas trouvé de lien vers le code source sur le site. La seule version Linux est un paquet Debian, j'ai donc besoin de compiler pour ma distribution exotique (fedora). On trouve bien des liens vers github pour les bugs ou le wiki, mais rien vers le code lui-même.
J'ai l'impression que c'est le pronom relatif implicite qui te dérange : « Falsehoods (that) programmers believe about names » → « Erreurs auxquels les programmeurs croient au sujet des noms »
Pour compléter les autres réponses, il y a un mécanicisme un peu plus complexe mais plus puissant (et qui est celui utilisé dans le journal). Il se base sur une règle du C++ abrégée en SFINAE (Substitution Failure Is Not An Error). L'idée est que si, lors de la substitution d'un type dans un template, on obtient une déclaration que n'a pas de sens, le compilateur ignore la fonction au lieu d'émettre une erreur. Ça ne marche que dans la déclaration (paramètres du template, type de retour, ou types des paramètres), pas dans le corps de la fonction.
#include<iostream>template<typenameT>typenameT::Af(T){std::cout<<"J'ai un type imbriqué A"<<std::endl;return{};}template<typenameT>typenameT::Bf(T){std::cout<<"J'ai un type imbriqué B"<<std::endl;return{};}structType1{usingA=int;};structType2{usingB=int;};intmain(){f(Type1{});f(Type2{});return0;}
Ce qui donne :
J'ai un type imbriqué A
J'ai un type imbriqué B
Pas d'erreurs puisqu'à chaque fois exactement une des fonctions est gardée. Si un type avait à la fois une type imbriqué A et B, les deux fonctions seraient valide et le compilateur générerait une erreur comme il ne saurait pas choisir. Si un type n'a aucune des deux propriétés, les deux fonctions sont ignorées et le compilateur génère une erreur disant que f n'existe pas (mais s'il est sympa, il t'explique pourquoi il a ignoré les deux possibilités avec un message à rallonge).
Ça permet d'avoir des fonctions surchargées qui sélectionnent la bonne alternative en fonction des propriétés d'un type paramètre du template. Évidemment, si la condition que tu veux avoir n'est pas un type que tu utilises en retour ou en paramètre, ça devient plus compliqué mais beaucoup de choses sont possibles. Les concepts de C++20 simplifient largement tout ça.
Pour aider à l'utilisation avancée du SFINAE pré-C++20, il y avait quelques aides comme enable_if et une TS proposait d'ajouter des détecteurs (mais c'est sûrement devenu obsolète avec les concepts).
Perso je l'utilise par exemple suivant si l'utilisateur veut une version Unicode ou pas de ma lib, utile à une époque même si moins de nos jours, je ne vois pas comment proposer ça simplement avec les modules, à part faire comme Java par avoir les 2 interfaces pour tous et limiter la taille du bousin est un truc que j'aime en C++ justement).
Si j'ai bien compris, tu as toujours le droit d'utiliser des #ifdef, mais les defines sont limités au module qui en a besoin. Plus besoin d'ajouter un -DZENITRAM_UNICODE pour la compilation de tous les fichiers qui pourraient inclure directement ou indirectement tes headers. Le revers c'est que les modules ne peuvent plus exporter de macros.
En effet, l'intérêt est limité. Mais il faut aussi se poser la question dans l'autre sens : quels sont les désavantages des fonctions curryfiées et quels sont les avantages des fonctions prenant un tuple de tous les arguments en même temps ?
J'en vois assez peu. Le principal, comme le montre l'existence de ce fil, c'est que ça perturbe ceux qui ne connaissent pas. Donc dans la plupart des langages, les fonctions curryfiées sont à éviter sauf quand c'est vraiment utile. Mais dans les langages dans lesquels c'est idiomatique (comme le Haskell ou d'autres langages fonctionnels), ça ne coûte rien de curryfier par défaut et de n'utiliser les tuples seulement quand c'est vraiment nécessaire.
Je rappelle aussi qu'en maths, une fonction associe à chaque élément d'un domaine un élément du codomaine. Si on veut passer plusieurs paramètres, le domaine est un ensemble produit et on doit créer un tuple pour passer les paramètres. Dans beaucoup de langages ce n'est pas un problème, mais j'imagine que pour un langage très matheux comme Haskell c'est une source de complexité supplémentaire (en pratique on devra écrire add (a,b) au lieu de add a b, c'est un peu plus lourd mais ça reste acceptable, la principale raison reste idiomatique).
Avec une syntaxe assez simple, il serait possible de faire la même chose: si _ est un argument a remplir plus tard, il est possible de faire f(x, _ , y).
Il y a des langages qui proposent ce genre de syntaxe ? Est-ce que c'est vraiment plus clair qu'une syntaxe du genre z => f(x, z, y).
Je ne comprends pas pourquoi les formes curryfiées seraient nécessaires pour avoir des fonctions pures. Une fonction de type A × B → C peut tout autant être pure que A → B → C.
Pour moi, l'intérêt des fonctions curryfiées était avant tout l'application partielle.
Pour la lecture, une fois qu'on me l'a expliqué, ça ne m'a jamais dérangé. Le prérequis important me semble de savoir dans quel ordre les flèches doivent être lues (elles ne sont pas associatives).
A → B → C est A → (B → C) et non (A → B) → C. Le type du retour est donc derrière la dernière flèche, les autres flèches séparent les arguments dans l'ordre dans lequel on doit les donner. Si on veut retourner plusieurs objets, on est obligé d'utiliser un produit : A → B × C.
[^] # Re: Beaucoup de "solutions"
Posté par Clément V . En réponse au journal Jouer à distance avec du logiciel libre. Évalué à 1.
Steam Link, ce n'est ni payant, ni du cloud. Tu utilises ton propre ordinateur pour lancer le jeu. Mais c'est proprio et nécessite un compte en ligne.
# VirtualGL
Posté par Clément V . En réponse au journal Jouer à distance avec du logiciel libre. Évalué à 5.
https://www.virtualgl.org/
C'est du X11 à distance mais le rendu 3D est effectué sur le serveur puis envoyé au client sous forme d'images.
[^] # Re: La part des choses...
Posté par Clément V . En réponse au journal Ados et réseaux sociaux. Évalué à 3.
Mais si on a un pseudo, c'est plus comme faire un tag sur un mur quelconque. Les passants peuvent le lire mais ne savent pas qui est vraiment l'auteur (à part celui qui a accès à la caméra de surveillance qui t'a filmé en train de taguer : l'admin du site/service).
[^] # Re: Mainteneurs
Posté par Clément V . En réponse au lien Trouver facilement un téléphone compatible avec LineageOS. Évalué à 4.
Il faut comparer ça à la version d'Android pour le même matériel qui a sûrement 0 mainteneurs.
[^] # Re: Fichier mp3 bien « taggé » mais toujours galère à récupérer
Posté par Clément V . En réponse au lien [Matinale France Culture] Pourquoi les logiciels libres intéressent-ils les Etats ?. Évalué à 1.
Je m'étais fait un script greasemonkey mais il a cassé. Je l'ai réparé, c'est un peu moche, mais ça marche au moins (pour l'instant) :
[^] # Re: Moui
Posté par Clément V . En réponse au journal Toujours plus proche du Python avec C++. Évalué à 2.
J'imagine que reference_wrapper doit passer.
[^] # Re: Littéraux non-standard
Posté par Clément V . En réponse au journal Toujours plus proche du Python avec C++. Évalué à 4.
J'ai tenté un bricolage en C++20 : https://gcc.godbolt.org/z/MxExbc
Ça semble possible avec la nouvelle syntaxe mais je ne garantie pas le qualité de ce que j'ai écrit. Ça marche avec GCC et clang, mais MSVC ne semble pas encore supporter la nouvelle syntaxe. Donc en pratique, pour l'instant, c'est pas mieux que l'extension GNU mais ça pourrait être le futur.
# Littéraux non-standard
Posté par Clément V . En réponse au journal Toujours plus proche du Python avec C++. Évalué à 2.
Il me semble que la syntaxe des littéraux que tu utilises pour
_kw
est une extension GNU et pas du C++14 standard.Je me souviens avoir essayé de créer des littéraux du même genre (chaîne dans un type) et de ne rien avoir trouvé de pratique et standard. Peut-être que C++20 améliore ça, je ne connais pas encore très bien.
# LanguageClient
Posté par Clément V . En réponse au journal Transformer vim en IDE avec LSP et DAP. Évalué à 6.
J'ai pas essayé coc, ça a l'air un peu trop gros pour moi. Pour pouvoir utiliser LSP, j'ai installé LanguageClient-neovim. Il y a juste à lui dire quel serveur utiliser pour chaque langage, pas besoin d'installer nodejs.
[^] # Re: Solution technique à un problème économique
Posté par Clément V . En réponse au journal Gemini et Solid, deux alternatives au Web (qu'il faut qu'on m'explique). Évalué à 3.
SGML est une syntaxe trop horrible, l'XHTML2 c'était bien.
[^] # Re: Config
Posté par Clément V . En réponse à la dépêche Sortie de TIC‑80 version 0.80 . Évalué à 2.
On est quand même sur du dessin très simple : rotations à 90 degrés et étirements par des facteurs entiers pour les opérations les plus complexes. On a surtout besoin de copier des pixels un peu partout, un CPU n'est pas si mauvais pour ça.
Et OpenGL, c'est aussi du temps CPU pour envoyer les données et commandes à chaque image. Et sur un eeepc avec une implémentation logiciel d'OpenGL, on doit se retrouver avec un surcoût énorme comparé à un rendu logiciel naïf qu'on aurait pu écrire soi-même.
Des machines avec des processeurs très très faibles mais compensés par des GPU spécialisés dans le dessin de sprites. J'aurais plutôt comparé aux vieux jeux DOS qui faisaient mieux que le TIC-80 mais sans accélération matérielle.
[^] # Re: Config
Posté par Clément V . En réponse à la dépêche Sortie de TIC‑80 version 0.80 . Évalué à 2.
Vu le type de dessin, ça devrait être possible de faire ce genre de rendu en logiciel sur n'importe quel processeur du 21ème siècle, non ?
À une époque j'ai pas mal programmé sur TI-89 (Motorola 68k à 12MHz, 256Ko de RAM), il n'y avait pas d'accélération matériel graphique mais ça ne posait pas trop de problèmes pour faire des jeux 2D simples. Ce n'était que du monochrome mais avec la différence de puissance des processeurs on devrait quand même pouvoir passer à 16 couleurs.
[^] # Re: PICO-8 vs TIC-80
Posté par Clément V . En réponse à la dépêche Construisez et programmez votre console de jeux open source. Évalué à 2.
Il est bizarre ce logiciel libre : je n'ai pas trouvé de lien vers le code source sur le site. La seule version Linux est un paquet Debian, j'ai donc besoin de compiler pour ma distribution exotique (fedora). On trouve bien des liens vers github pour les bugs ou le wiki, mais rien vers le code lui-même.
Donc je mets le lien vers la page github pour ceux que ça intéresse : https://github.com/nesbox/TIC-80
[^] # Re: Croyances
Posté par Clément V . En réponse au lien Falsehoods Programmers Believe About Names – With Examples. Évalué à 3.
J'ai l'impression que c'est le pronom relatif implicite qui te dérange : « Falsehoods (that) programmers believe about names » → « Erreurs auxquels les programmeurs croient au sujet des noms »
[^] # Re: Dommage que ce ne soit pas pour DNF
Posté par Clément V . En réponse au lien yum history. Évalué à 3.
Il y a des chances que yum ne soit qu'un alias de dnf et que donc tu utilisais déjà dnf sans le savoir. Sur Fedora 32 en tout cas :
# uBlock Origin bloque les trackers déguisés
Posté par Clément V . En réponse au lien Le déguisement des trackers par Cname. Évalué à 2.
Je ne connaissais pas la technique mais je suis rassuré : uBlock Origin a déjà une solution contre celle-ci (https://github.com/gorhill/uBlock/releases/tag/1.25.0).
[^] # Re: Firefox a eu sa chance par le public
Posté par Clément V . En réponse au journal Hégémonie et navigateurs. Évalué à 1.
Sync n'est toujours pas complet, il manque les moteurs de recherche : https://bugzilla.mozilla.org/show_bug.cgi?id=444284 12 ans que ça dure !
[^] # Re: Typage structurel
Posté par Clément V . En réponse au journal C++ Hell/Heaven et les concepts. Évalué à 3.
Pour compléter les autres réponses, il y a un mécanicisme un peu plus complexe mais plus puissant (et qui est celui utilisé dans le journal). Il se base sur une règle du C++ abrégée en SFINAE (Substitution Failure Is Not An Error). L'idée est que si, lors de la substitution d'un type dans un template, on obtient une déclaration que n'a pas de sens, le compilateur ignore la fonction au lieu d'émettre une erreur. Ça ne marche que dans la déclaration (paramètres du template, type de retour, ou types des paramètres), pas dans le corps de la fonction.
Ce qui donne :
J'ai un type imbriqué A
J'ai un type imbriqué B
Pas d'erreurs puisqu'à chaque fois exactement une des fonctions est gardée. Si un type avait à la fois une type imbriqué A et B, les deux fonctions seraient valide et le compilateur générerait une erreur comme il ne saurait pas choisir. Si un type n'a aucune des deux propriétés, les deux fonctions sont ignorées et le compilateur génère une erreur disant que f n'existe pas (mais s'il est sympa, il t'explique pourquoi il a ignoré les deux possibilités avec un message à rallonge).
Ça permet d'avoir des fonctions surchargées qui sélectionnent la bonne alternative en fonction des propriétés d'un type paramètre du template. Évidemment, si la condition que tu veux avoir n'est pas un type que tu utilises en retour ou en paramètre, ça devient plus compliqué mais beaucoup de choses sont possibles. Les concepts de C++20 simplifient largement tout ça.
Pour aider à l'utilisation avancée du SFINAE pré-C++20, il y avait quelques aides comme enable_if et une TS proposait d'ajouter des détecteurs (mais c'est sûrement devenu obsolète avec les concepts).
[^] # Re: Quel est l'intérêt ?
Posté par Clément V . En réponse au journal C++ vin va vous faire tourner en barrique !. Évalué à 3.
Si j'ai bien compris, tu as toujours le droit d'utiliser des
#ifdef
, mais les defines sont limités au module qui en a besoin. Plus besoin d'ajouter un-DZENITRAM_UNICODE
pour la compilation de tous les fichiers qui pourraient inclure directement ou indirectement tes headers. Le revers c'est que les modules ne peuvent plus exporter de macros.[^] # Re: Est-ce qu'il y a....
Posté par Clément V . En réponse au lien Micro: enfin un éditeur de texte normal pour votre terminal?. Évalué à 4.
Une fonctionnalité nécessaire pour devenir le meilleur éditeur de texte (aussi appelé vim).
Plus précisément, une façon très pratique de sélectionner des bouts de textes.
[^] # Re: Bien sûr
Posté par Clément V . En réponse au journal Toujours plus de fun avec C. Évalué à 5.
Non, Perl (source : https://xkcd.com/224/).
[^] # Re: Comportement indéfini
Posté par Clément V . En réponse au journal C++, surcharge d'opérateur, ordre d'évaluation. Évalué à 1.
Je ne savais que la règle avait changé. C'est quand même étrange de voir = comme un point de séquence.
Mais là
-std=c++11
est passé au deux compilateurs, donc on est bien dans un cas où l'ordre est indéfini, non ?# Comportement indéfini
Posté par Clément V . En réponse au journal C++, surcharge d'opérateur, ordre d'évaluation. Évalué à 8.
L'ordre entre
m[1]
etm.size()
n'est pas déterminé.operator=
est exécuté en dernier mais ce n'est pas lui qui ajoute l'élément, c'estm[1]
.[^] # Re: Haskell super expressif ?
Posté par Clément V . En réponse au journal Comprendre Go en 5 minutes, en Haskell. Évalué à 1.
En effet, l'intérêt est limité. Mais il faut aussi se poser la question dans l'autre sens : quels sont les désavantages des fonctions curryfiées et quels sont les avantages des fonctions prenant un tuple de tous les arguments en même temps ?
J'en vois assez peu. Le principal, comme le montre l'existence de ce fil, c'est que ça perturbe ceux qui ne connaissent pas. Donc dans la plupart des langages, les fonctions curryfiées sont à éviter sauf quand c'est vraiment utile. Mais dans les langages dans lesquels c'est idiomatique (comme le Haskell ou d'autres langages fonctionnels), ça ne coûte rien de curryfier par défaut et de n'utiliser les tuples seulement quand c'est vraiment nécessaire.
Je rappelle aussi qu'en maths, une fonction associe à chaque élément d'un domaine un élément du codomaine. Si on veut passer plusieurs paramètres, le domaine est un ensemble produit et on doit créer un tuple pour passer les paramètres. Dans beaucoup de langages ce n'est pas un problème, mais j'imagine que pour un langage très matheux comme Haskell c'est une source de complexité supplémentaire (en pratique on devra écrire
add (a,b)
au lieu deadd a b
, c'est un peu plus lourd mais ça reste acceptable, la principale raison reste idiomatique).Il y a des langages qui proposent ce genre de syntaxe ? Est-ce que c'est vraiment plus clair qu'une syntaxe du genre
z => f(x, z, y)
.[^] # Re: Haskell super expressif ?
Posté par Clément V . En réponse au journal Comprendre Go en 5 minutes, en Haskell. Évalué à 4.
Je ne comprends pas pourquoi les formes curryfiées seraient nécessaires pour avoir des fonctions pures. Une fonction de type A × B → C peut tout autant être pure que A → B → C.
Pour moi, l'intérêt des fonctions curryfiées était avant tout l'application partielle.
Pour la lecture, une fois qu'on me l'a expliqué, ça ne m'a jamais dérangé. Le prérequis important me semble de savoir dans quel ordre les flèches doivent être lues (elles ne sont pas associatives).
A → B → C est A → (B → C) et non (A → B) → C. Le type du retour est donc derrière la dernière flèche, les autres flèches séparent les arguments dans l'ordre dans lequel on doit les donner. Si on veut retourner plusieurs objets, on est obligé d'utiliser un produit : A → B × C.