Go: proposition : spec : littéraux entiers binaires

Créé le 27 févr. 2017  ·  91Commentaires  ·  Source: golang/go

Actuellement, Go prend en charge les littéraux entiers octaux et hexadécimaux en plus des littéraux décimaux standard auxquels vous vous attendez. Afin de compléter ce groupe, je propose également d'ajouter des littéraux entiers binaires. Ils se présenteraient sous la forme d'un nouveau préfixe aux littéraux entiers : 0b ou 0B .

Avis de non-responsabilité initial

C'était ma première plongée dans le code source de Go et principalement une expérience d'apprentissage pour me mettre les pieds dans l'eau en soumettant des modifications et autres. Cela étant dit, j'apprécie toutes les critiques, commentaires et suggestions.

Le « Pourquoi » : L'art antérieur

Les littéraux binaires existent ou sont également apparus dans les langues courantes, notamment :

Tous les cas ci-dessus se sont installés sur une convention consistant 0b utiliser 0B pour préfixer les littéraux binaires, suggérant que ce serait également un choix assez confortable et judicieux pour Go, évitant les inventions inutiles et fournissant une similitude pour les programmeurs provenant de ces autres langages susmentionnés.

Le « Pourquoi » : Suite

J'ai réussi à trouver des discussions antérieures à ce sujet, même si c'était après avoir déjà implémenté la fonctionnalité et cela a plus à voir avec le changement de la syntaxe octale que spécifiquement avec les littéraux binaires. Mais https://github.com/golang/go/issues/12711#issuecomment -142338246 de @griesemer mentionne que "le 'o' pour octal et 'b' pour la notation binaire ont également été discutés dans la conception de Go. Ce n'est tout simplement pas assez rentable." Cependant, je ne vois pas cela comme un bon argument contre l'ajout de quelque chose de si simple à la langue. Surtout compte tenu du fait qu'aujourd'hui, de plus en plus de langages ont adopté la syntaxe des littéraux binaires, il semble que les décisions antérieures de conception de Go pourraient devoir être examinées sous un nouvel angle.

Exemple d'utilisation

const (
    SOME_MASK   = 0b00001111
    SOME_FLAG_A = 0b00000001
    SOME_FLAG_B = 0b00000010
    SOME_FLAG_C = 0b00000100
    SOME_FLAG_D = 0b00001000
)

Mise en œuvre

Comme j'ai dit que c'était plus une expérience d'apprentissage pour moi, j'ai déjà des changements qui implémentent cette fonctionnalité prêts :

Spécification CL-37502 : spécifiez la syntaxe pour les littéraux entiers binaires
CL-37503 cmd/compile/internal/syntaxe : analyse les littéraux binaires
CL-37504 go/scanner : analyse des littéraux entiers binaires
CL-37505 strconv : prend en charge l'analyse des littéraux entiers binaires
Test CL-37506 : étendre int_lit avec des usages littéraux binaires

FrozenDueToAge Go2 LanguageChange NeedsDecision Proposal Proposal-Accepted

Commentaire le plus utile

Voyons pourquoi les langages susmentionnés ont progressé et ajouté la prise en charge des littéraux binaires. Commençons par C++14 car c'est le premier de la liste. Quels ont été les points soulevés par James Dennett, alors employé de Google ?

L'utilisation d'un préfixe 0b/0B pour les littéraux binaires est une extension GCC existante (également prise en charge par Clang) et correspond à la même syntaxe que Java 7, Python et D.

Pourquoi ce point particulier profiterait-il à Go ?

Familiarité avec la langue.

De nombreux développeurs passent d'un langage de programmation à un langage de programmation. Corrigez-moi si je me trompe, mais nous essayons tous ce que nous savons d'une langue dans une autre. On pourrait en quelque sorte dire que la familiarité de Go avec le C et le C++ a attiré ce genre de développeurs qui voulaient une fonctionnalité particulière comme GC, mais n'aimaient pas les autres langages. C'est l'une des raisons pour lesquelles l'entreprise pour laquelle je suis actuellement stagiaire a choisi de passer à Go.

Outre les développeurs expérimentés, examinons également quel est l'avantage de la familiarité pour les développeurs débutants. Prenons également le cas d'utilisation des indicateurs mentionnés par @eddieringle . Expliquer à un débutant complet comment fonctionnent les drapeaux est beaucoup plus difficile lorsque vous devez l'expliquer en octal ou en hexadécimal, car cela nécessite que la personne les apprenne également.

Enfin, je voudrais ajouter ici que le but de chaque langage (du moins c'est ce que j'espère) est d'écrire du code propre. Et je pense que c'est quelque chose sur quoi nous sommes tous d'accord de toute façon. Lorsque l'on regarde le code de quelqu'un d'autre, il est immédiatement clair sans aucune explication que lorsqu'on a une liste de constantes littérales binaires, ce sont des drapeaux. Cette même chose est beaucoup moins simple lors de l'utilisation de l'hexadécimal ou de l'octal. Ci-dessous une comparaison.

// Hexadecimal
const (
    MASK          = 0x1E
    DEFAULT_COLOR = 0x00
    BOLD          = 0x01
    UNDERLINE     = 0x02
    FLASHING_TEXT = 0x04
    NO_CHANGE     = 0x08
)

// Octal
const (
    MASK          = 036
    DEFAULT_COLOR = 00
    BOLD          = 01
    UNDERLINE     = 02
    FLASHING_TEXT = 04
    NO_CHANGE     = 010
)

// Binary
const (
    MASK          = 0b11110
    DEFAULT_COLOR = 0b00000
    BOLD          = 0b00001
    UNDERLINE     = 0b00010
    FLASHING_TEXT = 0b00100
    NO_CHANGE     = 0b01000
)

Je pense qu'il ne faut pas penser au fait que les dernières constantes sont utilisées pour les drapeaux. Ce sont également très peu de drapeaux, alors gardez à l'esprit que cela s'ajoute définitivement lorsque vous avez plus de drapeaux. La première constante 0x1E peut certainement faire tourner les têtes lorsqu'elle est déclarée sans contexte. L'utilisation de littéraux binaires seuls peut indiquer qu'une variable peut être utilisée comme indicateur.

Le PDF C++ référencé fait également référence aux langages susmentionnés pour la prise en charge. Voyons donc ces prochains. J'ai trouvé la proposition (originale ?) de Derek Foster en 2009 pour les littéraux binaires dans JDK. La source

La première chose qu'il remet en question, avec laquelle je suis tout à fait d'accord, c'est pourquoi il y a une représentation octale dans le JDK, mais il n'y a pas de représentation binaire dans le JDK. Au cours des dernières années, je ne me suis jamais dit : « Oh, les octaux rendraient mon code plus propre ! » Ceci fait cependant référence au point précédent que j'ai fait : la familiarité . Il y a cependant une chose qu'il ajoute à mon point précédent :

Cependant, lorsque les données traitées sont fondamentalement orientées bits, l'utilisation de l'hexadécimal pour représenter des plages de bits nécessite un degré supplémentaire de traduction pour le programmeur, ce qui peut souvent devenir une source d'erreurs. [...] alors un programmeur codant selon cette spécification doit traduire chacune de ces valeurs de sa représentation binaire en hexadécimal. [...] Dans la plupart des cas, les programmeurs font ces traductions dans leur tête, et J'ESPÈRE qu'ils les font correctement. cependant, des erreurs peuvent facilement s'infiltrer et la re-vérification des résultats n'est pas assez simple pour être effectuée fréquemment.

Les notations hexadécimales et octales utilisées principalement dans le matériel au lieu de binaires peuvent entraîner des erreurs humaines. Dans la comparaison que j'ai donnée précédemment, j'ai vérifié ce que j'ai fait avec ma tête en entrant ce que je pensais être octal dans Google, ce qui a confirmé mes réponses. Je suis automatiquement sûr de mon cas quand je l'écris en binaire, mais pas quand je l'écris en hexadécimal ou octal. Et peu importe le nombre de fois que vous faites cela par jour, il est plus difficile d'écrire du code car vous devez penser à la forme binaire dans votre tête et ce faisant, il est possible de faire des erreurs.

Pour approfondir la question de savoir pourquoi il y a une notation octale, mais pas de notation binaire, j'ai une autre question à poser qui a également été posée par Derek Foster, l'auteur de la proposition littérale binaire pour le JDK : "Pourquoi Go a choisi d'utiliser le préfixe 0 pour les notations octales ?" @griesemer a déclaré que nous ne devrions pas sauter le pas lors de la mise en œuvre de nouvelles fonctionnalités :

Attendons de voir ce que les autres disent avant de sauter le pas. Merci.

Mais Go n'a-t-il pas sauté le pas lors de l'implémentation de la notation octale ? Si son argument était « parce que d'autres langues le font », alors pourquoi cet argument ne peut-il pas être utilisé pour les littéraux binaires ? Si ce n'était pas le cas, alors quelle était la raison pour laquelle le préfixe 0 pour les notations octales est entré dans la langue lorsqu'il confond les gens ?

Quelqu'un pourrait penser à tort que "0b1" représentait la même valeur que le nombre hexadécimal "0xB1". Cependant, notez que ce problème existe pour l'octal/décimal depuis de nombreuses années (confusion entre "050" et "50") et ne semble pas être un problème majeur.

- Derek Foster

Il ne semble pas y avoir plus de points en faveur des littéraux binaires car c'est quelque chose auquel nous nous référons tous dans notre tête. C'est pourquoi je pense que les propositions pour d'autres langues ont été brèves comme celle-ci. Ce n'est cependant pas une raison pour l'arrêter si rapidement.

Tous les 91 commentaires

Cela est apparu auparavant. Il y a une quantité importante de travail impliqué dans le déploiement de cela, rendre le compilateur et les changements de spécifications est trivial. Mais il y a beaucoup de bibliothèques qui devraient également être rendues cohérentes (strconv, math/big, etc.).

Si nous effectuons un changement dans ce sens, il devrait être plus approfondi et soutenir des bases arbitraires. Je suis contre tel quel.

@griesemer Oui, les modifications que je suis sur le point de soumettre modifient également strconv (à ma connaissance, c'est en fait nécessaire pour prendre en charge cette modification).

@griesemer Je ne suis pas d'accord cependant sur le fait que tout changement doit prendre en charge des bases arbitraires ou sinon aucun changement ne doit être apporté. D'après les lectures précédentes, il semble que ce serait un bon objectif pour Go2 ; il s'agit simplement de peaufiner Go1 avec la syntaxe que les développeurs d'autres langages peuvent attendre lors de l'utilisation de Go. (c'est-à-dire que la base-2 est un cas assez courant, probablement plus courant que l'octal ; base-14 ou qu'est-ce que vous avez l'est moins.)

CL https://golang.org/cl/37503 mentionne ce problème.

CL https://golang.org/cl/37504 mentionne ce problème.

CL https://golang.org/cl/37502 mentionne ce problème.

CL https://golang.org/cl/37505 mentionne ce problème.

CL https://golang.org/cl/37506 mentionne ce problème.

Cependant, je ne vois pas cela comme un bon argument contre l'ajout de quelque chose de si simple à la langue.

Ce n'est pas non plus un argument particulièrement fort en faveur de leur ajout.

À mon humble avis, vous devrez développer la section « pourquoi » en expliquant exactement quels avantages la prise en charge des littéraux binaires apportera aux personnes qui écrivent du code go.

Je ne les trouve pas particulièrement utiles ; hex est un format beaucoup plus lisible et compact pour les littéraux qui ont une "signification au niveau du bit".

Vous avez donné un "exemple d'utilisation", mais ce n'est pas très convaincant. J'écrirais ces constantes en utilisant des 0xf s et des décalages pour les autres.

@EddieRingle Cette proposition n'a pas été largement discutée et n'a pas été acceptée. Veuillez ne pas nous spammer avec des critiques de code. L'équipe Go a assez à faire avec un travail vraiment important.

Il est clair pour tout le monde que l'ajout d'une fonctionnalité simple au langage est trivial. Il est également clair que beaucoup de gens aimeraient cette fonctionnalité (je l'aurais moi-même aimé un jour). Mais cela dit, juste parce que l'on peut, n'est pas un argument qu'il faut. Tout ajout, aussi petit et simple soit-il, à une langue a des coûts à long terme. Si nous acceptons cela, il deviendra encore plus difficile à l'avenir d'avoir un mécanisme plus général, et nous devons rester rétrocompatibles.

Attendons de voir ce que les autres disent avant de sauter le pas. Merci.

Rappel de notre politique no-me-too : https://golang.org/wiki/NoMeToo

Les opinions sans contenu constructif peuvent être exprimées à l'aide des réactions emoji de Github.

@ALTree

À mon humble avis, vous devrez développer la section « pourquoi » en expliquant exactement quels avantages la prise en charge des littéraux binaires apportera aux personnes qui écrivent du code go.

Je ne les trouve pas particulièrement utiles ; hex est un format beaucoup plus lisible et compact pour les littéraux qui ont une "signification au niveau du bit", IMO.

Je dirais le contraire, en fait. Hex est plus compact dans de nombreux cas, oui, mais les littéraux binaires seraient une représentation exacte "au niveau du bit" et donc aussi lisibles que possible.

@griesemer

Cette proposition n'a pas été largement débattue et n'a pas été acceptée. Veuillez ne pas nous spammer avec des critiques de code. L'équipe Go a assez à faire avec un travail vraiment important.

Excuses. Il s'agissait à l'origine d'un seul changement, mais comme il semble que la politique Go consiste à diviser les commits en fonction de la zone de base de code affectée, c'est ainsi que j'ai fini par les diviser. Je ne savais pas que le bot ferait des commentaires individuels ici pour chaque changement. Cependant, je ne serais pas assez froid pour appeler cela un spam, ni sous-entendre que tout effort que je fais pour utiliser mon temps libre est sans importance.

Tout ajout, aussi petit et simple soit-il, à une langue a des coûts à long terme. Si nous acceptons cela, il deviendra encore plus difficile à l'avenir d'avoir un mécanisme plus général, et nous devons rester rétrocompatibles.

Comme mentionné précédemment, la route à usage général (que je préférerais également) encouragerait également la dépréciation/suppression de la syntaxe octale existante (déroutante), non ? Le sentiment que j'ai eu était que la syntaxe à usage général ( 2r0010 ou 2x0010 pour la base-2, par exemple) était une invention destinée à Go2, où des changements de rupture seraient les bienvenus de toute façon.

Mettant de côté un Go2 potentiel, pour répondre à l'affirmation selon laquelle "_si nous acceptons cela, il deviendra encore plus difficile à l'avenir d'avoir un mécanisme plus général_" : je ne vois tout simplement pas en quoi cela est vrai. L'ajout du préfixe littéral binaire serait orthogonal à une syntaxe alternative à usage général, en particulier celle que vous avez décrite dans #12711 (en fait, cette syntaxe entre directement en conflit avec les littéraux hexadécimaux, mais pas avec cette syntaxe littérale binaire proposée). Ils existeraient côte à côte tout comme la syntaxe à usage général le ferait avec les littéraux octaux, hexadécimaux et décimaux existants.

Excuses. Il s'agissait à l'origine d'un seul changement, mais comme il semble que la politique Go consiste à diviser les commits en fonction de la zone de base de code affectée, c'est ainsi que j'ai fini par les diviser. Je ne savais pas que le bot ferait des commentaires individuels ici pour chaque changement. Cependant, je ne serais pas assez froid pour appeler cela un spam, ni sous-entendre que tout effort que je fais pour utiliser mon temps libre est sans importance.

Ce n'est pas seulement que le bot envoie du courrier à propos des CL, c'est que chaque CL envoyé est une demande pour qu'un réviseur Go passe du temps à l'examiner.

La syntaxe 0b est agréable car elle est familière, mais si le véritable objectif est simplement d'ajouter des littéraux binaires au langage, je préférerais de loin la solution générique à la solution familière.

Y a-t-il une raison technique pour laquelle l'option générique ne peut pas être implémentée avant la 2.0 ? J'ai eu un certain nombre de cas récemment où les littéraux binaires auraient été préférés à l'hexa et ce serait bien d'avoir cette option dans 1.9 ou 1.10 au lieu d'attendre (peut-être de nombreuses années) jusqu'à 2.0.

@wedow Je pense qu'il serait utile de voir des cas réels spécifiques où les littéraux binaires sont utiles. Veuillez partager les cas où les littéraux binaires seraient utiles. Merci.

Je ne vois pas « devrait soutenir des bases arbitraires » comme une objection valable. Cela ajoute de la complexité/des coûts pour peu ou pas d'avantages supplémentaires. Au cours de toutes les années où j'ai piraté, les bases potentiellement utiles que j'ai entendues de personnes souhaitant utiliser sont 2, 8, 10, 12 et 16, et peut-être 64 (nous avons l'encodage base64, après tout) .

Voyons pourquoi les langages susmentionnés ont progressé et ajouté la prise en charge des littéraux binaires. Commençons par C++14 car c'est le premier de la liste. Quels ont été les points soulevés par James Dennett, alors employé de Google ?

L'utilisation d'un préfixe 0b/0B pour les littéraux binaires est une extension GCC existante (également prise en charge par Clang) et correspond à la même syntaxe que Java 7, Python et D.

Pourquoi ce point particulier profiterait-il à Go ?

Familiarité avec la langue.

De nombreux développeurs passent d'un langage de programmation à un langage de programmation. Corrigez-moi si je me trompe, mais nous essayons tous ce que nous savons d'une langue dans une autre. On pourrait en quelque sorte dire que la familiarité de Go avec le C et le C++ a attiré ce genre de développeurs qui voulaient une fonctionnalité particulière comme GC, mais n'aimaient pas les autres langages. C'est l'une des raisons pour lesquelles l'entreprise pour laquelle je suis actuellement stagiaire a choisi de passer à Go.

Outre les développeurs expérimentés, examinons également quel est l'avantage de la familiarité pour les développeurs débutants. Prenons également le cas d'utilisation des indicateurs mentionnés par @eddieringle . Expliquer à un débutant complet comment fonctionnent les drapeaux est beaucoup plus difficile lorsque vous devez l'expliquer en octal ou en hexadécimal, car cela nécessite que la personne les apprenne également.

Enfin, je voudrais ajouter ici que le but de chaque langage (du moins c'est ce que j'espère) est d'écrire du code propre. Et je pense que c'est quelque chose sur quoi nous sommes tous d'accord de toute façon. Lorsque l'on regarde le code de quelqu'un d'autre, il est immédiatement clair sans aucune explication que lorsqu'on a une liste de constantes littérales binaires, ce sont des drapeaux. Cette même chose est beaucoup moins simple lors de l'utilisation de l'hexadécimal ou de l'octal. Ci-dessous une comparaison.

// Hexadecimal
const (
    MASK          = 0x1E
    DEFAULT_COLOR = 0x00
    BOLD          = 0x01
    UNDERLINE     = 0x02
    FLASHING_TEXT = 0x04
    NO_CHANGE     = 0x08
)

// Octal
const (
    MASK          = 036
    DEFAULT_COLOR = 00
    BOLD          = 01
    UNDERLINE     = 02
    FLASHING_TEXT = 04
    NO_CHANGE     = 010
)

// Binary
const (
    MASK          = 0b11110
    DEFAULT_COLOR = 0b00000
    BOLD          = 0b00001
    UNDERLINE     = 0b00010
    FLASHING_TEXT = 0b00100
    NO_CHANGE     = 0b01000
)

Je pense qu'il ne faut pas penser au fait que les dernières constantes sont utilisées pour les drapeaux. Ce sont également très peu de drapeaux, alors gardez à l'esprit que cela s'ajoute définitivement lorsque vous avez plus de drapeaux. La première constante 0x1E peut certainement faire tourner les têtes lorsqu'elle est déclarée sans contexte. L'utilisation de littéraux binaires seuls peut indiquer qu'une variable peut être utilisée comme indicateur.

Le PDF C++ référencé fait également référence aux langages susmentionnés pour la prise en charge. Voyons donc ces prochains. J'ai trouvé la proposition (originale ?) de Derek Foster en 2009 pour les littéraux binaires dans JDK. La source

La première chose qu'il remet en question, avec laquelle je suis tout à fait d'accord, c'est pourquoi il y a une représentation octale dans le JDK, mais il n'y a pas de représentation binaire dans le JDK. Au cours des dernières années, je ne me suis jamais dit : « Oh, les octaux rendraient mon code plus propre ! » Ceci fait cependant référence au point précédent que j'ai fait : la familiarité . Il y a cependant une chose qu'il ajoute à mon point précédent :

Cependant, lorsque les données traitées sont fondamentalement orientées bits, l'utilisation de l'hexadécimal pour représenter des plages de bits nécessite un degré supplémentaire de traduction pour le programmeur, ce qui peut souvent devenir une source d'erreurs. [...] alors un programmeur codant selon cette spécification doit traduire chacune de ces valeurs de sa représentation binaire en hexadécimal. [...] Dans la plupart des cas, les programmeurs font ces traductions dans leur tête, et J'ESPÈRE qu'ils les font correctement. cependant, des erreurs peuvent facilement s'infiltrer et la re-vérification des résultats n'est pas assez simple pour être effectuée fréquemment.

Les notations hexadécimales et octales utilisées principalement dans le matériel au lieu de binaires peuvent entraîner des erreurs humaines. Dans la comparaison que j'ai donnée précédemment, j'ai vérifié ce que j'ai fait avec ma tête en entrant ce que je pensais être octal dans Google, ce qui a confirmé mes réponses. Je suis automatiquement sûr de mon cas quand je l'écris en binaire, mais pas quand je l'écris en hexadécimal ou octal. Et peu importe le nombre de fois que vous faites cela par jour, il est plus difficile d'écrire du code car vous devez penser à la forme binaire dans votre tête et ce faisant, il est possible de faire des erreurs.

Pour approfondir la question de savoir pourquoi il y a une notation octale, mais pas de notation binaire, j'ai une autre question à poser qui a également été posée par Derek Foster, l'auteur de la proposition littérale binaire pour le JDK : "Pourquoi Go a choisi d'utiliser le préfixe 0 pour les notations octales ?" @griesemer a déclaré que nous ne devrions pas sauter le pas lors de la mise en œuvre de nouvelles fonctionnalités :

Attendons de voir ce que les autres disent avant de sauter le pas. Merci.

Mais Go n'a-t-il pas sauté le pas lors de l'implémentation de la notation octale ? Si son argument était « parce que d'autres langues le font », alors pourquoi cet argument ne peut-il pas être utilisé pour les littéraux binaires ? Si ce n'était pas le cas, alors quelle était la raison pour laquelle le préfixe 0 pour les notations octales est entré dans la langue lorsqu'il confond les gens ?

Quelqu'un pourrait penser à tort que "0b1" représentait la même valeur que le nombre hexadécimal "0xB1". Cependant, notez que ce problème existe pour l'octal/décimal depuis de nombreuses années (confusion entre "050" et "50") et ne semble pas être un problème majeur.

- Derek Foster

Il ne semble pas y avoir plus de points en faveur des littéraux binaires car c'est quelque chose auquel nous nous référons tous dans notre tête. C'est pourquoi je pense que les propositions pour d'autres langues ont été brèves comme celle-ci. Ce n'est cependant pas une raison pour l'arrêter si rapidement.

Voici une autre option, qui me semble plus claire que n'importe laquelle des constantes entières.

// Shifts
const (
    MASK          = 0x1e
    DEFAULT_COLOR = 0
    BOLD          = 1<<0
    UNDERLINE     = 1<<1
    FLASHING_TEXT = 1<<2
    NO_CHANGE     = 1<<3
)

(Et le masque ne devrait-il pas être 0xf, pas 0x1e ?)

Je suis légèrement contre l'ajout de constantes binaires, au moins dans Go 1. Je serais pour les ajouter dans Go 2, cependant. La raison de la différence est que si pour une raison quelconque quelqu'un est bloqué à Go 1.8, lorsque Go 1.9 sort avec des constantes binaires, si l'une des importations (transitives) du code de cette personne utilise des constantes binaires, alors ils ne peuvent plus construire leur projet en utilisant Go 1.8. Ils devraient vendre ou mettre à niveau. L'ajout d'une fonctionnalité incompatible en avant a un coût certain qui devrait peser contre son utilité.

Je suis d'accord que je ne vois aucun besoin de bases non dans {2,8,10,16}. Le cas de l'octal semble particulièrement fragile, je serais en faveur de la suppression de l'octal dans Go 2.

@ randall77 Je ne suis pas d'accord pour dire que le changement de

(Et le masque ne devrait-il pas être 0xf, pas 0x1e ?)

Le nom MASK a simplement été tiré de la proposition JDK et n'est pas vraiment conforme aux autres constantes. Mais cela montre que 0x1E et les hexadécimaux causent déjà de la confusion.

Je peux comprendre le point que vous essayez de faire en voulant le déplacer vers Go 2. Mais je ne suis pas d'accord pour dire que nous devrions avoir à soutenir les projets qui rétrogradent leur version Go de 1.9 à 1.8. Cela ferait des changements de langue un cauchemar à gérer. Je ne sais cependant pas comment Go voit cela, il serait plus sage de suivre quelle compatibilité Go a en tête.

Je soutiens de tout cœur votre position sur la suppression de l'octal dans Go 2.

Je viens de relire mon commentaire précédent (en particulier, "L'équipe Go a assez à faire avec un travail qui est réellement important."). Je tiens à m'excuser pour cette déclaration qui était une formulation plutôt offensante de ce que je voulais réellement dire. Alors laissez-moi réessayer, en développant un peu plus et, espérons-le, en trouvant le bon ton cette fois :

Nous apprécions les propositions bien étayées et, si nécessaire, accompagnées de prototypes de mise en œuvre. Cela dit, le processus de proposition Go est volontairement léger et aucun travail supplémentaire n'est requis par le proposant, à moins qu'il ne soit demandé ou nécessaire pour comprendre la proposition. L'envoi de listes de modifications qui ne sont pas demandées et/ou ne résolvent pas un problème est contre-productif car quelqu'un devra prendre le temps de les regarder (ne serait-ce que pour les reporter ou les fermer). Une meilleure approche, si l'on veut prototyper/écrire le code à l'avance, consiste à établir un lien avec les modifications ailleurs (par exemple, un commit GitHub privé). Cela laissera le choix à l'équipe Go et aux contributeurs externes : ils peuvent décider d'examiner ce code s'ils le souhaitent ou de se concentrer sur des éléments de priorité plus élevée. Merci.

@griesemer Gotcha, je comprends et cela a du sens. J'ai supposé que l'équipe de Go traitait son Gerrit comme l'AOSP le fait, et j'ai pensé que mes changements pourraient exister là-bas pendant que cela était discuté. Lier à une branche ici sur GitHub est de toute façon moins de travail, donc c'est un gagnant-gagnant, je suppose. :)

En fait, j'ai d'abord fait le travail puisque mon objectif principal était de pirater le compilateur. C'est après coup que j'ai décidé de le soumettre sous forme de proposition.

@AndreasBackx Le premier 0 pour octal en Go a été discuté dans le numéro #151. Voir aussi #12711.

Lors de la définition de constantes à 1 bit défini, le décalage est plus lisible que 0b00001000..00 pour la simple raison que dans la version shift, vous n'avez pas besoin de compter un tas de zéros à l'écran juste pour comprendre quel bit est défini ; vous venez de lire la valeur de décalage.

0b100000000000000000000000 vs 1 << 23

En ce qui concerne l'utilisation dans le monde réel, une méthode courante de codage d'entiers à longueur variable consiste à utiliser le bit de poids fort pour "lire la suite". J'ai dû l'utiliser pour extraire les fichiers git pack. Voici le code pour extraire les bits inférieurs dans différentes bases :

b & 127
b & 0x1f
b & 0177
b & 0b01111111

Personnellement, je pense que la version binaire montre plus clairement l'intention.

Vous avez toujours l'option de décalage mentionnée précédemment
Si vous pensez que ce n'est pas lisible, utilisez une fonction d'assistance

b & ^(^0 << 7)
b & mask(7)

@AndreasBackx , 1<<12 est plus clair que 0b0001000000000000 car je n'ai pas à compter tous ces zéros. Il est évident que c'est un masque car le 12 situe entre 11 et 13 , ou utilise iota . Lorsqu'il faut faire correspondre un modèle arbitraire, par exemple en masquant des bits d'un mot d'instruction, alors l'hexa est préférable car un programmeur habitué à traiter des bits peut lire 0xae et "voir" 10101110 en sachant que 0xa, dix, est 1010, mnémonique dix- dix, tout comme on apprend les tables de multiplication, 65 est ASCII A , etc. Hex est une représentation plus dense qui est plus facile à analyser pour le lecteur humain.

@randall77 , 0644, 02775, etc., ne sont-ils pas un peu fastidieux sans octal ? C'est pourquoi ça bouge encore.

@RalphCorderoy : oui, il me semble que l'octal survit pour la seule raison de construire un os.FileMode .
0664 = 6<<6 + 6<<3 + 4 , ce qui n'est pas trop fastidieux. Ce serait mieux si os fournissait des constantes symboliques pour rendre cela plus facile, ou au moins plus clair.

Nous savons déjà comment éviter le problème du comptage des zéros : nous devrions supporter 0b1e10 pour signifier 1 suivi de 10 zéros, en binaire. Certes, cela fonctionnerait mieux si nous avions un moyen de concaténer des constantes binaires plutôt que de les ajouter.

En fait, j'ai d'abord fait le travail puisque mon objectif principal était de pirater le compilateur.

Excellent. Si vous souhaitez des idées d'endroits pour continuer à pirater le compilateur pendant que cela est discuté, n'hésitez pas à m'envoyer un e-mail - (nom d'utilisateur github) @ gmail.

@RalphCorderoy 1<<12 est plus clair que 0b0001000000000000 car je n'ai pas à compter tous ces zéros.

Une solution à ce problème serait de permettre une sorte de séparation. Java autorise les traits de soulignement dans les littéraux numériques. Il a été brièvement discuté dans le #42, mais il n'y avait pas beaucoup d'arguments contre, s'il y avait des commentaires sur cette question en premier lieu.

La solution de @ianlancetaylor devrait peut-être aussi être envisagée.

Il est évident que c'est un masque car le 12 se situe entre 11 et 13, ou utilise l'iota.

Je suis désolé, mais c'est peut-être le cas pour vous. Mais pas pour tout le monde.

Lorsqu'il faut faire correspondre un modèle arbitraire, par exemple en masquant des bits d'un mot d'instruction, alors l'hexa est préférable car un programmeur habitué à traiter des bits peut lire 0xae et "voir" 10101110 en sachant que 0xa, dix, est 1010, mnémonique dix- dix, tout comme on apprend les tables de multiplication, 65 est ASCII A, etc.

Cela laisse place à l'erreur dans le code comme cela a été indiqué précédemment par moi et des propositions faites pour d'autres langues qui l'ont trouvé une raison valable. Vous supposez également ici que chaque "programmeur" connaît l'hex par cœur et que ce n'est pas le cas. Vous pouvez travailler avec beaucoup de matériel, mais ce n'est pas le cas pour la plupart des gens. Les débutants préféreraient certainement les littéraux binaires à la représentation hexadécimale.

Hex est une représentation plus dense qui est plus facile à analyser pour le lecteur humain.

Est-ce que dense signifie qu'il est plus propre ? Non, ce n'est pas le cas. Les gens écrivent tout le temps des lignes simples pour des choses folles et la raison pour laquelle celles-ci sont quelque peu impressionnantes est que ce code est si dense et illisible que nous nous demandons tous quelle sorcellerie se cache derrière la signification de chaque personnage.

1 << 10 est beaucoup plus clair que 0b1e10 .

Je trouve les littéraux binaires difficiles à lire. Très souvent, ce dont vous avez besoin arrondit à trois ou quatre segments de bits, qui sont beaucoup plus faciles et moins sujets aux erreurs à lire et à écrire en octal ou en hexadécimal. Lorsque les choses ne se limitent pas à des limites aussi égales, un changement est également beaucoup plus facile à lire et à écrire, et moins sujet aux erreurs.

Une certaine forme de concaténation rendrait les littéraux binaires plus faciles à lire et à écrire, au prix d'incohérences. Pourquoi les littéraux binaires peuvent-ils être concaténés, mais aucun autre type de littéraux numériques ? Pourquoi pas un sort ? À ce stade, cette discussion devient sans limites.

Personnellement, je préférerais une sorte de mécanisme de base générique. Je ne pense pas que les littéraux binaires apportent suffisamment à la table (et je n'écris que du code de bas niveau).

De plus, je suis presque sûr que nous avons eu cette discussion plusieurs fois auparavant.

(En remarque, la disparition de l'octal a été grandement exagérée. Octal est utile au-delà de la définition des modes de fichier. J'utilise certainement plus les littéraux octaux que j'utiliserais les littéraux binaires.)

C'est un peu surprenant pour moi de voir autant d'opinions personnelles exprimées comme arguments à propos d'un changement de langue. Je ne sais pas comment quantifier les commentaires liés à l'utilité que vous y trouverez personnellement.

Si certaines raisons pour lesquelles les sentiments personnels ont des points de mérite, je dirai arbitrairement que j'utilise des littéraux binaires en Java et je peux valider mon opinion à ce sujet en disant que je programme depuis 100 ans et que je possède une voiture.

Ensuite, débattre s'il est plus facile d'utiliser le décalage pour définir des masques, c'est comme affirmer que les calendriers grégoriens sont plus faciles à utiliser que les calendriers chinois. Ce n'est pas parce que vous le trouvez plus facile à utiliser que tout le monde le fait. Le fait que les littéraux binaires existent dans d'autres langues devrait probablement être une indication que quelqu'un les a trouvés utiles en affirmant que l'argument de décalage n'est pas vraiment un argument car il s'agit simplement d'une alternative.

Cela est apparu auparavant. Il y a une quantité importante de travail impliqué dans le déploiement de cela, rendre le compilateur et les changements de spécifications est trivial. Mais il y a beaucoup de bibliothèques qui devraient également être rendues cohérentes (strconv, math/big, etc.).

C'est un argument solide contre cette proposition et je comprendrais parfaitement l'hésitation à apporter des changements qui créent une quantité de travail importante.

Je dirais le contraire, en fait. Hex est plus compact dans de nombreux cas, oui, mais les littéraux binaires seraient une représentation exacte "au niveau du bit" et donc aussi lisibles que possible.

Ce qui est amusant à propos de l'apprentissage du binaire, c'est que vous devez réellement lire et écrire du binaire, puis effectuer des calculs dessus. Écrire en hexadécimal ou décimal ou octal ou base64 (lul) peut indirectement aider à apprendre le binaire, mais j'ai entendu dire que le simple fait d'apprendre ce que vous voulez apprendre directement est utile (probablement juste une opinion cependant).

Personnellement, je préférerais une sorte de mécanisme de base générique.

Je souhaite que chaque langue ait cela sous une forme littérale.

@randall77 : Comme indiqué par #151, il y a plusieurs raisons de garder octal. Oui, l'un est le réglage des modes de fichier, mais c'est le dernier important. Les deux autres sont le changement de sémantique en un littéral entier commençant par 0 et l'importance du code de portage de sécurité de tout autre langage de type C, dans lequel les constantes octales ont cette syntaxe. Il est vrai qu'aucun d'entre eux n'est convaincant, mais pris ensemble, ils répondent à la barre. Quoi qu'il en soit la question est tranchée, au moins pour le Go 1.

Quant aux constantes binaires, je ne pense pas qu'elles portent leur poids. Très peu de programmes en bénéficieraient, et même dans ce cas, l'avantage est faible.

@robpike Il serait prudent de ne pas compiler tout ce qui ressemble à une constante octale (commence par 0 mais pas "0").

Laissons ça pour Go 2.

Pourquoi attendre? Ça ne casse rien.
Le lundi 6 mars 2017 à 15h19, Russ Cox [email protected] a écrit :

Laissons ça pour Go 2.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/golang/go/issues/19308#issuecomment-284535766 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/ABLfW7bN2NicSthvEvMeGEhqExg2et-qks5rjHhtgaJpZM4MNgUY
.

@DocMerlin , parce que Go n'est pas un langage qui continue d'augmenter les fonctionnalités simplement parce qu'il le peut. Tous les changements de langue sont essentiellement suspendus pour le moment jusqu'à ce qu'ils puissent être évalués ensemble en tant que groupe, de sorte qu'ils ressemblent et fonctionnent ensemble comme un tout cohérent. C'est pourquoi cela est étiqueté Go2.

@DocMerlin J'aime ajouter au commentaire de

Ce sont également très peu de drapeaux, alors gardez à l'esprit que cela s'ajoute définitivement lorsque vous avez plus de drapeaux.
SOME_FLAG_D = 0b00000000010000000000000000000000000

En un coup d'œil, est-ce 2^19 ou 2^20 ? Vous voyez le problème ?

Merci @davecheney , j'ai rattrapé le fil. Je n'avais pas pensé qu'il pourrait y avoir un effort massif à faire pour que la bibliothèque standard prenne en charge les littéraux entiers binaires.

Il est évident qu'il n'y a pas de cas d'utilisation où une routine qui gère la manipulation de bits sur des entiers ne peut pas être correctement exprimée en raison du manque de littéraux binaires, et rien n'est gagné en termes de performances en exprimant des données entières dans une base plutôt qu'une autre.

Cependant, il existe de nombreuses situations d'encodage binaire (codecs vidéo, compression de données, protocoles réseau binaires, etc.) où les masques binaires, les constantes binaires et d'autres données bitmap peuvent être rendus plus lisibles dans le code source si les données sont exprimées en base 2.

C'est une question de lisibilité et de style pour les personnes qui manipulent des données bitmap.

La lisibilité et le style sont les mêmes raisons pour lesquelles la notation littérale entière octale a été prise en charge par Go dès le premier jour. L'inclusion de la prise en charge des littéraux entiers octaux est très probablement une décision liée à la gestion des autorisations de fichiers Unix. Il est difficile d'imaginer de nos jours de nombreuses utilisations pratiques de la notation octale autres que la prise en charge héritée des autorisations de style Unix et la lisibilité de ces données dans le code.

Le support octal est néanmoins utile pour montrer qu'il n'y a que deux fonctions simples dans strconv chargées de la gestion des chaînes octales.

archive/tar/strconv.go:func (p *parser) parseOctal(b []byte) int64
archive/tar/strconv.go:func (f *formatter) formatOctal(b []byte, x int64)

Pour évaluer très grossièrement l'impact de l'ajout de la prise en charge des littéraux binaires, une méthode possible consiste à vérifier l'empreinte de code d'une prise en charge équivalente pour octal, une chose triviale car octal est si rarement utilisé qu'il est facile d'identifier les endroits et les situations dans lesquels la base 8 est pris en charge.

Dans ma copie locale en ce moment, une recherche approximative montre que la plupart d'entre elles sont des opérations d'analyse et de formatage.

vxv@vxs :/gosource$ grep -i -r octal * | wc -l
73
vxv@vxs :/gosource$ grep -i -r octal * | grep "fun" | wc -l
2

Certes, il s'agit d'une recherche triviale et simple d'esprit, mais les proportions du problème ne semblent pas présenter une tâche insurmontable.

Pas de soucis. Pour info je n'ai pas de chien dans cette course, je suis juste là pour jardiner les problèmes. C'est aux autres de décider du sort de cette proposition de go 2

Cependant, il existe de nombreuses situations d'encodage binaire (codecs vidéo, compression de données, protocoles réseau binaires, etc.) où les masques binaires, les constantes binaires et d'autres données bitmap peuvent être rendus plus lisibles dans le code source si les données sont exprimées en base 2.

J'ai utilisé tout ce qui précède et je n'ai jamais imaginé que la base 2 pourrait avoir des avantages pour ceux-ci. Pourriez-vous me citer un exemple concret pour me convaincre du contraire ?

La lisibilité devrait être l'une des principales raisons de l'implémentation des littéraux binaires. J'écris actuellement un moteur qui tire parti du positionnement des bits, et j'utilise uint16, uint32 pour plusieurs cas d'utilisation et chaque tranche/section de ces uints représente des informations différentes.

Aux échecs, nous utilisons des coups codés en ajoutant des drapeaux, de et vers un uint16. Ce serait bien de voir une implémentation littérale binaire afin que le code puisse afficher, uniquement par lui-même, quelles sections se rapportent à quelles informations.

...
constexpr uint_fast16_t FLAG_SPECIAL1  {0b0010000000000000};
constexpr uint_fast16_t FLAG_SPECIAL0  {0b0001000000000000};
constexpr uint_fast16_t RANGE_FLAG     {0b1111000000000000};
constexpr uint_fast16_t RANGE_FROM     {0b0000111111000000};
constexpr uint_fast16_t RANGE_TO       {0b0000000000111111};

Ceci est mon exemple de code de C++17. Dans Go cependant, cela ressemblera à ceci:

const FlagSpecial1 uint16 = 8192
const FlagSpecial2 uint16 = 4096
const RangeFlag uint16 = 61440
const RangeFrom uint16 = 4032
const RangeTo uint16 = 63

Essentiellement utile pour écrire du code propre et simple pour quiconque travaille avec des bits et des masques.

Vous n'arrivez pas à obtenir un précompilateur pour cela et vous n'aurez plus rien à réécrire ? Puisqu'après tout c'est de l'esthétique (à mes yeux).

Quel bit est défini dans (c++)

constexpr uint_fast16_t FLAG_SPECIAL0  {0b0001000000000000};

vs

quel bit est défini dans (Aller)

const FlagSpecial0 = 0x10000

Je ne suis probablement pas le seul à pouvoir le dire immédiatement dans le dernier cas seulement.

Avec l'approche 0b00.. vous pouvez le voir, sans avoir à connaître les nombres hexadécimaux. C'est plus facile à lire quand vous avez une grande liste de uint16. Comprendre que le bit défini est à la position 13, puisque la taille est répertoriée, dans l'exemple que vous avez donné est plus facile que d'utiliser hexadécimal. 1<<13 , serait bien mieux que hex et vous n'avez pas besoin de rechercher des valeurs, vous pouvez simplement le regarder et savoir quels bits sont ciblés. Mais pour une plage ou plusieurs bits définis, il peut être plus facile d'utiliser simplement un littéral binaire.

En regardant les derniers cas comme 61440 je suis impressionné que vous puissiez le dire immédiatement, et vous pensez qu'il est plus facile de savoir quels bits sont définis en utilisant des décimales qu'un littéral binaire, mais tout le monde ne le voit pas.

Mais vous avez simplement ignoré les autres cas comme 0b0000111111000000 qui est 0xfe0 ou 4064 en décimal. À mon avis, c'est plus propre en utilisant le littéral binaire. 16 bits est un nombre plus grand, mais regardez les octets :

0b11101010 contre 0xea . Vous n'avez même pas besoin de penser à ce qui est ciblé, vous le savez dès que vous jetez un œil.

@andersfylling , Si vous programmez des masques de bits, vous devez vraiment être capable de lire l'hexadécimal: RangeFlag ne serait pas 61440 mais 0xf000, ce qui rend immédiatement évident que c'est le premier quartet des 16 bits.

Pour ceux qui pensent avoir une nouvelle idée de ce problème, pouvez-vous parcourir tous les commentaires du haut, en prenant particulièrement note de la référence de Brad à la politique NoMeToo, avant de nous réveiller de notre sommeil.

Le décalage hexadécimal et binaire fait tout pour moi (plus les autorisations de fichier octal), mais je me demande si l'apprentissage de la manipulation de bits en C aurait pu être plus facile avec des littéraux entiers binaires. J'aime l'apparence des exemples ci-dessus en binaire. Peut-être que je l'utiliserais pour de petits masques ou pour déplacer de petits masques.

x := y & (0b101 << 8)

(modifier : le meilleur moyen de Go est x := y & 0b101<<8 )

Je viens de rencontrer ce manque de fonctionnalité aujourd'hui. Dans mon exemple de cas d'utilisation, j'utilise le champ de jour de la semaine entier d'une date (0..6 pour signifier dimanche..samedi) et le vérifie par rapport à un masque de préférence. Parce que la source de l'entier est programmatique, je ne définis pas un ensemble de constantes pour chaque jour de la semaine (mon code n'a aucune raison de parler de DIMANCHE spécifiquement), donc la syntaxe 1 << 3 n'est pas utile ici. Cependant, je veux une valeur par défaut pour le masque de préférence, qui serait peut-être 0b0111110. Évidemment, il est facile d'écrire cette valeur par défaut sous la forme décimale (126) ou hexadécimale (0x7e), mais il est considérablement plus clair de l'écrire en binaire.

Re: octal, notez qu'entre python2 et pyhon3, ils ont abandonné la prise en charge du format 0110 et nécessitent maintenant 0o110 à la place. Ensuite, ils ont rétroporté l'analyse 0o110 vers python2 sans y supprimer l'ancien format, ce qui permet de commencer facilement à utiliser la nouvelle syntaxe moins sujette aux erreurs, sans rompre la compatibilité avec l'ancienne version. Dans python2, un nombre substantiel d'utilisateurs de python avaient fini par déclarer accidentellement des nombres octaux lors du collage de nombres décimaux complétés par 0, ce qui a prêté à confusion. (Problème courant : numéros de série complétés par la longueur d'une base de données de pièces ou numéros de facture complétés par la longueur.) J'ai en fait passé une demi-heure confuse à cause de cela, à essayer de comprendre pourquoi mon test unitaire « évidemment correct » échouait.

D'un autre côté, je n'ai jamais eu besoin de prendre en charge des constantes de langage dans une base arbitraire. Peut-être que quelqu'un l'a fait, mais cela semble être un faux-fuyant (et la syntaxe nécessaire pour le prendre en charge semble être assez moche).

Un autre exemple qui vient de me brûler était la définition d'adresses dans les protocoles embarqués (I2C, SPI, CAN, etc...) où il y a souvent une adresse définie comme une constante binaire dans la feuille de données décalée qui a une sorte de bit de lecture/écriture dans le cadre de la valeur. Les convertir en hexadécimal ajoute une couche supplémentaire de traduction que le cerveau humain doit faire, donc une chose de plus à remettre en question lors du débogage.

Salut @tapir , veuillez lire mon commentaire précédent https://github.com/golang/go/issues/19308#issuecomment-352290337, en particulier https://github.com/golang/go/wiki/NoPlusOne car NoMeToo s'appelle maintenant.

Voici une contre-proposition qui permet une notation de base arbitraire à peu près au même (ou moins) coût : #28256 . Je propose une notation à laquelle j'ai fait allusion directement ou indirectement dans diverses discussions, mais jamais formellement écrite. S'il vous plaît commenter là pour les opinions.

Voir #28493 (proposition indépendante) discutant de l'utilisation de _ comme séparateur entre les chiffres.

Si vous revoyez cette discussion ancienne / mise de côté pour Go 2, je vous suggère de regarder octal en même temps. Évidemment, vous ne pouvez pas supprimer la notation 0123 (pour des raisons de compatibilité - pas sans période de dépréciation au moins), mais vous pouvez ajouter 0o123 en même temps que vous ajoutez 0bXXX . Cela permettrait un ensemble plus cohérent d'identifiants de base de nombres, favorisant la belle uniformité de la syntaxe de Go et les attentes du programmeur.

Mais, à elle seule, la proposition binaire vaudrait toujours la peine.

strconv.ParseInt prendrait-il en charge la syntaxe 0b010 lorsque base vaut 0 ?

@nathany Oui, si nous décidons de prendre en charge le préfixe 0b dans la langue, nous devrions également le prendre en charge dans la bibliothèque. Par exemple, le compilateur s'appuie actuellement sur la méthode SetString de math/big.Int pour convertir les littéraux constants en big.Ints - on pourrait donc s'attendre à ce que SetString (et ses amis, tels que strconv.ParseInt) comprennent également 0b.

Peut-être moins évident est de savoir si ParseInt doit également filtrer les séparateurs _ si nous l'acceptons avec #28493. Ce serait facile en tant que chemin séparé (remplacez _ par ` ) but for error handling (e.g.; do we allow _` n'importe où, ou non) et les performances dont nous pourrions avoir besoin pour le gérer dans ParseInt (et toutes les autres routines ParseXXX pour les nombres ).

Devrait-il y avoir une proposition/problème séparé pour le littéral octal 0o ou est-il préférable de le garder avec celui-ci ?

0o correspondrait à Swift et Rust. Nous pourrions examiner leur raisonnement pour préférer cette syntaxe.

Une des raisons pour lesquelles j'ai vu préférer 0o à 0 est d'éviter toute ambiguïté avec strconv.ParseInt("012", 0, 64)"012" pourrait être une entrée utilisateur. Cependant, je ne sais pas si c'est vraiment un problème dans Go comme dans d'autres langages, étant donné que Atoi utilise toujours la base 10, et qu'il n'y a pas d'arguments par défaut dans Go, donc le programmeur doit explicitement demander à dériver la base du préfixe de chaîne en spécifiant 0 pour la base.

Je ne peux pas dire que j'ai déjà eu besoin d'utiliser _ dans une chaîne en cours d'analyse. Moins évident en effet.

@nathany Je suggérerais un problème distinct. Je suis d'accord que si nous décidons d'autoriser 0b il pourrait être logique d'autoriser également 0o pour la cohérence (et alors nous pouvons vouloir que gofmt réécrive automatiquement 0 -prefix octals dans 0o préfixes octaux afin que le premier puisse être progressivement supprimé de la base de code). Mais cette proposition concerne les littéraux entiers binaires ; gardons-le là-dessus.

Ma question d'origine n'a pas reçu de réponse, j'ai donc relu l'intégralité du fil pour voir pourquoi un fil
avec autant de pouces levés, il y a si peu de discussions.

Jusqu'à présent, la proposition demande des littéraux binaires pour les raisons suivantes :

d'autres langues en ont

La proposition détaille méticuleusement comment les autres langues les ont et comment les autres y sont habitués. Cela a-t-il déjà été une raison suffisante auparavant ?

ils sont "plus lisibles"

Je ne suis pas d'accord. Ce sont des motifs ignobles de uns et de zéros qui ne se prononcent pas facilement sans un
conversion en base16.

  • Tu sais juste

0b11101010 contre 0xea. Vous n'avez même pas besoin de penser à ce qui est ciblé, vous n'avez qu'à
le savoir dès que vous jetez un oeil.

_Le premier bit de poids faible, le troisième bit de poids faible et le cinquième bit de poids faible sont désactivés, mais pas les autres. Et il y a [compte le nombre total de bits deux fois pour s'assurer que le nombre est correct] huit
bits au total._

Je sais quel est le modèle, et je m'en souviendrai probablement pendant quelques secondes. Comment est cette connaissance
intrinsèquement utile?

  • Aller contre C++

Certains arguments dénaturent leur avantage, peut-être involontairement. Dans un exemple particulier dans
ce fil, l'extrait suivant a été publié en comparant go et c++.

constexpr uint_fast16_t FLAG_SPECIAL1  {0b0010000000000000};
constexpr uint_fast16_t FLAG_SPECIAL0  {0b0001000000000000};
constexpr uint_fast16_t RANGE_FLAG     {0b1111000000000000};
constexpr uint_fast16_t RANGE_FROM     {0b0000111111000000};
constexpr uint_fast16_t RANGE_TO       {0b0000000000111111};

This is my code example from C++17. In Go however, it will look like this:

const FlagSpecial1 uint16 = 8192
const FlagSpecial2 uint16 = 4096
const RangeFlag uint16 = 61440
const RangeFrom uint16 = 4032
const RangeTo uint16 = 63

Le problème est que le C++ est méticuleusement aligné alors que le Go n'est pas formaté, qu'il manque un bloc const et qu'il utilise incorrectement des décimales au lieu de hex (que vous ne pouvez pas facilement convertir en binaire en divisant chaque chiffre hexadécimal en quatre binaires) .

const (
    FlagSpecial1 uint16 = 0x2000
    FlagSpecial2 uint16 = 0x1000
    RangeFlag    uint16 = 0xf000
    RangeFrom    uint16 = 0x0fc0
    RangeTo      uint16 = 0x003f
)

les spécifications des protocoles publient parfois des binaires

Un autre exemple qui vient de me brûler était la définition d'adresses dans les protocoles intégrés
(I2C, SPI, > CAN, etc...) où il y a souvent une adresse définie comme une constante binaire dans le
feuille de données décalée > qui a une sorte de bit de lecture / écriture dans le cadre de la valeur. Conversion
les hexadécimal ajoute une couche de traduction supplémentaire que le cerveau humain doit faire, donc une couche de plus
chose à remettre en question lors du débogage.

Le problème est que le cerveau humain ne devrait pas faire cela pour vous en premier lieu. |

Considérez à nouveau votre expérience de débogage. Vont vider les littéraux entiers binaires vers stderr ou
et grep pour eux plus tard? Partagerez-vous ces chiffres avec vos collègues en disant chaque 1
et 0 à voix haute ? Les chances sont que vous les sortiez et les transmettez plutôt en hexadécimal, et si c'est vrai, c'est
également vrai que le code source doit exprimer ces chiffres en hexadécimal afin de supprimer le besoin
pour que le cerveau humain (ou programme) fasse encore plus de travail pour le lecteur.

De nombreuses spécifications expriment 1010 pour signifier un flux binaire composé de ces états ordonnés. Cela ne correspond pas à la notion d'octet de littéraux entiers binaires et brûlera sûrement quelqu'un qui s'attend à
pour implémenter un lecteur bitstream. (Je préférerais implémenter un lecteur de flux de bits dans la bibliothèque standard plutôt que de prendre en charge les littéraux entiers binaires).

Je viens de rencontrer ce manque de fonctionnalité aujourd'hui. Dans mon exemple de cas d'utilisation, j'utilise le jour de la semaine entier
champ d'une date (0..6 pour signifier dimanche..samedi) et en le vérifiant par rapport à un masque de préférence.
Parce que la source de l'entier est programmatique, je ne définis pas un ensemble de constantes pour chaque jour
de la semaine (mon code n'a aucune raison de parler de DIMANCHE en particulier), donc 1 << 3 syntaxe
n'est pas utile ici. Cependant, je veux une valeur par défaut pour le masque de préférence, qui serait
peut-être 0b0111110. Évidemment, il est facile d'écrire cette valeur par défaut sous la forme décimale (126) ou hexadécimale (0x7e), mais
il est beaucoup plus clair de l'écrire en binaire.

J'aurais les jours de la semaine comme constantes non exportées et je construirais le masque en OR utilisant leurs valeurs. Je ne suis pas d'accord que les littéraux entiers binaires aideraient à rendre quelque chose plus clair dans cette situation.

@as Merci pour votre commentaire. Il a été enregistré.

Il est clair que nous n'avons pas besoin de littéraux entiers binaires ; nous avons un moyen assez proche d'exprimer de tels nombres en utilisant des littéraux hexadécimaux (et je l'ai souligné dans mon article de blog ). Mais en même temps, ils semblent résoudre un problème pour de nombreux programmeurs, et c'est quelque chose que nous pourrions facilement résoudre ici sans ajouter beaucoup de complexité au langage.

Peut-être qu'une meilleure façon de réfléchir à cette question est de savoir si nous voulons amener Go à la hauteur de la plupart des autres langages de programmation à cet égard et compléter l'ensemble des représentations littérales entières en prenant en charge toutes les bases pertinentes (2, 8, 10, 16).

C'est une question qui est distincte du sentiment personnel sur l'utilité des littéraux binaires et peut être plus facile à répondre.

Le changement https://golang.org/cl/152338 mentionne ce problème : spec: add binary integer literals (tentative)

Voir https://golang.org/cl/152338 pour les modifications de spécifications pertinentes à cette proposition (en ignorant les séparateurs _ dans cette première étape).

Le changement https://golang.org/cl/152377 mentionne ce problème : spec: permit underscores for grouping in numeric literals (tentative)

Je cherchais une référence pour divers algorithmes de tri où le pseudo-aléatoire était défini sur 0xff & (i ^ 0xab) S'il s'agissait de 0b10101011 au lieu de 0xab ce serait plus lisible. Je suis surpris qu'il n'y ait pas de littéraux binaires dans Go, pas même une proposition...

@andrewmed Ceci _est_ la proposition de littéraux entiers binaires.

Je l'ai Merci

Nous avons publié une proposition combinée pour les #19308, #12711, #28493 et ​​# 29008 sur

Notez que ce sera la première proposition de suivre le processus décrit dans l'article de blog : nous aurons tout prêt à l'emploi et enregistré au début du cycle Go 1.13 (1er février), nous passerons les trois prochains mois à les utiliser. fonctionnalités et sollicitant des commentaires basés sur l'utilisation réelle, puis au début du gel de la version (1er mai), nous prendrons la "décision de lancement" d'inclure ou non le travail dans Go 1.13.

Merci pour vos commentaires et toute votre aide à l'amélioration de Go.

À l'origine suggéré par @rsc : il pourrait être sage de déprécier (mais toujours prendre en charge) 0X pour l'hexadécimal, puis de ne pas ajouter 0B (inutile) et 0O (inutile, déroutant et difficile à lire).

@robpike ... et que gofmt commence à changer 0X en 0x.

@josharian , oui, j'ai également

Mais pour 0X -> 0x, cela pourrait être fait dans gofmt, oui.

Je n'ai pas de sentiments forts à propos de 0B contre 0b et 0O contre 0o (de nombreux éditeurs de code écrivent un zéro avec une barre oblique à travers eux qui semble différent d'un O majuscule ; personnellement, j'utilise toujours des minuscules).

Mais le point principal de l'ajout de ces nouveaux formats est d'être compatible avec d'autres langues et de soulager la douleur des personnes venant de ces langues, et peut-être de traduire du code provenant d'ailleurs. Cela irait à l'encontre de cet objectif si ces personnes ou ce code utilisaient des majuscules dans ces préfixes et que Go ne pouvait pas digérer ces littéraux après tout.

Je note également qu'il y aura un peu d'incohérence avec l'exposant où nous autorisons E et e (et nouvellement P et p).

En bref, bien que je soutiens totalement le sentiment, interdire les majuscules 0B semble être une différence gratuite qui n'aide de toute façon pas les gens habitués aux minuscules 0b (ce qui, je suppose, est majoritaire) et blesse les autres.

D'un autre côté, laisser gofmt effectuer le changement automatiquement (ou peut-être avec -s) semble être une bonne idée.

en tant que développeur intégré qui travaille beaucoup avec des bits individuels et des masques de bits, les littéraux binaires seraient un changement bienvenu. Je les ai récemment découverts en (GC)C et j'ai été agréablement surpris.
bien sûr, à peu près tout le monde peut comprendre assez rapidement 0x1 , 0x80 et 0x8000 . mais quelque chose comme 0x1c vous fait faire une pause. Bien sûr, (7 << 2) est un peu mieux 0b00011100 est juste plus lisible et transmet le sens - trois bits contigus 2 positions vers la gauche - plus clairement.

Le changement https://golang.org/cl/157677 mentionne ce problème : cmd/compile: accept new Go2 number literals

Le changement https://golang.org/cl/159997 mentionne ce problème : go/scanner: accept new Go2 number literals

Le changement https://golang.org/cl/160018 mentionne ce problème : cmd/gofmt: test that Go 2 number literals can be formatted

Le changement https://golang.org/cl/160239 mentionne ce problème : go/constant: accept new Go2 number literals

Le changement https://golang.org/cl/160240 mentionne ce problème : go/types: add tests for new Go 2 number literals

Le changement https://golang.org/cl/160247 mentionne ce problème : fmt: scan new number syntax

Le changement https://golang.org/cl/160250 mentionne ce problème : math/big: add %#b and %O integer formats

Le changement https://golang.org/cl/160248 mentionne ce problème : text/template: accept new number syntax

Le changement https://golang.org/cl/160246 mentionne ce problème : fmt: format 0b, 0o prefixes in %#b and %O

Le changement https://golang.org/cl/160244 mentionne ce problème : strconv: add 0b, 0o integer prefixes in ParseInt, ParseUint

Le changement https://golang.org/cl/160184 mentionne ce problème : cmd/gofmt: normalize number prefixes and exponents

Le changement https://golang.org/cl/160478 mentionne ce problème : design/19308-number-literals: add note about gofmt

Pour rappel, nous avons introduit un nouveau processus pour ces changements de langue liés à Go 2 dans notre article de blog blog.golang.org/go2-here-we-come. Nous allons provisoirement accepter une proposition, apporter des modifications au début d'un cycle, acquérir de l'expérience en l'utilisant, puis prendre la décision d'acceptation finale trois mois plus tard, lors du gel. Pour Go 1.13, cela signifierait un changement lorsque l'arbre ouvrira en février et prendre la décision finale lorsque l'arbre gèlera en mai.

Nous allons provisoirement accepter cette proposition pour Go 1.13 et prévoyons de débarquer sa mise en œuvre lorsque l'arbre s'ouvrira. L'état du problème pour « tentative accepter » sera marqué Proposition-acceptée mais laissée ouverte et jalonnée vers la version Go (Go1.13 ici). Au gel, nous réexaminerons le problème et le fermerons s'il est finalement accepté.

Le changement https://golang.org/cl/161098 mentionne ce problème : spec: document new Go2 number literals

Le changement https://golang.org/cl/161199 mentionne ce problème : text/scanner: accept new Go2 number literals

Le changement https://golang.org/cl/163079 mentionne ce problème : text/scanner: don't liberally consume (invalid) floats or underbars

Le changement https://golang.org/cl/173663 mentionne ce problème : unicode/utf8: use binary literals

Le changement https://golang.org/cl/174897 mentionne ce problème : cmd/compile: disable Go1.13 language features for -lang=go1.12 and below

Pour rappel, nous avons introduit un nouveau processus pour ces changements de langue liés à Go 2 dans notre article de blog blog.golang.org/go2-here-we-come. Le cycle de développement de Go 1.13 est maintenant terminé et il est temps de prendre la décision finale.

Les retours sur les changements littéraux du nombre Go 2 ont été fortement positifs, avec très peu de voix négatives. Ces changements modernisent et harmonisent la syntaxe des nombres littéraux de Go sans ajouter de complexité significative au langage : il existe désormais une notation de préfixe uniforme pour les trois bases de nombres non décimales communes, qui correspond à la notation utilisée dans d'autres langages de programmation modernes. L'introduction de littéraux hexadécimaux à virgule flottante résout un problème pour les personnes qui s'intéressent au code numérique. Le suffixe « i » peut maintenant être utilisé avec n'importe quel littéral numérique (non imaginaire) pour créer une constante imaginaire de manière uniforme. Et enfin, les traits de soulignement peuvent être utilisés pour diviser les littéraux plus longs en groupes de chiffres pour une meilleure lisibilité.

Proposition acceptée pour Go 1.13. Fermeture car les changements ont atterri.

- rsc pour l'examen de la proposition

Le changement https://golang.org/cl/189718 mentionne ce problème : compiler: support new numeric literal syntax

Cette page vous a été utile?
0 / 5 - 0 notes