Korean as a Concatenative, Stack-Oriented Language
Korean is an subject-object-verb (SOV) language, which shares the a similar structure to Reverse Polish Notation (RPN) used in concatenative, stack-oriented computer programming languages such as Forth and Factor. By this, I mean that SOV and RPN both have operators (i.e. verbs and adjectives, in the case of Korean) in the final position, which take the proceeding subject and object as arguments. In other words, SOV could be seen as (S,O)V where S and O are arguments to V. Similarly, nouns can take adjectives or even relative clauses as arguments, verbs take adverbs, particles take nouns, verb endings (어미) take verbs, etc. Taken further, this can be visualized as a concatenated list of values being pushed on and off of a stack like stack-oriented computer languages do when they are executing programs. I believe this stack analogy may be able to help some Korean (and other SOV) language learners better mentally parse sentences while reading. This is surely not a perfect analogy and I do not claim this to be an original idea, but it was simply something I noticed when learning about the Factor language and drew parallels to the way Korean is structured.
Brief Introduction to RPN and Stacks
Like SOV languages, RPN puts the operator in the postfix position. This means that instead of saying 2 + 3, one would say 2 3 +. Taken further, instead of writing (2 + 3) × 11 + 1, one would say 2 3 add 11 mul 1 add as a concatenated list of symbols and operators. Since this can become cumbersome to keep track of mentally, it can be represented on a stack where inputs are pushed onto the stack and consume any existing values as arguments:
Input
2
3
add
11
mul
1
add
Stack
2
3
5
11
55
1
56
2
5
55
This is only meant to be a brief introduction, but Wikipedia goes into more depth with this example. Make sure you understand this concept before continuing onto the Korean examples below.
Basic Example
This is a basic example showing a simple sentence with a subject, object, and verb:
Original
내가 밥을 먹다. (I eat rice.)
Lexing
Breaking the original sentence into concatenated, parameterized morphemes:
나 (N)가 밥 (N)을 (S,O)먹 (V)다.
Notice how not only does the verb have parameters, but also the particles and verb ending. I’m viewing the particles as almost like optional, type-safe wrappers to mark the subject and verb. Without them, the types can be inferred, but they add clarity a sort of type-safety. The verb endings are also parameterized in a similar way, but these take verbs and return new verbs for multiple levels of chaining (i.e. agglutination).
Parsing
Moving left-to-right, each morpheme is added to the stack. Some morphemes can consume morphemes already on the stack as arguments similar to the math example above.
Input
나
(N)가
밥
(N)을
Stack
나
(나)가
밥
(밥)을
(나)가
(나)가
Input
(S,O)먹
(V)다
Stack
((나)가, (밥)을)먹
(((나)가, (밥)을)먹)다
Relative Clause Example
This is a slightly more complex example showing how relative clause is treated, which is often one of sources of difficulty for Korean learners, especially those coming from SVO languages like English. This also includes past tense and a polite verb ending.
Original
어제 먹은 음식이 맛있었어요. (The food I ate yesterday was delicious.)
Lexing
어제 먹 (V)은 음식 (N)이 (S)맛 (S)있 (V)었 (V)어요.
Parsing
Same as the example above, but some morphemes consume optional parameters. They are not part of the signature shown in the lexing because they are not required, and listing every possible optional parameter would be impractical. An example of this is a verb being described by an adverb. A verb can certainly take an adverb, but it is not required. A transitive verb on the other hand would be required to take an object, even if it might be an implied object.
Note how the relative clause 어제 먹은 simply acts as a descriptor to 음식. This is a simple relative clause for brevity, but it’s easy to see how this could be expanded.
Input
어제
먹
(V)은
음식
(N)이
Stack
어제
(어제)먹
((어제)먹)은
(((어제)먹)은)음식
((((어제)먹)은)음식)이
Input
(S)맛
(S)있
(V)었
(V)어요
Stack
(((((어제)먹)은)음식)이)맛
((((((어제)먹)은)음식)이)맛)있
(((((((어제)먹)은)음식)이)맛)있)었
((((((((어제)먹)은)음식)이)맛)있)었)어요
Conclusion
As mentioned above, this is only scratching the surface, but it could be taken further although there are surely holes in places like conditionals, topics, and contextual information. For example conditionals (e.g. -면) probably need to be treated as infix operators and topics and contextual information could probably be envisioned living in their own stack alongside the main sentence stacks shown above.
I also considered creating an extension to Factor (or perhaps a whole new programming language) that was based on Korean keywords following this principle. It’s not really a task I would like to take on now, but perhaps someone would like to run with the idea on their own.
From a code example titled 「九十九瓶啤酒」 (99 Bottles of Beer). It is indeed a cat lang, or at least stack-based.
吾有一言。 ; I have a word
曰「「春日宴。」」。 ; Is "A Spring Festival Banquet"
書之。 ; Write it (to console)
有數九。 ; Is number 9
名之曰「酒數」。 ; Name it "Wine Count"
Another program generates a tree with flowers, using a couple of methods defined as a chain of curried functions. That sure looks like a pipeline, or “train” as it’s called in APL.
; Draw tree method = Paper => East => South => Length => Roughness => Direction => Change Direction
畫樹法 = 紙 => 東 => 南 => 長 => 粗 => 向 => 向變 => { ... }
; Draw ground method = Paper => Left => Right => Bottom => Top => Step
畫地法 = 紙 => 左 => 右 => 底 => 高 => 步 => { ... }
Those who read French may profit from these slides from a (non-recorded) talk on programming languages that are not based on English, including a section on Wenyan, and/or from a recorded talk by the same author (Baptiste Mélès) on roughly the same topic.
I’ve been wondering this too, several times, as I explore the array languages, mainly J. Don’t think I am experienced enough yet to answer, as I’ve only done a very little bit on the cat side. The experience of “weaving” described and the geometric part does make me wonder…
Point-free programming (“tacit programming”, as they call it in J) feels somehow very nice, you feel like you’re directly manipulating the computational thing itself, directly doing the algorithmic thing directly, in some sense, rather than talking about the algorithmic act, or “setting it up”.
Conor Hoekstra (code_report, or something similar, is his yt channel) does very nice videos where he goes through the solution of some problem showing a load of solutions, including often in five or six array languages, as he’s into array languages. They’re very interesting. I don’t know if you’ll get that feeling I’m attempting to describe in the previous paragraph, but you might.
He made arraybox too, which I would recommend for seeing the glyphs alone. Do C-h for the keyboard shortcuts to pop up, C-k for all the beautiful glyphs:
The array languages in general are very good for their interactive playgrounds with nice labs and tutorials, I know Dyalog has ones that look nice, but the ones I can personally vouch for are the J ones:
If you go to Examples, click on “Plot”, then click “Run” over on the top of the Edit pane, you’ll see some surprisingly excellent plots and can investigate the code. Or if you hover over “labs” you might very well see something that interests you there!
That J Playground with the Plot example, it’s a joy to see it in action. Now I get how computational notebooks like Jupyter and Clerk evolved from such conversational interfaces. From APL on the teletype machine to the terminal command line, REPLs, editors, and integrated environments like Emacs and Glamorous Toolkit. They enable building programs incrementally as a conversation between human and machine, through interactive live coding sessions.
Especially I like how the text of the source code mixes freely with non-textual media like symbols, matrixes, tables, images, graphs. It’s similar to live music programming systems like TidalCycles pattern language, Strudel, Max, Pure Data, and a recent one I saw, loopmaster.
Every node in the syntax tree is interactive in some way, adjusting values with sliders and knobs, visualizing waves and notes, hover on names to show hints or inline documentation. “Semantic density” is a phrase I learned from APL, and I see how live coding benefits from a dense interface, fewer key strokes to express ideas and navigate the score as it’s being written and performed.
Apparently many of these live coding systems are from a family of languages called MUSIC-N.
MUSIC-N refers to a family of computer music programming languages descended from or influenced by MUSIC, a program written by Max Mathews in 1957 at Bell Labs.
Dataflow languages model a program as a directed graph of the data flowing between operations. Functions or “objects” are linked or “patched” together in a graphical environment which models the flow of the control and audio.
With Lisp I think of programs as trees, lists of lists, but of course trees are a subset of graphs. I suppose that’s where a visual programming interface can have a unique advantage over textual code editor, by being able to represent and directly manipulate a graph of nodes and links.
A key innovation in Pd has been the introduction of graphical data structures. These can be used in a large variety of ways, from composing musical scores, sequencing events, to creating visuals to accompany patches or even extending the GUI.
Pd is designed to offer an extremely unstructured environment for describing data structures and their graphical appearance. The underlying idea is to allow the user to display any kind of data he or she wants to, associating it in any way with the display.
To accomplish this Pd introduces a graphical data structure, somewhat like a data structure out of the C programming language, but with a facility for attaching shapes and colors to the data, so that the user can visualize and/or edit it. The data itself can be edited from scratch or can be imported from files, generated algorithmically, or derived from analyses of incoming sounds or other data streams.
Bimodal programming is the interaction paradigm in which a programmer freely intermixes text edits with direct manipulation of output in order to craft a program.
As originally defined by Ben Shneiderman, direct manipulation is the workflow characterized by “visibility of the object of interest; rapid, reversible, incremental actions; and replacement of com- plex command language syntax by direct manipulation of the object of interest”.
..We answer the question above with the following thesis: Non-trivial vector graphics programs and functional data structure manipulation programs can be constructed by output-based interactions in a bimodal programming environment.
One of the chapters is about “Tiny Structure Editors”.
It’s an experiment in generating user interface elements automatically from algebraic data types. Editing the code changes the UI, and vice versa.
There’s an insight here I’m starting to understand about the value of having malleable views and interfaces into the same underlying data structure, including functions and programs, as well as file systems, databases, websites, operating systems..
The other day I saw a project with an idea to provide a single unified API to all running desktop applications and their user interfaces.
OculOS is a lightweight daemon that reads the OS accessibility tree and exposes every button, text field, checkbox, and menu item as a JSON endpoint. It works as a REST API for scripts, testing, and CI/CD — and as an MCP server for AI agents.
Accessibility tree is a way for an application to model its user interface, the controls and all of its public properties and states, for assistive technology users to interact with it. I’ve heard it called a parallel information architecture, since it doesn’t necessarily map one-to-one with what’s rendered visually.
Assistive technology, in this context, refers to a third party application which augments or replaces the existing UI for an application. A well-known example is a screen reader, which replaces the visual UI and pointer-based UI with an auditory output (speech and tones) and a keyboard and/or gesture-based input mechanism. Many assistive technologies interact with a web page via accessibility APIs, such as UIAutomation on Windows, or NSAccessibility on OS X.
These APIs allow an application to expose a tree of objects representing the application’s interface, typically with the root node representing the application window, with various levels of grouping node descendants down to individual interactive elements. This is referred to as the accessibility tree.
If all desktop applications, including the browser itself, expose an accessibility tree to the OS; and all websites expose an accessibility tree automatically built from the DOM (document object model).. What would a world-wide tree of all accessibility trees look like? I suppose that’s where the semantic web was meant to go.
I have a dream for the Web in which computers become capable of analyzing all the data on the Web – the content, links, and transactions between people and computers. A “Semantic Web”, which makes this possible, has yet to emerge, but when it does, the day-to-day mechanisms of trade, bureaucracy and our daily lives will be handled by machines talking to machines. The “intelligent agents” people have touted for ages will finally materialize.
– Tim Berners-Lee in 1999, quoted in the book Weaving the Web
Live-coding music languages are typically dataflow-oriented, they say. Like the loopmaster language, it has a pipeline operator to express the flow of data.
The operator |> is the heart of this language. It chains operations left to right. You can chain as many operations as you want. .. Make a sawtooth wave, run it through a lowpass filter, send to output.
saw(440) |> lp($) |> tube($) |> out($)
It sure looks concatenative, though the language syntax itself isn’t.
[In the concatenative style of programming,] a function is defined as a pipeline, or a sequence of operations that take parameters from an implicit data structure on which all functions operate, and return the function results to that shared structure so that it will be used by the next operator.
ArrayBox is a nice simple interface to try out array languages. From the source repository, it says it runs BQN, Uiua, J, Kap, and TinyAPL in the browser using WebAssembly, and APL by running Dyalog on the server. I see what you mean about the author @code_report, a research scientist at Nvidia, whose YouTube channel has videos on interesting programming topics including 1 Problem, 7 Array Languages.
Girard’s linear logic can be used to model programming languages in which each bound variable name has exactly one “occurrence”—i.e., no variable can have implicit “fan-out”; multiple uses require explicit duplication. Among other nice properties, “linear” languages need no garbage collector, yet have no dangling reference problems. We show a natural equivalence between a “linear” programming language and a stack machine in which the top items can undergo arbitrary permutations. Such permutation stack machines can be considered combinator abstractions of Moore’s Forth programming language.
My fascination with catlangs is their potential to be quick to learn for non-programmers:
Strict left-to-right order of computation & data flow. (The reading orders for infix/prefix are something we tend to take for granted, but actually have to be taught at some point.)
A clear understanding YOU can grow the language by adding words. To me, what justifies calling a language “language” is neither its builtin vocabulary, nor its grammar, but only the fact you can grow it.
Programming languages with more “syntax” tend to have a more constrained 2nd-class feel e.g. “you can define functions but not operators nor statements”. Now, actually adding control structures to say Forth involves deeper wizardry than I can expect from beginners ;-), but I consider the liberating “open-world” feeling of everything being on equal footing to be valuable in itself.
I’d rate Snap! and Tcl on similar level of language malleability.
Natural REPL use — can just press Enter at any point and inspect intermediate data.
But it could and should be more than a REPL! Brief was great refactoring demo. Should allow user to go back and edit code. Should directly visualize stack at intermediate points. @akkartik’s demo was quite neat. here is my WIP prototype…
For these purposes, I don’t care for Forth’s machine sympathy and radical simplicity. I don’t want raw memory management and stack elements that are exactly one machine word.
I’d want something high-level, like Factor, only I don’t know, friendlier? I believe we’ve not seen peak concatenative user-friendliness, yet.
An inviting intellectual puzzle, the way it’s presented mysteriously with little explanation. I couldn’t resist learning some Hebrew characters and words because I wanted to make sense of what’s going on in this strange microworld of a programming environment.
(An idea I sometimes mull over: an educational strategy of presenting the learner with an incomplete thing, to provoke the natural tendency of the mind to seek balance, harmony and resolution - similar psychological dynamic as Cunninham’s Law where people can’t help but “correct” you and give their answers.)
Reading and writing in the right-to-left direction is challenging for my brain, like trying to fight a habit I wasn’t aware of before. It reminds me of practicing the piano, teaching the fingers of left and right hands to move independently and with equal fluency. I’d never tried to read and write Hebrew on the computer before, navigating with left/right arrow keys, also backspace and delete, they go the opposite direction than expected. It gets harder when Hebrew words are mixed with English, the cursor going in a single line can change direction, then after the word, it flips back.
In Japan - and as far as I know China and Korea, traditionally - the language is mainly written in vertical lines from top to bottom, progressing in right to left direction. Particularly for books and hand-written manuscripts. A theory is that it may have been due to centuries of using scrolls (“a roll of papyrus, parchment, or paper”) as a communication medium, where it would have been natural for a right-handed person to hold the scroll in the left hand, and gradually pull the paper out toward the right, for the eyes to scan the writing from right to left.
..Mhmm so the eyes act like a cursor of the visual interface of writing, indicating the current position for user interaction. Or like a program counter that points at the current instruction being executed: a letter, a word, a sentence. Reading is like performing as an interpreter, parsing the written language as code, and running the words on the virtual machine that is your imagination!
A writing system for natural language corresponds to the “stored program” in a univerval Turing machine. And the eyes, or the finger, of the reader moving the cursor of attention is the “head” positioned at the current point on the tape storing the program.
The machine operates on an infinite memory tape divided into discrete cells, each of which can hold a single symbol drawn from a finite set of symbols called the alphabet of the machine.
It has a “head” that, at any point in the machine’s operation, is positioned over one of these cells, and a “state” selected from a finite set of states. At each step of its operation, the head reads the symbol in its cell. Then, based on the symbol and the machine’s own present state, the machine writes a symbol into the same cell, and moves the head one step to the left or the right, or halts the computation.
For the web and digital documents, Japanese is often written horizontally for convenience, for better compatibility with Latin alphabet used predominantly on computers. It flows the same direction as English, left to right (LTR); however, during the Meiji period, there was a time when it was common to write the other way, horizontally from right to left (RTL) like Hebrew and Arabic. (Also, I learned, other languages using Arabic script like Persian/Farsi, Urdu, Kurdish, Uyghur, Pashto et al.)
(Bank of Japan silver-convertible one Yen note from 1885 shows a mixture of horizontal right-to-left lines, vertical top-to-bottom lines, and English writing in horizontal left-to-right. And a stamp with letters going in a circle. And check out the god of wealth, I think, carrying overflowing bags of rice - and three little mice enjoying the crumbs, how cute!)
For centuries the Japanese language had been written top-down and right-left, following the Chinese writing system. After World War II, there was a general rebuilding of the nation, including a major reform of the language with a shift toward horizontal left-to-right writing and simplification of kanji characters (which some still consider a cultural loss). Around the same time (1949~), the newly established People’s Republic of China also implemented language reforms, with a shift from vertical to horizontal, and right- to left-oriented direction.
This political dimension of language, writing, and notation - I wonder who in history have thought and written about the subject. Umberto Eco. Jorge Luis Borges. Hakim Bey. Noam Chomsky? Hermeneutics? Maybe semiotics and that French school (as in cardumen, a shoal of fish, un banc de poissons) of thinkers like Foucault, Derrida, Baudrillard, Deleuze. I wonder why humanity lost (or had never found) the universal utopian language of Eden, where everyone - even animals, plants, stones and stars - sympathetically communicate and understand each other, to live and cooperate as a collective organism in a mutually beneficial symbiosis, instead of a babble of a hundred different languages, countries, religions. Aren’t we one as a living planet, waking up as a child-god in the vastness of the universe? How did the Hoop of the World, as Black Elk called it, get broken and how do we mend it?
And while I stood there I saw more than I can tell and understood more than I saw; for I was seeing in a sacred manner the shapes of all things in the spirit, and the shape of all shapes as they must live together like one being. And I saw that the sacred hoop of my people was one of many hoops that made one circle, wide as daylight and as starlight, and in the center grew one mighty flowering tree to shelter all the children of one mother and one father. And I saw that it was holy.
..As an aside, I found this strange-looking tree by chance: Yanghui Triangle. From Suanxue Qimeng (算學啓蒙), an elementary textbook on mathematics written in 1299. Ohh I see, it’s a predecessor of Pascal’s Triangle! I’ll check it out later.
Sefirot (Hebrew: סְפִירוֹת) meaning emanations, are the ten attributes in Kabbalah, through which Ein Sof (“infinite space”) reveals itself and continuously creates both the physical realm and the seder hishtalshelut, the metaphysical Four Worlds, in a descending chain of existence.
Ein Sof (אֵין סוֹף) meaning infinite, literally “There is no end.”
The mother of all things, a fertile emptiness and infinite source of creation. It all starts with 0 (zero), a circle, a womb. She’s only implied in the diagram of the Tree of Life, for she is beyond representation, names, concepts, categories, and systems of mere mortals.
At the top of the tree is Kether, “the crown” or “I am that I am.” It’s 1 (one), a phallus proud of his own existence - please excuse my Greek. Then existence divides into 2. The primordial unity is broken into a duality of light and dark, good and evil, left and right.
The Function of the Heart shows a way we heal the whole. From the start point at (0, 1) the lines diverge, a fork in the road for the momentum of individual will - but soon enough they attract and find each other, to meet again at (0, -1) like lovers going home.
Bagua is a set of symbols from China illustrating the nature of reality as made of mutually opposing forces. It is a group of trigrams—composed of three lines, each either “broken” or “unbroken”, which represent yin and yang, respectively. Each line having two possible states allows for a total of 23 = 8 trigrams, whose enumeration and characterization has influenced the history of Chinese philosophy.
In the I Ching (“Book of Changes”), a Chinese text on divination and cosmology from 1000-750 BC, two trigrams are stacked together to create a six-line figure known as a hexagram. There are 64 possible permutations, whose hexagrams and their descriptions make up the book.
A popular theory why traditional Japanese writing flowed the way it did: the horizontal right-to-left style is the same as the vertical flow flattened to a single character per column in a long linear row.
To illustrate, the above image is the first page of 「方丈記」(Hōjōki) published in 1647.
It starts, “The flow of the river never ceases..”
行
く
川
の
な
が
れ
は
絶
え
ず
し
て
By reducing the column height to a single character, it’s transformed to a horizontal flow, still going right to left.
てしずえ絶はれがなの川く行
The horizontal style was often used for signage over building entrances, like in this historic photo of Nintendo company headquarters in 1889.
It says かるた製造元 (“card manufacturing base”) from right to left; and the top row in English is written from left to write, I mean right. Nintendo originally made and sold playing cards for a game called 花札, hanafuda meaning “flower cards”, popular in the Yakuza-run gambling parlors of Kyoto.
The flow of the river is endless,
and so the water is never the same.
Bubbles float on the murky surface,
bursting, re-forming, never staying in place.
Such are people and their homes in this world.
It was written after the Great Fire of Angen blazed through Kyoto, destroying a significant portion of the historic capital city and imperial court. The author moves to the mountains to live as a hermit, writing the book titled, Ten Foot Square Hut. It’s steeped in Buddhist worldview, akin to the philosophical pessimism of Schopenhauer, but he has moments of peace, poetry and beauty.
In the spring,
Wisteria flowers bloom like purple clouds in the west.
In summer,
The chattering cuckoos guide me,
Toward the mountain pass of death.
On autumn evenings,
The cries of cicadas fill my ears,
Lamenting this empty husk of a world.
And when the winter comes,
Snow covers the earth.
The book is included in 青空文庫, the Aozora Bunko project (“blue-sky library”), a digital collection of public domain works.
“Phoenicia” may have meant Land of Purple. ..A synonym for red or purple dye (“Tyrian purple”), laboriously produced by the Kassite rulers of Babylon from murex molluscs as early as 1600 BC, and on the Mediterranean coast by the Phoenicians from a byproduct of glassmaking.
In 1953, a hoard of arrowheads were discovered in al-Khader, five of them bearing inscriptions dating from circa 1100 BCE. They’re in a transitional script, offering the “missing link” between the pictographs of the Old Canaanite script, and the linear alphabetic Early Linear Phoenician script. The owner of the arrowheads “signed” them, the translation being: dart/arrow of 'Abd Labi’t, son of Bin-'Anat.
Beginning in the 9th century BC, adaptations of the Phoenician alphabet thrived, including Greek, Old Italic and Anatolian scripts.
The alphabet’s attractive innovation was its phonetic nature, in which one sound was represented by one symbol, which meant only a few dozen symbols to learn. The other scripts of the time, cuneiform and Egyptian hieroglyphs, employed many complex characters and required long professional training to achieve proficiency.
O-hoh, that is curious, how the alphabet as a phonetic notation was easier to learn compared to others, leading to its spread and popularity. It grew variants that branched off in different regions, the Greeks added vowels, some sounds changed, others were added.
Another reason for its success was the maritime trading culture of Phoenician merchants, which spread the alphabet into parts of North Africa and Southern Europe.
The alphabet had long-term effects on the social structures of the civilizations that came in contact with it. Its simplicity not only allowed its easy adaptation to multiple languages, but it also allowed the common people to learn how to write. This upset the long-standing status of literacy as an exclusive achievement of royal and religious elites, scribes who used their monopoly on information to control the population.
From the alphabet, to the printing press, to computers with a mind of their own. A writing system can influence not only social and economic structures, but mental, psychological and cultural structures as well. That’s where I imagine the revival of Hebrew as a spoken and written language for daily life succeeded - it was a way to guide personal and group thinking by consciously reviving, breathing life into “a language of our own”, bootstrapping an independent computing and cognitive tech stack.
Phoenician letter forms spread, mutated, and evolved into many other alphabets, roughly: the Ionic variant grew into the standard Greek alphabet, and the Cumae variant into the Italic alphabets including the Latin alphabet. The Runic alphabet is derived from Italic, the Cyrillic alphabet from medieval Greek. The Hebrew, Syriac and Arabic scripts are from the Aramaic variant.
A new word I learned, abjad, a family of writing systems with only consonants and no vowels. And Al-Abjadīyah (الأبجديّة), derived from the first letters of the script: Alef, Ba, Jim, Daal. It’s the same way “alphabet” is from Alpha Beta, and азбука (“azbuka”) from ABC in Cyrillic script.
In Hebrew there are 22 letters, and five of them have a variant when used at the end of a word.
Alef
Bet
Gimel
Dalet
He
Vav
Zayin
Chet
Tet
Yod
Kaf
א
ב
ג
ד
ה
ו
ז
ח
ט
י
ך / כ
Lamed
Mem
Nun
Samech
Ayin
Pe
Tsadi
Qof
Resh
Shin
Tav
ל
ם / מ
ן / נ
ס
ע
ף / פ
ץ / צ
ק
ר
ש
ת
I can’t even type these with the keyboard yet, so far I’m copy-and-pasting each letter. Like with APL, a beginner student of a Hebrew-based programming language might appreciate an input interface to enter letters by selecting them from an overview table or virtual keyboard.
While I’m at it, I’m curious to learn how to input Korean Hangul and Arabic. They’re both “connective” in a way, how the graphemes (?) flow together in Arabic cursive script with context-aware ligatures; and how a single Hangul character is made of composable building blocks.
The tag <div dir="rtl"> will set the text direction in HTML and Markdown.
Here’s an example text I found.
דוגמא לעברית במסמך Markdown
טקסט רגיל
עברית ו-English יכולות להופיע באותה פסקה. גם מספר מילים באנגלית יופיעו בסדר הנכון word1 word2 word3.
דוגמא לרשימות
אחד
שתיים
שלש
It says: “Hebrew and English can appear in the same paragraph.” “English words will appear in the correct order.” “Example list: one, two, three.”
Setting the value to auto is supposed to work with bidirectional text, a mixture of LTR and RTL, depending on what is the first letter of the sentence.
Whew, finally I made it back to Anistal (or actual name TBD). I downloaded the HTML page and its scripts to explore the language and editing interface. I like the Eyes icon that follow the cursor, how it changes to a Book symbol to refer to the dictionary when there’s invalid syntax detected.
Here’s the instruction set currently, formatted to show in pairs.
שחור = black
אדום = red
צהוב = yellow
ירוק = green
תכלת = cyan
כחול = blue
סגול = purple
לבן = white
הפוך = reverse
לאט = slow
מהר = fast
כהה = dark
בהיר = light
ערבב = mix
הדבק = glue
זרוק = drop
שכפל = copy
החלף = swap
I’ll leave it for another time to see if these are correct and how to string them together to form sentences. I never knew code blocks could flow in right-to-left direction, and it handles mixing English words so I didn’t have to spell them in reverse.
Named after Bluma Zeigarnik, a Soviet psychologist of Lithuanian origin, her 1927 research demonstrated that people remember unfinished or interrupted tasks better than completed ones. It was based on an observation that a waiter could recall unpaid orders in detail but forgot them immediately after payment.
Her experiments showed that incomplete tasks create cognitive tension that keeps information more accessible in memory—the tension persists until the task is resolved.
That sure sounds like a stack-based thinking process, where values are pushed onto a stack as accessible memory, then popped off (removed) as they’re used.
Also related to information gap theory.
George Loewenstein formalized the information gap theory in 1994, describing it as the psychological experience of curiosity that arises from the awareness of a gap between what one knows and what one wants to know.
This gap motivates individuals to seek information to close it. It explains how people react to gaps in their knowledge or understanding, often driving them to seek answers to resolve uncertainty.
It highlights the motivational learning dynamics that arise when individuals become aware of what they do not know. The theory suggests that when there is a gap or lack of information in a conversation or interaction, it creates a cognitive tension or uncertainty, motivating either curious investigations or defensive avoidance to resolve the tension.
That’s the dynamic that pulls me into rabbit holes like programming in Hebrew, the history of the alphabet, or a “hex seed” to bootstrap Uxn. It starts with a mystery or question that I’m too curious to know how the story goes.
Why cats can’t resist red laser pointers. Hunting instincts, predatory chase reflex provoked by quick unpredictable movements of an unknown source. Aspects of human psychology, thinking and emotional dynamics, can be explained by animal instincts for hunting.
What about instincts for gathering, like the natural tendency for a person (or a bird) to scan the environment looking for food and other potentially valuable things to gather and collect, doing visual information processing and pattern matching. I’m driven by this too, often when I’m reading articles and news, I’m skimming through the data, waiting for a ping of curiosity for something new, fresh, unusual, weird, or unknown - or anyting that triggers a pang of hunger for an intellectually satisfying morsel, meal, or feast. (“The ping/pang theory of hunter-gatherer instincts and the role of adrenaline/dopamine triggers in applied cyberpsychology.”)
These instincts can be used to manipulate people’s behavior, as in marketing, advertising, propaganda, cults, addictions. They can also be used by people for education, personal development, critical thinking and empathy, behavioral therapy - cultivating behaviors and thought patterns to improve physical, mental, and community health.
Virtual keyboard to input Hebrew letters, I’m intrigued by the idea - and further, I wonder about the design of user interface and input methods for all languages, what principles and patterns are useful.
There’s a common thread relating accessibility, supporting people of various abilities and preferred input/output methods, like screen readers; and internationalization and localization (i8n and l10n), to support a range of preferred languages to read and write.
Here’s a keyboard diagram with Hebrew letters, their names, positions, Unicode hex values.
I learned about niqqud, diacritical marks to indicate vowels. They look like braille with clusters of dots. The way to input them via keyboard is by holding the Alt (Alt Graph) as modifier key.
The AltGr key has a dedicated function in most language keyboards to input symbols, special characters, or modify the last entered character.
So a “virtual keyboard” is not only a software replica of the hardware version, there’s a more open design space for user interface patterns, like drop-down lists. And a challenge to support a range of input devices, the keyboard that assumes 2 hands and 10 fingers; a mouse with right and left clicks, double-clicks, drag, release; finger taps, slides, gestures; by microphone, camera, brain-wave monitor helmets.
Accented letters in Spanish, French, German. Useful to know how to read and write, considering my actual geographical and literary wanderabouts. A wealth of wonderful literature and thinkers in these languages. Goethe, Baudelaire, Pablo Neruda.. Looks like the US International Keyboard layout covers many of these letters in a single layout conveniently, with a combination of AltGr + a single key.
There’s also a “compose” key for multi-key combinations that input a single character.
typing Compose followed by ~ and then n will insert ñ
Ethnologue: Languages of the World is an annual reference publication in print and online that provides statistics and other information on the living languages of the world. It is the world’s most comprehensive catalogue of languages.
Most spoken languages in 2026, their list starts:
English - 1.5B
Mandarin Chinese - 1.2B
Hindi - 611.2M
Spanish - 561.3M
Arabic - 334.9M
French - 333.5M
Bengali - 274.4M
Portuguese - 269.4M
Indonesian - 254.8M
Urdu - 246.0M
Russian - 210.3M
German - 133.4M
Japanese - 125.7M
Compared to Internet users by language (2020):
1
English
1,186,451,052
25.9%
2
Chinese
888,453,068
19.4%
3
Spanish
363,684,593
7.9%
4
Arabic
237,418,349
5.2%
5
Indonesian
198,029,815
4.3%
6
Portuguese
171,750,818
3.7%
7
French
144,695,288
3.3%
8
Japanese
118,626,672
2.6%
9
Russian
116,353,942
2.5%
10
German
92,525,427
2.0%
Some languages under-represented on the web are: Hindi, Bengali, Urdu. These all use non-Latin scripts.
The Devanagari InScript keyboard layout is used to type Hindi, Marathi, and Sanskrit.
Twelve leather-bound papyrus codices buried in a sealed jar were found by an Egyptian farmer and others in late 1945. The writings in these codices comprise 52 mostly Gnostic treatises, but also three works belonging to the Corpus Hermeticum, and a partial translation of Plato’s Republic.
4Q7, a fragment of the scroll containing Genesis found in Cave 4 near Qumran, written in proto-Hebrew. It is thought to be made by a sect of Essenes, a mystic Jewish community during the 2nd century BCE.
Bereshit (בְּרֵאשִׁית—Hebrew for “in the beginning”) is the first weekly portion (פָּרָשָׁה, parashah) in the annual Jewish cycle of Torah reading. The parashah consists of Genesis 1:1–6:8. It starts:
“Just to be, it is a blessing, only to live is holiness.”
Hebrew
English
רק
Only
להיות
To be
זוהי
This is (feminine)
ברכה
Blessing
לחיות
To live
קדושה
Holiness
מטרתנו בחיים היא לחיות בהשתאות רדיקלית. לקום בבוקר ולהביט בעולם בדרך שלא לוקחת דבר כמובן מאליו. הכל פלא, אל תתייחסו לחיים באגביות. להיות אדם רוחני זה להתפעם מהיקום.
“Our goal in life is to live in radical awe. Wake up in the morning and look at the world in a way that takes nothing for granted. It’s all a wonder, don’t treat life casually. To be a spiritual person is to be amazed by the universe.”
Not sure if that’s correct - but if I think about the reading flow, I can see the URL protocol + domain is grouped, then the path parts in descending order, from parent to child.
Found a single-page explanation of Uxntal assembly language in Hebrew.
אוקסנטל (Uxntal) היא שפת סף מבוססת מחסנית שמִּתרגמת לשפת מכונה של מכונה ווירטואלית בשם אוקסן (Uxn).
אוקסנטל is a stack-based esoteric language that compiles to the virtual machine אוקסן.
א = a (Aleph)
ו = u (Vav)
ק = k (Qof)
ס = s (Samekh)
נ = n (Nun)
ט = t (Tav/Tet)
ל = l (Lamed)
How the code looks in RTL direction.
( זו הערה )
( התכנות באוקסנטל נעשה כולו בעזרת שינוי המחסנית )
#12 ( דחוף בית (8 סיביות) )
#3456 ( דחוף צמד בתים (16 סיביות) )
POP ( שלוף בית )
POP2 ( שלוף צמד בתים )
( ניתן לשלב בין המצבים השונים )
#1234 #5678 ADD2k ( 12 34 56 78 68 ac )
That last line, multiple words might flow better in the same direction as comments.
In linguistics, linear logic models grammatical parsing as deduction. A valid parse tree corresponds to proving the existence of a sentence using implication rules encoding the grammar.
In two-valued logic, there are sixteen possible truth functions, also called Boolean functions, of two inputs P and Q. They correspond to a truth table of a certain logical connective in classical logic, including several degenerate cases such as a function not depending on one or both of its arguments. Truth and falsehood are denoted as 1 and 0, respectively.
The resource interpretation - Lafont (1993) first showed how intuitionistic linear logic can be explained as a logic of resources, so providing the logical language with access to formalisms that can be used for reasoning about resources within the logic itself, rather than, as in classical logic, by means of non-logical predicates and relations.
symbol
linear logic
⊸
linear implication
⊤
top
⊥
bottom
⊗
multiplicative conjunction (tensor)
⊕
additive disjunction (plus)
&
additive conjunction (with)
⅋
multiplicative disjunction (par)
!
exponential conjunction (of course)
?
exponential disjunction (why not)
(−)⊥
negation
1
unit
0
impossibility
Tony Hoare (1985) used purchases at a vending machine to illustrate the logic, and culinary transactions have become the traditional example to describe use of the connectives.
indicating that the customer must choose either a soup or a salad. Contrariwise, the restaurant’s choice is disjoined using ⊕: if the dessert is seasonal fruits, then it might be well-modeled as
Finally, an all-you-can-eat/drink item is modeled with !:
(Drink) := (Coffee) & (Tea) & !(Tap water)
In the resource interpretation, the constant 1 denotes the absence of any resource, and so functions as the unit of ⊗ (any formula A is equivalent to A⊗ 1). ⊤ is the unit for & and consumes any unneeded resources; 0 represents a product that cannot be made, and thus serves as the unit of ⊕ (a machine that might produce A or 0 is as good as a machine that always produces A, because it will never succeed in producing a 0); and ⊥ denotes unconsumable resources.
That’s a tough one, it’s like another language - I can’t just jump in and expect to understand it. But I’m getting a good first taste.
Another name I recognize in the bibliography is Vaughn Pratt, from his top-down operator precedence parser algorithm (Pratt parsing). In 1999, Pratt built the world’s smallest web server at the time, the size of a matchbox. His master’s thesis was “Translation of English into Logical Expressions” (1969).
This is something I think is important to “language-ness” too. Human languages, we can grow them all the time, just by deciding to “wordify” some sounds and declare that they’re now a new word. (We can also do this with grammar: accidentally all the things, because Internet).
One of the attractions of catlangs for me is that very tiny “notional machine” and that feeling of liberation, that you’re very close to being able to say anything you want in any way that you choose to say it. In Forth, it’s not quite there yet. Some things you want to say, you just can’t easily: one of those quite important things is, “here is a sequence of tokens, please remember this for me as a single thing so I can use it again”. (What Lisp would call a List of Atoms). But it does feel close.
This is true. It’s also the part that makes stack machines hard to use when you want to have something like a database or a file system, with things that you write once and then read many times. In the 1980s, there was a thing called “dynamic RAM” which was cheap (compared to “static RAM”) and it kind of had a similar quality: reading from it, erased it. This wasn’t actually a great thing: the computer had to spend a lot of its time just refreshing RAM values to keep it alive, and that slowed it down. Fortunately we didn’t have to do the RAM refresh cycle in software, there were hardware circuits to do it. But we could go back to that again, if we wanted.
Lisp is inspired by Lambda Calculus, among other things (ie, “lists” did NOT come from Lambda Calculus). But Lambda Calculus is not the only way of defining functions. There’s a much more stack-machine like approach which, oddly enough, didn’t really get used to make a proper language, though it’s used inside a lot of modern functional languages. That’s Combinatory Logic, aka SKI Calculus.
I always get tripped up with SKI calculus because the way it’s defined is quite old-fashioned and weird and does NOT map well to the Lisp style of brackets (I think it’s left-associative where Lisp is right-associative, or the opposite?) Also, it’s prefix rather than postfix, so not actually as easy to evaluate as it could be. But it’s essentially a stack machine with only two builtin functions (S, which copies, unquotes and executes) and K (which deletes), and no variable names. And like Lambda Calculus, it doesn’t have anything else except functions. No data types at all. Not very practical for actual programming, but apparently useful for mathematicians proving theorems.
Forth (and Uxn), on the other hand, has a stack but also has a heap, with the memory read/write operations. Having that heap - so the ability to store values at addresses and keep them for as long as the program is running and read them many times - seems to turn out to be quite important for actual programming.
But then, when a Forth or Uxn program finishes… yeah, what happens to all that heap space? It sort of kinda gets “popped off the stack” at a higher level of organization, doesn’t it? Normally it’s the “operating system” that deals with closing a process’s allocated memory space and “pops it”. But what if there were no operating system, no processes, just the language?
So what if we had multiple stacks: a stack of values, then maybe a “small heap” on a stack of small heaps, then maybe more and more stacks of larger heaps? Since in actually-existing computers, we always now do have multiple levels of caches to think about, and those are never going to go away. We’re rather going to pretty much always have sets of small machines accumulated into sets of larger machines, and so on. If we could find a way of expressing a “tower of machines of increasing size” in a single stacky language, that might be useful.
Ie what if (to line up on integer numbers of bytes) a stack of bytes, then a stack of say 256 byte RAM chunks, then a stack of 64K chunks, then…
neko (猫) = “cat” in Japanese. חתול - khatúl, मार्जार - mārjār, 貓, Katzen, Кот
ekolog (אקולוג) = “ecologist” in Hebrew, Polish, Czech, Slovak. der Ökologe, ecoloog, эколог
Design a language as a learning toy and microworld, in the sense of Papert and LOGO; as an abstract machine and literary exercise. Explore linear and concatenative logic in a playground of two-dimensional Euclidean space.
A portmanteau is a suitcase that opens in two parts,
from the French porter (“to carry”) and manteau (“overcoat”).
First used in a linguistic sense by Lewis Carroll in the book Through the Looking-Glass (1871), where Humpty Dumpty
explains to Alice the strange words in Jabberwocky.
’Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
Slithy means “slimy and lithe” and
mimsy means “miserable and flimsy”.
You see it’s like a portmanteau—there are two meanings packed up into one word.
This creature is a set of 32 frames, each frame an image of 32 by 32 pixels. They’re stacked in a single image as a texture atlas, also called a spritesheet.
A sprite is a being or object, like an animated character, drawn on its own
layer on a background. The term originated from engineers working on
the Texas Instruments TMS9918 video display processor, noting how
sprites “float” on top of the background image without overwriting it,
much like a ghost or mythological sprite (from Latin spiritus).
Map of spritesheet
Code examples are sketches for now, in no particular syntax - a subset of TypeScript that feels natural to me.
Actions are: alert, still, run, sleep, itch, scratch, wash. Some with direction (north, south, east, west) or frame number (1 or 2).
Direction
nw
n
ne
w
•
e
sw
s
se
I’ll need a function to take a being’s vector from current and target positions, draw a line over time (wasn’t the Euclidean algorithm useful for drawing a line with pixels?) and map the angle θ (theta) to the direction names in sprites.
The word angle comes from the Latin word angulus, meaning “corner”.
Related to the Greek ἀγκύλος (ankylοs) meaning “crooked, curved”
and the English word “ankle”. Both are connected with the Proto-
Indo-European root ank-, meaning “to bend” or “bow”.
A cat in the city
I have a set of spritesheets and old programs from a public domain project, on which I wrote an article, Neko: History of a Software Pet. And more from Micropolis, a GNU Public License release of the OLPC (one laptop per child) version of SimCity, in C++ and ported to WebAssembly.
I’ve taken it apart to rewrite it as a “future city” builder, pictured above – and running here as Microcity Alpha (use arrow keys to move and mouse to build, the city state is persisted in browser local storage). But the engine is in old C++ style, hard to understand, modify or extend.
It’d be more fun to implement your own logic and build from scratch, with a simple interpreted language. Even better, a world where every block is a program that one can read and edit. Hm, that sounds like a spreadsheet, a reactive dataflow system..
Aiming only to make things clear to herself,
an artist pursues clarity in open confusion.
Map of world
Give the cat some space to play in. Start with a grid of 64 by 64 cells, each cell the size of a cat.
A being is a function called on every moment, a tick of the clock, receiving the world - its current state, time as number, previous state of self - and returns a new world and state of being.
Having a coherent flow of states across time, it creates a self, an illusion of identity through changes and actions. An action affects the state of the being or world around it - in some cases, spooky action at a distance, like gravity or electromagnetism.
How can all this be modelled in a linear or concatenative manner? I wonder if the paradigm and concepts fit well with the question, whether they lead to an elegant solution. Or the other way:
In solving the questions of this microworld, see how
linear logic can model the state and computation in insightful ways.
Time, as in physics, a rate of change - but modelled like musical time with tempo and rhythm patterns. An action, or behavior, is a pattern of state changes across time. A stream of events, as notes for a player of an instrument, or scheduled change in a visual player of a graph or interface element.
To be continued..
Think how to design a system that brings it together.
From The Distance Geometry of Music: “Euclidean rhythms have the mathematical property that their onset patterns are distributed as evenly as possible.” Illustrated above, the six fundamental African and Latin American rhythms all have equal sum of pairwise geodesic distances.
Every time a being is called on a tick of the world clock, it draws an imaginary line and moves the current position forward one step closer to the goal.
Uxn runs on a lot of systems without a host OS, it doesn’t do any cleanup of the memory on System/halt, but it does do an initial cleanup of the memory on load
This is how I write every program I make! it’s quite rare that I’ll use only a single stack in an application, I generally implement towers of machines in Uxntal, each modeled as an object with different capabilities and its own buffers. I use the main stack as the message passing stack, a sort of communication channel between all these machines, but individually, they each do their own error handling, type checking, and memory operations exposed as methods to interface with that memory.
Hiding the inner working of these different stacks, exposing only their APIs, reduce a lot of errors and gives the text editor some sense of the members of an object. I think this is peak practice if you’re working in catlang for extensive projects.
I should also clarify for other readers you don’t have to use it in Hebrew! The dropdown also has English (then press [↡:rainbow: Example↡] to replace editor with some stuff for chosen , and move cursor around to see how the stack evolves)
The Hebrew version exists because I started the project for my kids (huh, 7 years ago?! they grow fast).
(Translating languages only works
The “animation” aspect must be confusing by now. README explains how it was supposed to represent color=f(time), with words like slow and fast reflecting this. I did have a prototype controlling an RGB lamp at home, but the target audience didn’t grasp it.
If curious, you can play those “animations” in terminal:
git clone https://github.com/cben/animation-stack-language
git switch -d 77d2eca275be2ea628c32095de01a45dda3e03eb # sufficiently old commit
cd animation-stack-language
yarn install
LANG=en node repl.js
# Then type e.g. `red green fade` into the repl
Presently, I gave up the “function of time” aspect, and instead have an instance controlling a LED strip in my daughter’s room rendering the stack. There is no animation aspect, only fixed colors; but edit the code and the LEDs change.
But time-related words like slow and fast make little sense now, I should change them.
The web version is better UX than the terminal repl — you can move back and edit anywhere. The web interface never played “animations”, only fixed display.
I wish to bring back time but also interactivity later, still fuzzy how… (probably involving self-modification)
Aside: Localizing programming languages
So far it only truly works in toy learning environments with small stdlib…
Keywords are easy (e.g. חווה סקריפט) but interfacing to existing APIs is where it doesn’t scale… And right-to-left languages suffer worse unless ALL words are localized.
Ramsey Nasser had several talks on the topic, including his Arabic toy language. https://www.hedy.org/ and https://wordplay.dev/ are the most ambitious I’ve seen.
..Short computer programs, sometimes consisting of as few as three arithmetic operations in an infinite loop, can generate data that sounds like music when output as raw PCM audio.
This paper discusses the programs resulting from this exploratory work and highlights some rather unusual methods they use for synthesizing sound and generating musical structure.
This year we will take it to the next level with competitions in different size categories from 16 bytes to 1024 bytes. From tiny executable graphics and nanogames to bytebeat music.
I will propose here instead to turn this view on its head: instead of programs manipulating input, I will have input manipulating programs—for me, input is something that happens to a program, not vice-versa. This is certainly in the spirit of continuations, and, I hope, also in the spirit of functional programing.
What if there is no “world”, only a set of interacting beings, each self with a model of the world around it, having a relative center as (0, 0). Then there’s no need for an absolute center or a complete objective model of the world, only a set of centers as views into a shared subjective space. That would work better with an infinite canvas.
A “being” can be like a byte-beat expression, a function that takes a stream of values as input, and returns a stream of values as output. They’re a lazy stream that creates values as needed. A being is a node in a chain of asynchronous signal generators.
A function generator is equipment or software used to generate different types of electrical waveforms over a range of frequencies. Common waveforms are the sine wave, square wave, triangular wave and sawtooth shapes.
A pattern generator is equipment or software to generate an electrical waveform varying between two voltages corresponding to two logic states: 0 (low) and 1 (high).
An observation: the duality of analog (continuous wave) and digital (discrete particles) appears in various contexts, often requiring a translation to convert with loss of information (analog → digital). Related to how computers are clocks made of clouds.
An infinite canvas is like a stream of lazily-evaluated space.
(Is there a thing as a two-dimensional stream? Look into the streaming of lists, matrixes, trees. A stream of documents, programs, database changes. Destructuring and reconstructing complex values from a single stream of multiplexed data, or from multiple synchronized streams.)
Coinduction is a technique for defining and proving properties of systems of concurrent interacting objects. Coinductively defined data types are known as codata and are typically infinite data structures, such as streams.
To generate and manipulate codata, one typically uses corecursive functions, together with lazy evaluation. Corecursion and recursion can be thought of as operating on trees, which include data structures like lists and streams as special cases.
A stream is a special case of tree? I hadn’t heard that before.
A tree in functional programming is typically defined recursively. A tree node can have multiple children or branching.
Tree a = Leaf a | Node (Tree a) (Tree a)
A stream, or lazy list, is defined similarly but with exactly one tail, where a tree node can have at most one child. A stream is a linear, unbranching tree.
Stream a = Cons a (Stream a) | Nil
A stream is a degenerate tree. A tree can always be flattened into a stream, by choosing a depth- or breadth-first traversal; but reconstructing the tree requires additional information that the stream alone doesn’t contain.
The fundamental unit of information in computing and communication, the bit is a portmanteau of “binary digit”.
A directed acyclic graph can represent a data processing network. For instance, in electronic circuit design, static combinational logic blocks can be represented as an acyclic system of logic gates that computes a function of an input, where the input and output of the function are represented as individual bits.
The term “binary digit” reminds me that a hand can count to a number much higher than five.
There are 5 bits available, so 00000 to 11111 (0~31) or 32 values. With two hands or 10 fingers, it’s 210 = 1024. Plenty to represent a stream of bytes, with a couple fingers for metadata.
Two hands can represent a byte and half-nibble of storage.
“How to Count on Your Fingers: On Binary Digits and Human Habits” in the book, Digits and Dastards by Frederik Pohl.
Morra is a hand game that dates back thousands of years to ancient Roman and Greek times. Each player simultaneously reveals their hand, extending any number of fingers, and calls out a number. Any player who successfully guesses the total number of fingers revealed by all players combined scores a point.
Morra can be played to decide issues, much as two people might toss a coin, or for entertainment.
指算法 - Chisanbop (지산법), meaning “finger calculation” is a method used to perform basic mathematical operations. It can represent numbers from 0 to 99 with the hands, and can add, subtract, multiply and divide numbers. The system has been described as being easier to use than an abacus for students with visual impairments.
The letter A. Shaky, with awkward, wobbly sides and an uneven
centre line. I had done it! I had started – the thing that was to give my
mind its chance of expressing itself. True, I couldn’t speak with my lips,
but now I would speak through something more lasting – written words.
That one letter, scrawled on the floor with a broken bit of yellow chalk gripped
between my toes, was my road to a new world, my key to mental freedom.
– Poet and author Christy Brown describes a communication
breakthrough at age 5 in the book, My Left Foot.
Illustration of Mushi-ken (虫拳), a variant of rock-paper-scissors in Japan (1809). From the right: snake (蛇 hebi), frog (蛙 kawazu), slug (蚰蜒 namekuji). The frog defeats the slug, the slug defeats the snake, and the snake defeats the frog.
Hand games exist in a variety of cultures, and are of interest to academic studies in ethnomusicology and music education. Hand games are used to teach music literacy skills and socio-emotional learning in elementary music classrooms internationally.
Palmas is a handclapping style which plays an essential role in flamenco music.. There are two distinct types of hand claps: hard (fuertes, claras, secas) and soft (sordas). Each has a particular sound and is used at a particular time. Contra-tiempo palmas is a way of clapping between the normal beats in a bar. For instance, filling the space between beats with another beat or clap.
What’s starting to take shape in my mind is a programming approach where the world is modelled as streams of values, including complex values flattened to a linear stream and rebuilt on the other end. As needed, values are pushed onto a shared stack for the next expression or function to work on. Values are popped off the stack to use (or “consume”) them, related to the resource metaphor of linear logic.
No names, variables or constants. No garbage collection.
Well - names are a convenient way to refer to raw values; but perhaps much of what we take for granted in conventional programming can be eliminated by (re)framing the question and modelling the world differently. I imagine, somehow, control flow structures like loops and conditionals (if/else) can be built from logical operators or “connectives” that work on streams also.
A program is composed of a chain or graph of functions acting as filters in a pipeline of input and output streams. Some functions are signal generators, they emit a stream of values as a lazily evaluated list.
A simple generator I created, a metronome.
It emits an incrementing number on every beat. The second number shown in the demo is “drift” to measure latency, consistently below a quarter (1/4) of a millisecond.
I’d like the metronome to accept an optional input value, the tempo in BPM (beats per minute). At any time the input stream can emit a value, to schedule a tempo change at the next incoming beat.
On each beat the cat “thinks” and emits an event, like run and sleep. Next it can be made to emit a “movement” as (dx, dy) for any difference in position.
Running each node as separate process, data flowing through pipes, may not be practical for precise timing; or how it can handle many beings in parallel. But prototyping small programs in the shell and treating them as a composition of functions - it helps me think visually about streams. I like the idea of cross-platform nodes of reusable logic. Maybe a Nekolog expression can compile to a C program or WebAssembly module, each run in its own process or thread - as well as run a chain or graph of expressions in parallel. Mm, it’d be interesting to try making a spreadsheet application.
A node type I can imagine is a visualizer that takes an input stream and shows it in the terminal, a window like SDL (Simple DirectMedia Layer), on a web page with canvas or svg element.
A bit of a different topic, unrelated to catlangs, but since you’re thinking about colors and binary encoding. Here’s a little language that uses 3 bits of bandwidth, it’s called Solresol.
Accessibility
Two people facing each other at a distance, can communicate using the stenographic symbols in such a way that only they can see them. In this manner, a prisoner can, through the bars of the window, express thoughts to the outside world, and vice-versa.
One can make use of Solresol at sea, to communicate from one ship to another, or from a ship to a seaport, or vice-versa, and again in many ways: By playing tones, or if at night, by displaying bright lanterns or fires of the 7 colors.
To communicate to a deaf-mute, one can take the hand of a blind person and alternately press the fingers, as in the mute Universal Language.
Curwen hand signs often go along with the Solfa Scale. These provides a movement to go along with the pitch that we’re singing. Moving our bodies at the same time as singing, and thinking and using our voices gives us another way to understand what we’re doing. It engages another part of our brains, which means that we work more actively and understand what we’re doing.
The word for catlang in solresol is Faresimi’Solresol
What I wonder about is comprehensibility using representations other than characters on a 2D surface. In text-based code, we use the 2D layout to expose the code structure. This is lost in serialization. Would Forth-on-Solresol be understandable when played as music?
Logic Alphabet, Visual Variables, Tangible Values. Sémiologie des Graphiques: Diagrams, Networks, Maps. On a fruitful angle of inquiry, study and research.
At sea, to communicate from one ship to another, or from a ship to a seaport.. A prisoner can, through the bars of the window, express thoughts to the outside world .. By playing tones, or if at night, by displaying bright lanterns or fires of the 7 colors.
Solresol and the Shavian alphabet are beautiful, conceptual works of art. Lovely correspondence of colors, musical notes, and language. And software keyboard input, too.
This paper suggests that input and output are basic primitives of programming and that parallel composition of communicating sequential processes is a fundamental program structuring method. – Bell Labs and CSP Threads
jq, a command-line JSON processor, I learned is a concatenative language to process and query a stream of JSON over Unix pipes - to slice, filter, map and transform structured data. jaq, a Rust variant with a new twist on the concept.
Streams are a first-class language primitive, even booleans and numbers are filters that return their respective values. And how casually it creates an infinite sequence with recurse and repeat.
How the data flows through a pipeline of expressions with lazily evaluated values.
Feels like a good fit for the heartbeat generator (clock, metronome) I started: the function is an infinite sequence yielding values over time. For the syntax I’d prefer an extended JSON with pipeline |> operator (and syntax sugar like comments, optional trailing comma, unquoted object property names); maybe something that can easily run on, for example MicroQuickJS, a JS engine for microcontrollers.
Above an example of notation used in Principia Mathematica (1910). I’m starting to see why there is not only one language, but an endless variety and permutations of graphemes, ligatures, vowels and consonants, digits, letters, symbols, gestures. Below an audio-visual sequence diagram from director Sergei Eisenstein’s film Alexander Nevsky (1938).
Graphomania (from Ancient Greek: γρᾰ́φειν, gráphein, “to write”; and μᾰνῐ́ᾱ, maníā, “madness, frenzy”) is an obsessive impulse to write.
Graphorrhea is a communication disorder involving excessive wordiness, incoherent rambling, or frequent digressions in writing. The ramblings may be grammatically correct, but still leave the reader confused and unsure what the piece is about.
Hypergraphia is a behavioral condition characterized by the intense desire to write or draw.
Aw how fun would it be to have a magazine of hypermedia literature called Hypergraphia.
It turns out that normalization corresponds to performing computations in a functional language. To give an example, suppose that we do not take all numbers as primitive, but instead start with just 0 (zero) and the successor function s that adds one to zero. Thus we could represent the number 3 as the term s(s(s(0))). We can also represent a function for adding 2 to x as a term λx.s(s(x)) of type N -> N. Now consider a proof
λx.s(s(x)) : N -> N s(s(s(0))) : N
----
λx.s(s(x))[s(s(s(0)))] : N
Lambda reduction of the final proof term, λx.s(s(x))[s(s(s(0)))] yields s(s(s(s(s(0))))), which is our internal representation for 5, the result of adding 2 to 3.
– Linear Logic for Linguists
Repeatedly applying rewriting rules to an expression and reducing it to its simplest form, is equivalent to evaluating a program.
Shea Zellweger’s logic alphabet offers a visually systematic way of representing each of the sixteen binary truth functions.
The idea is to represent the truth functions in the form of a square matrix, and then to assign a letter shape to each of these matrices. When drawing a logic symbol, one passes through each square with assigned F values while stopping in a square with assigned T values.
Venn diagram of Greek, Latin and Russian Cyrillic upper case graphemes.
A precursor of Boolean algebra was Gottfried Wilhelm Leibniz’s algebra of concepts. The usage of binary in relation to the I Ching was central to Leibniz’s characteristica universalis. It eventually created the foundations of algebra of concepts, which is deductively equivalent to the Boolean algebra of sets.
From 1934 to 1936, NEC engineer Akira Nakashima, Claude Shannon and Victor Shestakov introduced switching circuit theory in a series of papers showing that two-valued Boolean algebra, which they discovered independently, can describe the operation of switching circuits. Using this property of electrical switches to implement logic is the fundamental concept that underlies all electronic digital computers.
"She is not manipulating the machine by turning knobs or pressing buttons. She is writing messages to it by spelling out instructions letter by letter. Her painfully slow typing seems laborious to adults, but she carries on with an absorption that makes it clear that time has lost its meaning for her.” – Sherry Turkle on Robin, aged 4, programming a computer.
An insight into linear logic, in an article I was reading about compilers. It discussed a technique of flattening the abstract syntax tree and other data structures.
Locality. ..Flattened Exprs are packed together in a contiguous region of memory, which is good for spatial locality. Your data caches will work better.
Cheap allocation. In flatland, there is no need for a call to malloc every time you create a new AST node. Instead, provided you pre-allocate enough memory to hold everything, allocation can entail just bumping the tail pointer to make room for one more Expr.
Cheap deallocation.. Smaller references..
Ergonomics
Easier lifetimes.. Convenient deduplication
Exploiting the Flat Representation
What could we do if we exploited stuff about the flattened representation that isn’t true about normal AST style?
..Visually, you can imagine that reference arrows always go backward in the array, and data always flows forward.
Let’s write a new interpreter that exploits this invariant. Instead of starting at the root of the tree and recursively evaluating each child, we can start at the beginning of the ExprPool and scan from left to right. This iteration is guaranteed to visit parents after children, so we can be sure that the results for subexpressions will be ready when we need them.
The tree flattened into a stream is essentially a stack-based concatenative style program in postfix notation.
This “extra-flat” interpreter has two potential performance advantages over the recursive interpreter: there’s no stack bookkeeping for the recursive calls, and the linear traversal of the ExprPool could be good for locality.
My favorite observation about this technique, due to a Reddit comment by Bob Nystrom, is that it essentially reinvents the idea of a bytecode interpreter. It’s pretty nifty that “merely” changing our AST data structure led us directly from the land of tree walking to the land of bytecode.
“I can imagine, while parsing, whenever you created a new node, rather than allocating space just for it and giving the parent node the pointer, you could push the node onto a vector or some other such growable contiguous array and give the parent a reference to that spot.”
Yes, that will definitely help! Once you do that, you may consider other stepwise refinements.
Since subexpressions are executed first, it makes sense to have them earlier in the array than their parents. So instead of walking from the root to the leaves, walk the leaves first and then have the parents follow them.
At that point, parents no longer need references to their children. Instead, you just need some convenient place to store the results of the child evaluations. Maybe a stack.
Now your array of instructions doesn’t need any actual links between them. It’s just a flat list of which operations to perform.
The Oil shell project has a big collection of links all about “compact AST representation,” much of which boils down to flattening.
Flattening-like ideas appear a lot in data-oriented design. Beyond just language implementation, similar concepts show up in other performance-oriented domains.
Then we can unroll the definition of eval′5 on expr, as in figure 5(b).. The end result is shown in figure 6(b); note in particular that the generalized compositions now all nest to the right.
There is a well-known compilation scheme from expressions to a stack machine. The observation that associativity of generalized composition leads directly to linearly structured target code is due to Wand (Continuation-based program transformation strategies), and explored in detail for more sophisticated languages by Henson (Elements of Functional Languages).
..Going into a forest and discussing the unusual “birds” (combinators) they find there.
Bird-watching was a hobby of one of the founders of combinatory logic, Haskell Curry, while the name of another founder, Moses Schönfinkel, means beautiful spark, or possibly beautiful little finch.
Each species of bird in Smullyan’s forest stands for a particular kind of combinator appearing in the conventional treatment of combinatory logic. Each bird has a distinctive call, which it emits when it hears the call of another bird. Hence, an initial call gives rise to a cascading sequence of calls by a succession of birds.
In a seminal paper (Definitional interpreters for higher-order programming language), Reynolds showed how to use continuation-passing style (CPS) and defunctionalization to take a recursive interpreter for a language and transform it into an abstract machine for executing programs in that language.
We revisit some well-known applications (factorial, fast reverse, tree flattening, and a compiler
for a simple expression language) to spotlight their dependence on the algebraic property of associativity.
Continuation-passing style transformation—which after all is a matter of sequentializing code that would otherwise be tree-structured—is connected to associativity.
Linear logic and concatenative languages are closer to writing a stream of bytecode instructions. Even tree-like languages like LISP, or syntax trees of any language, are typically compiled into a flat structure before running on a real machine or an interpreter, essentially an abstract machine.