Les types en tant que bits

Il y a de nombreux types possibles en Elm :

  • Bool
  • Int
  • String
  • (Int, Int)
  • Maybe Int
  • ...

Nous en avons une compréhension conceptuelle à présent, mais comment sont-ils compris par un ordinateur ? Comment Maybe Int est-il stocké sur le disque dur ?

Bits

Un bit est une petite boite qui a deux états. Zéro ou un. Allumé ou éteint. La mémoire d'un ordinateur est une séquence de bits extrêmement longue.

Ok, donc nous avons un gros ensemble de 0 et de 1. Maintenant il nous faut tout représenter avec ça !

Bool

Une valeur Bool peut être soit True ou False. Ça correspond exactement à un bit !

Int

Une valeur Int est un nombre entier comme 0, 1, 2, etc. On ne peut pas stocker ça dans un seul bit, donc la seule solution est d'utiliser plusieurs bits. Un Int serait donc normalement une séquence de bits, comme celle-ci :

00000000
00000001
00000010
00000011
...

Nous pouvons attribuer arbitrairement un sens à chacune de ces séquences. Alors peut-être que 00000000 est zéro et 00000001 est un. Génial ! Nous pouvons simplement commencer à attribuer des numéros aux séquences de bits dans l'ordre croissant. Mais nous finirons par manquer de bits...

Avec un rapide calcul, huit bits n'autorisent que (2^8 = 256) nombres. Qu'en est-il des nombres totalement acceptables comme 9000 et 8004 ?

La réponse est simplement d'ajouter plus de bits. Pendant longtemps, les gens ont utilisé 32 bits. Cela a permis (2^32 = 4 294 967 296) nombres qui couvrent les types de nombres auxquels les humains pensent généralement. De nos jours, les ordinateurs prennent en charge les nombres entiers 64 bits, permettant (2^64 = 18 446 744 073 709 551 616) nombres. C'est beaucoup !

Remarque : Si vous êtes curieux de savoir comment fonctionne l'addition, consultez le complément à deux. Il explique que les numéros ne sont pas attribués arbitrairement aux séquences de bits. Afin de rendre l'addition aussi rapide que possible, cette façon particulière d'attribuer des nombres fonctionne très bien.

String

La chaîne "abc" est la séquence de caractères a b c, nous allons donc commencer par essayer de représenter les caractères sous forme de bits.

L'une des premières méthodes d'encodage des caractères s'appelle ASCII. Tout comme avec les nombres entiers, ils ont décidé de lister un tas de séquences de bits et de commencer à attribuer des valeurs arbitrairement :

00000000
00000001
00000010
00000011
...

Ainsi, chaque caractère devait tenir sur huit bits, ce qui signifie que seuls 256 caractères pouvaient être représentés ! Mais si vous ne vous souciez que de l'anglais, cela fonctionne plutôt bien. Vous devez couvrir 26 lettres minuscules, 26 lettres majuscules et 10 chiffres. Ça fait 62. Il reste beaucoup de place pour les symboles et autres trucs bizarres. Vous pouvez voir ce qu'ils ont obtenu ici.

On s'est fait une bonne idée pour les caractères, mais comment l'ordinateur saura-t-il où se termine la String et où commence la donnée suivante ? Ce ne sont que des bits. Les caractères ressemblent vraiment à des valeurs Int ! Nous avons donc besoin d'un moyen de marquer la fin.

De nos jours, les langages ont tendance à le faire en stockant la longueur de la chaîne. Ainsi, une chaîne comme "hello" pourrait ressembler à 5 h e l l o en mémoire. Vous savez donc qu'une String commence toujours par 32 bits représentant la longueur. Et que la longueur soit 0 ou 9000, vous savez exactement où s'arrêtent les caractères.

Remarque : À un moment donné, les gens ont voulu d'autres langues que l'anglais. Cet effort a finalement abouti au codage UTF-8. C'est en réalité génial et je vous encourage à en apprendre davantage. Il s'avère que « obtenir le 5e caractère » est plus difficile qu'il n'y paraît !

(Int, Int)

Qu'en est-il des tuples ? Eh bien, (Int, Int) correspond à deux valeurs Int, et chacune est une séquence de bits. Mettons simplement ces deux séquences l'une à côté de l'autre en mémoire et appelons ça un jour calendaire !

Types personnalisés

Un type personnalisé consiste à combiner différents types. Ces différents types peuvent avoir toutes sortes de formes différentes. Nous allons commencer par le type Couleur :

type Couleur = Rouge | Jaune | Vert

Nous pouvons attribuer un numéro à chaque cas : Rouge = 0, Jaune = 1 et Vert = 2. Nous pouvons maintenant utiliser la représentation Int. Ici, nous n'avons besoin que de deux bits pour couvrir tous les cas possibles, donc '00' est rouge, '01' est jaune, '10' est vert et '11' est inutilisé.

Mais qu'en est-il des types personnalisés contenant des données supplémentaires ? Comme Maybe Int ? L'approche typique consiste à mettre de côté quelques bits pour "tagger" les données, afin que nous puissions décider que "Nothing = 0" et "Just = 1". Voici quelques exemples:

  • Nothing = 0
  • Just 12 = 1 00001100
  • Just 16 = 1 00010000

Une expression case regarde toujours ce "tag" avant de décider quoi faire ensuite. Si elle voit un 0, elle sait qu'il n'y a plus de données. Si elle voit un 1, elle sait qu'il est suivi d'une séquence de bits représentant les données.

Cette idée de "tag" revient à placer la longueur au début des valeurs String. Les valeurs peuvent être de tailles différentes, mais le code peut toujours déterminer où elles commencent et se terminent.

Résumé

Au bout du compte, toutes les valeurs doivent être représentées sous forme de bits. Cette page donne un aperçu approximatif de la façon dont cela fonctionne réellement.

Habituellement, il n'y a pas vraiment de raison de penser à tout ceci, mais j'ai trouvé cela utile pour approfondir ma compréhension des types personnalisés et des expressions case. J'espère que cela vous sera également utile !

Remarque : Si vous pensez que cela est intéressant, il peut être amusant d'en savoir plus sur le processus de "ramasse-miettes"). J'ai trouvé que The Garbage Collection Handbook (en anglais) est une excellente mine d'informations sur le sujet !


Source de cette pageSuggérer une modification

results matching ""

    No results matching ""