The Hidden Cost of Making Meaning Machine Readable
Hatched by Emil Funk Vangsgaard
Aug 23, 2026
11 min read
2 views
92%
What if the biggest obstacle in artificial intelligence is not intelligence at all, but the alphabet we force it to use?
A language model does not read a sentence in the human sense. It receives a sequence of numbers. Before any apparent understanding occurs, a prior system has already decided how language should be cut apart, packaged, and represented. A similar decision appears in ordinary programming, where a string may be treated as Unicode text, a sequence of raw bytes, or a template waiting for values to be inserted.
These details often look like implementation trivia. They are not. They reveal a general principle about computation and communication: every intelligent system depends on a representation layer, and every representation makes some meanings easier to preserve than others.
The interesting question is not merely whether a system can process information. It is whether the system’s chosen units of information fit the world it is being asked to understand.
The first translation always changes the problem
Suppose you want to give a machine the sentence “The clock has stopped.” A neural network cannot accept the sentence as a sentence. It needs numerical input, so a tokenizer converts the text into units and maps those units to numbers. Depending on the tokenizer, the result might correspond roughly to pieces such as “The,” “ clock,” “ has,” and “ stopped.”
This seems harmless because the pieces resemble familiar words. But resemblance is not the same as neutrality. The tokenizer has made a theory of language operational. It has decided which recurring sequences deserve to be treated as units, which should be split, and which combinations will be expensive to express.
The same thing happens in a Python program when text is assigned to a string. A sequence enclosed in quotation marks is interpreted as text. A sequence prefixed with b is interpreted as bytes. A multiline value enclosed in triple quotation marks is given a different practical shape. The programmer may feel that all of these are simply ways to write words, but the machine sees different objects with different capabilities and limitations.
A string can represent the character α directly because Python strings use Unicode. A bytestring such as b'Hello \xce\xb1' instead represents encoded data. The visible Greek character and its encoded form may refer to the same underlying message, but they are not interchangeable objects. One is a textual abstraction. The other is a sequence of numerical storage units.
This is the first major connection between tokenization and programming strings: representation is not a transparent window onto meaning. It is an engineering decision about what distinctions to preserve and what operations to make convenient.
Before a machine can reason about information, someone has already decided what counts as a piece of information.
That decision can be excellent for one task and poor for another. A tokenizer optimized around common English fragments may make English compact and efficient while representing Burmese with a much longer sequence of less useful pieces. Likewise, a program designed to manipulate Unicode text may behave badly when handed raw bytes, even if those bytes happen to encode perfectly valid text.
The error is not always in the data. Often, the mismatch lies between the data and the chosen units.
Compression is never just compression
Tokenization is often discussed as a compression problem. If a tokenizer can represent “unhappiness” in one or two units rather than many individual characters, the model can process more apparent language within a fixed context window. This matters for speed, memory, and cost.
But compression has a cultural and structural dimension. A system does not merely shorten all languages equally. It rewards patterns that appeared frequently in the data used to construct its vocabulary. Common English words may receive compact representations because they recur in familiar forms. Languages with different writing systems, morphology, or segmentation patterns may be divided into awkward fragments.
Imagine two travelers carrying the same amount of luggage through a narrow doorway. One traveler owns objects that fit the doorway’s shape. The other must dismantle every object before passing through. The doorway has not become objectively smaller for the second traveler, but the design of the objects and the design of the passage are poorly matched.
That is what representation inefficiency feels like. A language can be perfectly expressive, regular, and information rich, yet become expensive when translated into a vocabulary built around another language’s recurring patterns.
The Python distinction between text and bytes makes this visible in a more familiar setting. If a program treats a UTF 8 encoded byte sequence as though it were a collection of independent characters, it can split a multibyte character incorrectly. A single visible symbol may occupy several bytes, just as a single human concept may be distributed across several tokens. The storage units are real, but they are not necessarily the units a user cares about.
This suggests a useful diagnostic question for any machine learning or software system:
What does the system count, and what does the user count?
A user might count letters, words, names, or ideas. The program may count bytes, code points, tokens, records, or fixed length vectors. Bugs and biases often appear in the gap between these counting systems.
The abstraction ladder and its leaks
We rely on layers of abstraction because raw computation is too detailed for everyday thought. A Python programmer writes "He said 'hello'." and does not need to reason about every memory location involved in storing the characters. The quotation marks provide a boundary that tells the interpreter where the value begins and ends.
That convenience works because the language gives us several compatible ways to express text. Single quotation marks can contain double quotation marks, and double quotation marks can contain single quotation marks. Triple quotation marks allow multiline text. These are small design choices, but they reduce the amount of escaping and restructuring a programmer must perform.
Good abstractions minimize friction between human intent and machine representation. Bad abstractions force the user to think constantly about accidental details.
Yet every abstraction eventually leaks. A string containing non ASCII text may need careful encoding when written to a file or sent across a network. A bytestring may be necessary for a protocol even though the programmer thinks in characters. A formatting operation using %s may substitute values smoothly, until the values contain unexpected characters or types. The apparently simple sentence is always sitting on top of more specific rules.
Tokenization is another abstraction layer with leaks. Humans experience a word as a meaningful unit, but a model may receive several fragments. Humans experience a writing system as a natural medium, but the tokenizer may impose boundaries that are statistically convenient rather than linguistically sensible. The model does not encounter language before tokenization. It encounters the tokenizer’s interpretation of language.
This does not mean that tokens must correspond to words. In fact, subword units can be useful because they allow a system to handle unfamiliar words by composing known pieces. The deeper issue is not whether a unit is linguistically perfect. It is whether the unit is fit for the operations the system needs to perform.
For spelling, character level units may be useful. For syntax, word or subword units may be better. For source code, indentation, punctuation, and delimiters may carry more structural information than ordinary prose conventions. For Burmese or other languages whose segmentation patterns differ from English, a vocabulary designed elsewhere may represent the text inefficiently.
There is no universally correct granularity. There are only tradeoffs made visible or hidden.
Meaning survives through interfaces, not containers
A common mistake is to imagine that information lives inside a container unchanged. We place text in a string, send it through an encoder, convert it into tokens, and assume the same meaning remains intact at every stage. In practice, meaning survives only when each interface preserves the distinctions relevant to the next operation.
Consider a simple substitution template:
name = "Mina"
message = "Hello, %s" % name
The %s marker is not part of the final message. It is an instruction that creates a new textual value by combining a template with another value. The programmer is manipulating not just text, but a small language embedded inside text. The representation has two levels: literal content and control syntax.
Tokenization introduces a similar layering. A token is both a fragment of text and an index into a learned vocabulary. Its identity is not determined only by its visible characters. Context, whitespace, encoding rules, and vocabulary design can all matter. The token is simultaneously a piece of a sentence and an address in a numerical system.
This is why changing a representation can alter behavior even when the displayed text looks identical. Two strings may print the same but differ in normalization. Two byte sequences may decode to related text but follow different conventions. Two token sequences may reconstruct the same visible sentence while giving the model different intermediate units and therefore different computational costs.
A helpful model is to distinguish three layers:
- Surface form: what a person sees, such as a sentence or a symbol.
- Operational form: the units software manipulates, such as strings, bytes, or tokens.
- Semantic task: what must be preserved or inferred, such as meaning, syntax, identity, or intent.
Failures occur when the operational form is chosen without reference to the semantic task. If the task is to display text, a Unicode string may be appropriate. If the task is to transmit a network packet, bytes are essential. If the task is to reason across many languages, a tokenizer optimized for one language may be a poor foundation.
The key is to stop asking whether a representation is correct in the abstract. Ask instead: correct for which task, under which constraints, and for whom?
Representation is also a question of power
Technical systems distribute convenience unevenly. A representation that makes one community’s language compact, searchable, and easy to model may make another community’s language costly. This is not simply a performance issue. It affects who can participate, how much data can be processed, which languages receive strong model behavior, and whose linguistic patterns become the default assumptions of software.
The same asymmetry appears in programming. A developer familiar with encodings, Unicode, and string boundaries can anticipate failures that remain invisible to someone who thinks every character occupies one byte. The system may appear universal while quietly favoring the cases its abstractions were designed around.
This yields a broader principle: defaults are compressed histories of past usage. A tokenizer’s vocabulary reflects the distribution of text used to build it. A programming language’s syntax reflects assumptions about common tasks. A file format reflects the devices and protocols it was designed to connect. When these defaults are exported into new settings, they may look like neutral infrastructure, but they carry inherited priorities.
The practical response is not to reject abstraction or demand a single perfect representation. That is impossible. It is to make representation choices inspectable and revisable.
For language models, this could mean evaluating token efficiency across languages rather than reporting only aggregate benchmark scores. It could mean designing vocabularies with explicit attention to scripts, morphology, and real user needs. It could mean allowing alternative tokenization strategies when the task or language demands them.
For programmers, it means treating text boundaries as part of the design. Know when you have characters and when you have bytes. Test with accented letters, non Latin scripts, combining marks, and multiline values. Do not assume that a value that displays correctly has been represented correctly.
A practical framework for choosing the right units
When designing or debugging a system, use a four step representation audit.
First, name the human object. Is it a word, a character, a document, a code point, a spoken utterance, or an idea? Vague nouns produce vague interfaces.
Second, inspect the machine object. Is it a byte sequence, a Unicode string, a token ID list, or a formatted template? Print or measure the representation rather than relying on how it looks on screen.
Third, identify the costly mismatch. Are some languages consuming many more tokens? Are characters being split incorrectly? Is a formatting marker being confused with literal content? Find the place where the system’s units stop matching the task.
Fourth, optimize for the real objective. Compactness may matter for a context limited model, but clarity and fidelity may matter more for translation. Byte level control may matter for a protocol, while Unicode level operations may matter for user facing text. The best representation is task dependent.
A small experiment can reveal more than a general assumption. Take the same sentence in several languages and compare token counts. Encode a string containing Greek, accented Latin, and an emoji, then inspect its bytes. Insert values into a template that includes quotation marks and line breaks. These tests turn invisible boundaries into observable facts.
Key Takeaways
- Treat representation as part of system behavior. Tokenizers, encodings, and string types do not merely transport meaning. They shape what the system can process efficiently and reliably.
- Measure across cases, not just averages. Test multiple languages, scripts, symbols, and text lengths. Aggregate performance can conceal severe inefficiency for particular users.
- Separate text from bytes. Use Unicode strings for textual operations and bytes for storage or protocols when appropriate. Convert deliberately, with an explicit encoding.
- Choose units according to the task. Characters, subwords, words, bytes, and tokens each preserve different distinctions and support different operations.
- Audit defaults for inherited bias. A convenient representation often reflects the data and users that shaped it. Ask who benefits from its compactness and who pays for its assumptions.
The deepest lesson is easy to miss because representations are designed to disappear. When an interface works, we forget that a translation occurred. We see a sentence, not the token boundaries beneath it. We see a character, not the bytes that store it. We see a formatted message, not the substitution rules that assembled it.
But intelligence, whether biological or artificial, never encounters meaning without mediation. It encounters signals organized according to a scheme. Some schemes preserve distinctions beautifully. Others make certain worlds look fragmented, expensive, or strange.
The future of intelligent software may depend less on giving machines more information than on giving them better units in which to receive it.
The important design question is therefore not only how much a system knows. It is what the system is allowed to recognize as one thing. Change that answer, and you may change the cost of language, the visibility of a pattern, and the boundaries of what understanding can become.
Sources
Hatch New Ideas with Glasp AI 🐣
Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)
Start Hatching 🐣