If you’ll humor my slight digressions, you can learn:
- Why is Left Bank Ukraine in the East not West?
- Why are Upper German varieties spoken in the South and Low German in the North?
- Why is Belarus, i.e. White Rus, white?
- Why did the Ashkenaz, a lost, ancient Semetic kingdom, move to France, Germany, then Poland/the Pale of Settlement (and even Crimea and the Caucasus)?
- Why did Japanese, Korean and Vietnamese polities claim to be the true China?
- Why do Greeks call themselves Ρωμηός (Romans)?
- Why don’t these make sense to us moderns?
Why coupling, of course. There’s little more software engineers obsess about than coupling. 1, 2, 3, 4, 5, 6, 7 In computer and human languages, tragically, we must couple.
In a mythical ur-language or program, perfect, yet unblemished by the world, every concept might map to its own sign (word, symbol). But seeing something new, our caveman or programmer (both the selfsame Grug) must map this ineffable discovery to some sign and grow the language, to tame it with understanding and communicate with the others. Though he can coin a fire new sign (or accidentally copy over an existing sign), today (when intentional) he’d more often wield metaphor (polysemy). As an example, to talk about the internet, we leveraged many water metaphors: surfing, streaming, phishing, downstream/upstream, TCP flow control, ports…
Now just wait one minute! Programming languages are artificial! You can’t talk about them like natural, spoken, human languages!
But most European standard languages were intentionally created in the last few hundred years (deciding which grammar to use and coining tens of thousands of words) by greats like Joachim Campe and Philipp von Zesen who coined modern German words for ancient, author, university, project, address, spelling etc. Vuk Karadžić, Ljudevit Gaj, Bogoslav Šulek etc. did similar for Serbo-Croatian. In Finnland, Mikael Agricola, then Antero Warelius and August Ahlqvist, in Hungary, Ferenc Kazinczy and Dávid Baróti Szabó enriched their tongues! For the Czechs Josef Jungmann and Josef Dobrovský etc. etc. It was only a short leap from here to bringing Hebrew back to life, creating a brand new language like Volapuk, Esperanto, Javascript or Lambda Calculus (though Lisp was discovered).
When Campe & von Zesen created the modern German vocabulary and Zamenhof chose Esperanto’s lemmas, when Iverson named the reduce function and Grug wrote a CLI, when Vostokov created the name Svetlana and Fielding came up with REST APIs, they were performing the same ritual! They stretched prior mappings of sign to meaning. Arthur Köstler, investigating humor, invention & discovery, dubbed this “bisociation”, because it associates two metaphors of “matrices of thought” together. We’re not reasoning, but analogy machines, thinking by resonance, not deduction. Subconsciously, we name this conceptual blending.
Einstein’s space is no closer to reality than Van Gogh’s sky. The glory of science is not in a truth more absolute than the truth of Bach or Tolstoy, but in the act of creation itself. The scientist’s discoveries impose his own order on chaos, as the composer or painter imposes his; an order that always refers to limited aspects of reality, and is based on the observer’s frame of reference, which differs from period to period as a Rembrant nude differs from a nude by Manet. - The Act of Creation
There’s the hitch: Languages change. After all, Italians no longer speak Latin and few readers would know what eoh, mearh, blanca, wiċġ mean. Their synonym hors is familiar, though hās' symbol changed and shares its sound: hoarse. When you couple the right side of a human to a river bank or political group and share its symbol with the very concept of correctness, what happens when their complected meanings all slide around over hundreds of years? Confusion!
‘Complect’ is an archaic word, … means to turn something simple into something complex … ‘think of four strands of yarn that hang independently—that’s a simple system. Now take those same four strands of yarn and braid them together. Now you’ve complected them.’ … In the simple system, you can change one string independently without having to touch the others … in the complected system, when you want to make a change to one strand of yarn, you are forced to change the other three strands, too. In fact, for many things you may want to do, you simply cannot, because everything is so knotted together! - The Unicorn Project
Forward into History!
Jerry-rigging cardinal directions onto your language isn’t easy. To our modern sensibilities, after Ptolemy’s eventual victory, with North at the top, left would be West. But reckoning with rivers, it makes sense to base things off of current: up and downstream, left and right. The left bank can be West (on the Rhine) or East (on the Dnieper). When reckoning with mountains, up simply means higher! But why use new symbols for directions when you have perfectly good colors? White Russians and White Croats in the North-West, Green Ukraine out East on the Pacific, the Black Sea in the South (conveniently, the Turkic “kara” was both the symbol for black and North!) In China too, the Black Dragon River lies in the North while white means West. (Turks call the Mediterranean the White Sea.) China’s Yellow River and Mountains were once considered central (and the Golden horde was between the other Mongol hordes).
Now, what if you move to a new place? Why even bother with new or local names when you can simply use one you already know (like New York, New Jersey or not even bother with “new” and make a 100 Santa Fes in the New World)?
Let us take a classic example from European Jewish history. Around the year 1000 AD, a number of Jewish culture areas in Europe were crystallizing, each referring to itself by a name usually recycled from the Hebrew Bible. On the Iberian Peninsula it was Sepharad; in the Slavic lands Knaan (Canaan); and in the Germanic and adjacent territories of central Europe — Ashkenaz . The Jewish residents in these lands were the Ashkenazim (singular Ashkenazi ). Well, European history took its course. The Crusades and numerous other manifestations of medieval religious intolerance resulted in massacres and expulsions; as a result, over a period of generations, Ashkenazim were continually resettling eastward to the then more tolerant Baltic and Slavic lands, particularly Poland and Lithuania. And, guess what, their new home in the east just “became the new Ashkenaz,” and they were still the Ashkenazim, although their neighbors now spoke Slavic and Baltic languages rather than Germanic, and they were, to speak spatially, in a “different place.”
Then there are many cases where a Jewish geographic term more or less represents an erstwhile state of geopolitical reality. Over the centuries, the militarily established borders keep changing or the original state might cease to exist altogether, but this changes zero for the stateless culture’s knowledge and transmission to new generations of its own world view of the geo-cultural terrain. As it happens, the best known case is Lita (Yiddish Líte ), which means “Lithuania” and whose Jews are known as Litvaks (Yiddish lítvakes ). The borders of Lita are relatively congruous with those the Grand Duchy reached in the days of Grand Duke Gediminas (Gedymin, ±1275 — 1341), and it is an irony of history that Lithuanian Yiddish is the only one of its many languages common to roughly “all and only” that territory. That made for the once-famous 1919 quip by diplomat Max Soloveitchik, negotiating on behalf of Lithuania with Soviet Russia, that he would respectfully like to ask for the ceding to Lithuania of all lands the Jews consider to be “Lita” (the Russian diplomat was called Mr. Yoffe, and they held this particular conversation in Yiddish). - Dangers of Modern Cartography - Dovid Katz
China and Chinese has many names: 9 states (九州), Middle Country (中国), Flourishing and Grand (华夏), China (支那, offensive today!), all Xias (诸夏, perhaps similar to “all Ruses” for the Eastern Slavs), under Heaven (天下), Magnificence 华… Some stress the physical place, others a civilized nature or importance. But what happens if the people and place are no longer “civilized”? Well, the neighboring rulers in (what’re now) Korea, Vietnam & Japan may call themselves Magnificence or (little) Middle Kingdom instead, asserting that they now hold the mantle of civilization.
To illustrate the process with animal algebra, given 3cat + 3dog + 3bird we may factor out the common part 3 and restructure ab+ac+ad to a(b+c+d) or 3(cat+dog+bird) by coupling them together. If our assumption is correct that there will be the same number of each animal (e.g. 4 of each) we have successfully simplified! And compression is comprehension! But were that a mere coincidence, we’d have complected the system by coupling ill-fitting parts together. Representing 4 dogs requires representing 4 cats and birds! But thankfully, this is not often the case in human languages! People do understand terms like Left Bank Ukraine.
In a sense, these terms “close over” and preserve old senses, old versions of language, most evident in fossil words like “fro”, “eke”, “kith”, “bated” only used in a single set phrase: “to and fro”, “eke out”,“kith and kin”, “with bated breath”. We see it with grammar too: hell hath no furry preserving the archaic hath for has.
Conlangs, DSLs and APIs
Cool, but how does this help me? I just failed an interview. The question the guy asked was so vague! “What are the common pitfalls of API development?”
You can intentionally craft your API as a language! A “technical” answer would say Go has contexts for this, which cancel the whole chain if need be. Racket has continuations, which preserve whole stack frames so you can restart or reroute a computation for some reason. But that’s the wrong paradigm for this article; we can do so much better! You’re on a website right now, with a url: https://alexalejandre.com/languages/complecting-language-and-geography
On this static site, I just quasi-expose the file system, while some sites with dynamic features are just vague gibberish like item?id=20164657 or 322719?context=8#context or /watch?v=fxqIrTLRBoE&list=PLBCINLbRAJXk9lvxxS0nJ2CYAXPRO4CQG&index=2, but could they do better? If a url does not represent a simple location, but instead one of many operations like calling a database or transferring money, how can you compose them in a logical way? How can you to intuitively know which are which without constantly checking the documentation? Avoiding gibberish, we can use English-esque grammar or make our own:
noun/verb/nounlocation/noun/verbverb/noun/details
Perhaps your scheme even allows for plurals, for batch jobs, with every request sharing a structure (even if unfilled):
give/me/post/s/from/last-yeargive/server/data/to-uploadgive/you/post/newgive/you/post/edited
English has: noun verb indirect-object direct-object (I gave the dog a treat) or noun verb direct-object --to indirect object (I gave a treat to the dog). We can use adverbs perhaps using ? keywords etc. For concrete examples, let’s look at CLIs:
For (name) veb noun details, kubectl get pods and kubectl describe -n namespace resourcetype/resourcename. On the other hand, docker image ls or docker node update nodeID... use (name) noun verb… At first, (name) verb noun seems clearer, subject verb object like English! But is it? Which is better: exercise fetch dog --ball or exercise I walk dog --in park? (Perhaps we should name this CLI “ToExercise”!) Inspired by languages with cases like Russian or Turkish, you could do (the equivalent of): ToExercise :subject I :verb walk :object dog :indirect-object grandma :in park :at 7 or ToExercise :nominative I :what throw :accusative dog To push it further, in Gleam, you can use filler to write: replace( in string: "the cat is black", each pattern: "cat", with replacement: "dog") or just replace(in: "the cat is black", each: "cat", with: "dog"). Here’s a case study:

But what about /details and other flags? Why not give your API a quickly cargo build to skip some optimizations and compile faster or cheaply store --on cloud for cheaper cold storage? Coupling yourself to English may seem elegant, but it’s a false, complecting hope. After all, what API would ever use conjugation? I walk dog but he walks dog?! For Esperanto, Zamenhof made a single present tense verb ending -s and an object marker -n. Even though it’s different (not immediately intuitive to an English speaker), a transparent system is easier (though ToExercise I walk --s dog --n is terrible! Suffixes don’t work as flags/keywords.)
Non-linguistic concerns matter too. If your nouns support all verbs, verb first makes more sense and vice versa. Verb first allows you to chain objects (compare Lisp (add 1 2 3 4 5) to 1 + 2 + 3 + 4 + 5.)
(Why did I choose /languages/ not /programming/ before the title? Beats me!)
But Languages, Requirements & Worlds Change
If your nouns support all verbs
PRecious few are the projects where we can know for certain (control our environment or perfectly control invariants). When the world changes (whether through innovation or disaster), our language expands for us. But change (even in the very symbols and grammar) jumbles things together too! When our users want new features or governments pass regulations, when library maintainers pass breaking changes or new hardware comes out, we must quickly build on top of once stable foundations while undermining them too. All production code bloats and rots with time. With precious effort refactoring, we can delay the decay but never evade it. Like refactors through a code base, genuine innovations and paradigm shifts (like memory safety, functional programming, pattern matching) spread in waves.
Although I equivocate them together, neither linguistics nor computer science present a convincing method or calculus (to measure change). Vogt laid Swadesh & Starostin’s glottochronology to rest (although lexicostatistics holds some promise.) Drift and shearing layers are also of interest.
Cohesion is the positive side of coupling, where similar things (should) change together. Returning to our example of 3(cats + dogs + birds), perhaps there are little buggies holding one of each; if our simple form is true, we can understand complex systems and relationships more easily! (What aspects of human language, register, jargon etc. best correspond to modules and name spaces?) Connascence presents a taxonomy of coupling types and advice for “fixing” them.
Maybe it does not make sense to talk about some thing called “software architecture”. Instead we should talk about “structural decomposition of systems”, “decision documents”, “behavior descriptions” or whatever else an architect might produce. None of these is necessary to exist when we build large systems although they might help. Maybe what we call “architecture” is just pareidolia. - qznc
Theoretically, a perfectly fitting, maximally efficient system will experience the greatest breakage when change occurs (compare overfitting). Human language is full of error-correcting redundancies while programming languages are very brittle, a single modified character may stop compilation(!), so changing one part of a program may require many changes elsewhere while adding a new world or changing a spoken phoneme’s phonetic realization may not necessarily impact anything else.
Human languages recognize common sound changes. 8, 9, 10, 11
Besides a framework of language/code change, I seek a morphology of morphologies, to understand where 2 systems or notations don’t correspond but:
- have 1 point which requires judgement or a rule to disentangle (english has 2 types of present, russian 1)
- have a whole system which doesn’t fit or encodes totally different information, not carried in the other (rus makes past from gender, english doesn’t)
what are these “loss zones” in programming languages, DSLs etc.? How to deal with them?
unsorted verbiage
summary: “Diachronic (historical) linguistics and software engineering have a lot to teach each other.”
We have fossil words remaining only in set expr But we also have fossil concepts, closing over ? Modern worldview api concepts with archaic forms
This illustrates how coupling (and merging superficially similar implementations) (across shear layers!) …leads to conceptual closures (Bisecting is coupling, inviting impedance mismatch … Stretching or closing over shear layers) (…but for creativity, you must bisect! Unless creating totally new names. Elements of Clojure notes that new names, less intuitive, are slower to learn but also less misleading (if significantly different from their symbols shared meanings.))
In functional programming, closures help us with bookkeeping, maintaining their own values and reducing confusion (e.g. avoiding shared memory causing unexpected effects). But conceptual closures persist/suspend perplexing version differences
order of ideas / structure
In software, we obsess about coupling. programming and human languages are both languages hide: - yes, they really are! (explain to language lovers why this is so: grammar, vocab, encoding… philology/symbology?) - human languages have various linguistic/philological tools like: - etymology - language learning books (apply a colloquial style text+vocab+grammar to programming, with a requirement/problem, the func/lib vocab then …domain grammar? and then exercises how???) - algorithms or patterns qua idioms? Hmmm …idiom are domain related, e.g. working with money do this for security or accounting fidelity? there are artificial languages too (simple english, hebrew revival, conlangs! …math symbols like mandarin symbols!)
conlang and api design? the stuff i told shwitz about cli wording with verbs etc. Arthur Köstler’s bisection - mapping new topics to existing idioms (symbols) we humans are not reasoning machines but analogy/metaphor machines/pattern matchers! (elements of closure has stuff about modeling, with gravity etc.) historically, humans coupled new concepts to existing symbols/metaphors - i.e. the top examples! when the original meanings drift (across shearing layer), the mapping to other meanings became stranger: fossil words etc.
languages change according to??? the world changing (tech, geopolitics etc.) and mindsets shifting? programs similarly changes according to new requirements, changes in the world etc. scholars have tried to measure language change in these ways, which can inspire how to measure program change/code rot?