--- title: Trying to imagine a future of programming language ecosystem --- _Feel free to treat what follows as a technical fantasy-fiction, or an intellectual exercise, a thought-experiment. Some familiarity with programming language theory, design and implementation is assumed._ Try to imagine a programming ecosystem that is syntax-, semantics-, runtime- and platform-agnostic. Programs, written in multiple syntaxes and semantics, for multiple platforms and runtimes, can run and interoperate seamlessly, while it's possible to make manual or programmatic changes across the whole stack from syntax to runtime, both at compile- as well as run-time, as far as possible and practicable. In effect, syntaxes, semantics and runtimes could be treated as first-class constructs, with mechanisms to create and adjust them as needed. {.sidenote} Earlier, I used the term programming _system_ here and in discussions elsewhere, which I now find inadequate to properly convey the idea being talked about here. {.sidenote} Obviously, a compiled program will have limited room for maneuver. There could be multiple levels of compilation, like compression, but making tradeoff between features and size of resulting system image. In general, *sub*ecosystems could be _sent out_ (on a mission or something?), with reduced functionalities, and on return can regain features back. If we were able to build such an ecosystem, among all the things that could be realized, here are a few of them that I can imagine: - Programmers choosing their own flavor of syntax to view and edit the code, similar to UI skins and themes now. When we say programming _language_, we usually mean the syntax and semantics as a coherent whole, if not including the implementation along as well. It's not like syntax and semantics can be so cleanly decoupled.. I'll discuss that in a while. By _flavors_ of syntax (and semantics, for that matter) I'm imagining the peripheral layer (of syntax and semantics) to be brought into the same mold as code styling, forming a smooth spectrum. Lispers should empathize on this aspect: does it matter from the perspective of the underlying implementation: - whether you structure your code with indentation (like Python), braces (like.. all the C-like languages) or keyword-based enclosure (like Pascal, Ada or Lua) - whether you put the type before or after the term (`int x = ...` vs `x: int = ...`), or even - which notation (prefix, infix or postfix) you use for expressions? Within a single project, there may be multiple flavors of syntax and semantics, suited for different usecases. Different from contemporary multi-language codebases, deeper interoperability with less overhead could be realized; a better version of pipes, remote procedure call or ''foreign'' function interface, where reserialization is minimized or eliminated and there could be richer interfaces, respectively. Even further, in the manner of language-oriented programming, programmers would be able to continuously (in a vaguely topological sense) adapt# the language to fit the problem domain better, to deal with the complexities more effectively. - When dealing with semantics in a first-class manner, making such changes that some existing code couldn't be updated into the modified semantics automatically, programmers can interactively fix them, similar to, or rather a narrow application of, interactive theorem proving. This would make it easier to incrementally rewrite large legacy codebases to benefit from innovations in programming methodology (e.g. borrow checking, capability-based security). It'd also allow the whole ecosystem to continue to evolve little by little along with the problem domain and society at large, the cost of effort to be paid amortized over time; instead of dealing with the maintenance cost, and when it could no longer be borne, the cost of rewriting. - Not only it would be possible to make significant changes to the runtime at run-time, but even swap-out (transplant?) the runtime entirely; due to having schemas to represent the entire program state runtime-agnostically to reliably carry this out. [^adapt]: For example: when certain language constructs are used quite often, there could be a shortcut syntax for it. For localized cases, macros would be enough, but they are usually not as powerful as Lisps, or as easy to use. As for non-local situations, it starts with preprocessing and goes upto transpilation. Languages that allow their syntax to be finely tuned are rare. The seeds of this can be found in Common Lisp's reader macros or in Forth. Racket and, [to some extent](https://www.gnu.org/software/guile/manual/html_node/Other-Languages.html), Guile shows what can be done in this aspect. Now let's take a look at some concrete examples of what's already there in reality, perhaps to better digest the nebulous idea: Starting with code styling: casing of identifiers (`camelCase`, `PascalCase`, `snake_case`, `kebab-case` and so on), spaces (how many) vs tabs, whether braces are on the same line or next, spacing around operators and punctuations and so forth. When there aren't some standards or norms in place, it's a matter of personal taste and preference. While we're quite far off from treating the entire syntax like styling today, there are still a few sporadic examples of an inkling of this: - [Partial style-insensitivity of identifiers](https://nim-lang.org/docs/manual.html#lexical-analysis-identifier-equality) in Nim, while camel case is the norm, the identifiers may be accessed using snake case. - [Uniform function call syntax](https://en.wikipedia.org/wiki/Uniform_function_call_syntax) in D, Nim etc., allowing a function call `f(a, b, c)` to be written as `a.f(b, c)`. - [Indentation-based layout](https://www.haskell.org/onlinereport/lexemes.html#sect2.7) in Haskell is optional, braces and semicolons can be used instead as well. - [Quote-like operators in Perl](https://perldoc.perl.org/perlop#Quote-and-Quote-like-Operators) allow arbitrary delimiters. - _What else have you seen in the wild that suits to be in this list?_ Treating syntaxes as first-class constructs, we'd see libraries of syntaxes, where you could import features on demand. Syntax features can be used in arbitrarily-nested lexical enclosures, overriding the syntactical elements of outer layers if needed. Similarly, semantics would benefit from both nesting of lexical and [dynamic](https://www.lispworks.com/documentation/HyperSpec/Body/03_aab.htm) [extent](https://www.lispworks.com/documentation/HyperSpec/Body/26_glo_d.htm#dynamic_extent)[^dynext]. For example, you could choose to temporarily use saturation arithmetic instead of wrap-around on overflow, switch between rounding modes in floating-point environment, turn on stricter semantics when dealing with untrusted input[^taint] or for cryptographical libraries and so on. [^dynext]: How this would work with continuations or conditions systems with control flow leaving and returning into the enclosure, just trying to imagine it causes headache.. Ugh, it's not my problem to worry about! [^taint]: Like [Perl's taint checks](https://perldoc.perl.org/perlsec), but even better. Unlike now when the same algorithms need to reimplemented for standard libraries of newly developed programming languages again and again; with this ecosystem like this, how much time and effort can be saved? Implement the algorithms once and it would be available to all programs, written in different syntaxes and semantics[^diff], like how LSP, to some degree, made the situation of bindings between editors and languages to turn from $O(mn)$ to $O(m + n)$. [^diff]: Where difference in semantics is too big, the cost of using an 'adapter' between two semantics would have to be paid, or when one can't pay, the portions where the cost is too high would have to be rewritten. But now it's limited to the specific semantics than all the languages. The best we're able to do for now in this respect is: - Transpilation, as you can see with so many languages targetting ECMAScript, Lua, C etc. - Targetting the well-established runtimes: JVM, CLR, BEAM, and recently, WebAssembly; or IRs like that of LLVM. When people seek new features and design a new language, yet don't want to start from scratch and would rather want take advantage of the vast amount of software already written, these are viable choices. However, this leads to entrenchment of the programming ecosystem around these existing language implementations and runtimes, making it quite difficult for new ones to gain foothold. Otherwise, the innovations, the advantages it brings to the table must be worth more than the cost of rewriting existing codebases into it. Or, it can slowly gain traction through the new code that gets written in it. With that idea of continuously molding the semantics, providing kind of a bridge to smooth[^smoothpath] out the path of upgrading the code, how beneficial would it be for the vast swaths of legacy codebases? While not at this grand scale, there was a [quite significant demo of this idea](https://soft-dev.org/pubs/html/barrett_bolz_diekmann_tratt__fine_grained_language_composition/) where they merged a Python 2 and a PHP implementation together, allowing deep integration between code written in those two languages, even arbitrary nesting of the languages onto each other at the source code level. [^smoothpath]: Like gradual typing, but gradual _everything_. The recent proliferation of configuration languages is an interesting situation. There should be many more of them coming up. We are better off focusing more on the schemas: the meaning of the data being represented through such DSLs. Because when a proper schema is in place, what syntax is used to represent it is quite inconsequential, there are infinite ways to represent the same data.[^ways] However, in an analogy to typography, we should consider the legibility of the syntax being used. [^ways]: This has—to a great extent—been realized for markup languages with [Pandoc](https://pandoc.org/). When dealing with schemas, creating, updating or interoperating with other schemas[^interop], it might make sense to have schemas of schemas, _meta_-schemas, or it would be more appropriate to call them [_ontologies_](https://en.wikipedia.org/wiki/Ontology_(information_science)) at that point. Then, as things develop, there will exist multiple different ontologies, to properly deal with which [foundational ontologies](https://en.wikipedia.org/wiki/Upper_ontology) would be needed, and so on.[^inspire] In order for the programming ecosystem to be agnostic in the ways we talked about, we'd need to agree on the _meaning_ of programs. Semantics schemas and programming ontologies might suffice at the beginning. But, as the ecosystem evolve further and attains higher and higher levels of abstractions, theories would be needed to be developed in tandem to sustain such evolution. [^interop]: [Cambria](https://www.inkandswitch.com/cambria/) is a quite interesting recent development in this domain, remarkable in its use of [lenses](https://golem.ph.utexas.edu/category/2020/01/profunctor_optics_the_categori.html) for bidirectional translation of data between schemas. There's also [Subtext](https://www.subtext-lang.org/retrospective.html), which has over two decades of research efforts going in it, deeply exploring the problem space that closely relates to what I'm trying to talk about here. [^inspire]: Vaguely analogous to [hierarchy of universes](https://ncatlab.org/nlab/show/hierarchy+of+universes) in type theory or [$\infty$-categories](https://ncatlab.org/nlab/show/infinity-category)? Can math people corroborate whether this analogy is appropriate in this case? In my extremely limited understanding, semantics schemas should form a category, the category of semantics schemas describing[^descr] Turing-complete languages, with morphisms translating programs written for one semantics to another. Even in the worst case of two semantics being extremely unlike each other, by virtue of Turing-completeness, we can just send interpreter of one's semantics in the other along with the program to be translated.[^internal] For that idea of smoothly molding semantics, I wonder if additional structures in all these semantics would be helpful... I'm not a ''working mathematician'' (not even a ''working'' programmer), thus severely lack in fundamentals, leaving me unable to explore any deeper. Still, I have a vague feeling, taking cues from [Rice's theorem](https://en.wikipedia.org/wiki/Rice's_theorem) (and [Gödel's incompleteness theorem](https://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems) in general) that we'll come across some more walls that limit what can be done with semantics. [^descr]: Would it help to include the entire Chomsky hierarchy, so.. upto and including Turing-complete semantics? [^internal]: This is ignoring how semantics are actually studied; as with the many approaches to semantics (denotational, operational, axiomatic and so on), it might be beneficial to take advantage of semantics sharing same approach to interoperate better together. There might also be big bridges built between these apptoaches for the benefit of semantics of those approaches. In the [preliminary](https://lobste.rs/s/jrwaey/why_engineers_can_t_be_rational_about#c_svcbfj) [discussions](https://lobste.rs/s/4inlhr/language_design_notes#c_hnh1mf) about this idea, I came across some common responses that I find worth elaborating more: > (the infeasibility of) a single universal system (or language, or schema) Clearly, it didn't work with natural languages (Esperanto and so on), I think it won't with programming languages either. Continuing with the analogy of natural languages, we come across the concept of [dialect continuum](https://en.wikipedia.org/wiki/Dialect_continuum): when there's significant amount of human interaction possible (i.e. there's no natural barrier as hindrance), we don't see a sudden drastic difference in language across regions; the languages spoken are mutually intelligible at a local scale, not so much at a larger distance. It forms a spectrum, with the languages smoothly transitioning from one to another. Also consider the formation of Pidgins and Creoles, out of sheer need to communicate. As many words there are, there aren't usually[^fron] that many concepts that can be conveyed; through our shared sense of humanity, cross-cultural exchanges have been able to take place. It's even more apparent with current capacity of worldwide connectivity and what this has afforded us. We want to imagine the same manner of dynamism here in the domain of programming as well. So we'll have multiple syntaxes, semantics, runtimes, platforms, even systems[^dist]; each adapted to their respective purposes or fields, while allowing interaction, collaboration, interoperation among them. [Standardization](https://xkcd.com/927/) wouldn't help, either it would be too strict, too limiting, or too loose, too vague. Thus let the ecosystem might emerge naturally: when the need to interoperate arise, let there be agreements the aspects where there can be and divergence where can't; like bridges or adapters between protocols now, but more fundamental. As the systems developed in this manner aren't as rigid like protocols; each of them can evolve and converge towards a certain direction in matters of collaboration, incorporating the best aspects of each of them, to the benefit of all. [^fron]: As apparent from the study of etymology. Not considering the case of artists and thinkers who delve past the frontier of representation or imagination; whether taking advantage of inherent ambiguity of the languages, using literary devices or coining new words or phrases, they aren't having it easy. [^dist]: Maybe certain packagings of these could be made into distributions. Like Linux distributions? > intermediate representations (LLVM(,) MLIR etc.) or existing platforms (JVM, CLR, BEAM, WebAssembly etc.) Targetting these would cause loss of information about the programs. The ecosystem would need to preserve all information to achieve what it purports to. Initial implementations of the idea would rely on and target these, but only as a means to bootstrap. Eventually we'd break them down, tear them apart and then incorporate all the pieces together; so that we can mix and match parts as needed. > programming languages are tools, instead of one tool trying to do everything, there should be multiple tools suited for different purposes While I don't disagree with the intent being conveyed, I find it a little inappropriate, considering the language seperate from its implementations. Can languages, cultures or even civilizations be considered as tools? From what kind of perspective? Languages are not static entities. Languages are the mediums we use to convey intent. They shape not only our own identity, but our worldview as well. They form cultures and communities. As cultures evolve to find richer perspectives, the languages evolve along with them. The systems under the ecosystem would need be quite flexible and malleable to deal with this kind of dynamism. Here, through these ideas, I've been trying to explore the realm of languages as well as what lies beyond. Therefore, to put it another way, if you (still) see programing languages as tools, I'm considering the entire infrastructure of such toolmaking. Instead of the current state of rigid, inflexible toolmaking, we want to consider the extent of realizability of [malleability](https://malleable.systems/) and [conviviality](https://www.nimblemachines.com/convivial-tool/) in these tools, from the perspective of programmers and developers of these systems alike. Smalltalk, Forths and Lisps have traditionally been the [systems](https://andreyor.st/posts/2023-10-18-a-programming-system/) that quintessentially embody this ideal. How can benefits of these systems be brought to all and how to develop the philosophy that they embody further.. Gabriel [analyzed](https://www.dreamsongs.com/Files/Incommensurability.pdf) the paradigm shift from programming _systems_ to _languages_ through the lens of incommensurability. Tagore, a century ago, [contemplated](https://en.wikisource.org/wiki/Nationalism/Nationalism_in_the_West) on the rise of nationalism and the adverse effect that had on society. What conclusions can you draw from these two seemingly disparate bodies of work? While strolling outside this early winter morning, I tried to apply and interpret the political conclusions in the domain of programming. Nation-states has been quite successful, effective and efficient in what they do. So has the paradigm shift into languages. But at what cost? Abstracting over humanity, is it worth it? As we got to see for ourselves how the word _algorithm_ slowly gained the negative connotation it now has, does it pain us? In exchange of the benefits that the language paradigm continue to bring us, we put on more bondage, at a fundamental level, for language is the very medium of our expression. Bondage may be understood as a metaphor that generalizes the physical to the spiritual. However, if it's convenient, it's better to understand this from [metaphysical viewpoint](https://en.wikipedia.org/wiki/Moksha) that it really alludes to. As nation-states and the political machinery that run it amassed wealth and power and lost themselves in the vicious pursuit for more, wars broke out, and will continue to break out. This is how bondage manifests and suffering ensues. Similarly, the digital empires built with the aid of the language paradigm, considering what they have been inflicting upon us.. where does this leave us? Math can't be blamed, but its wielders. So we have to develop stronger mathematical weapons in turn to fight the war. As for how to get rid of bondage, there's [a quite beautiful answer](https://en.wikisource.org/wiki/Ashtavakra_Gita#Chapter_VIII) to it. However if you read around it, you'd be even more surprised (or not?). Getting back to the modern concept, bondage is a matter of consent, otherwise it's turns into captivity. So the awareness about the extent of bondage is important. Doug Hoyte [writes](https://letoverlambda.com/index.cl/guest/chap3.html#sec_5), "Hygienic macros are, in the best of situations, a beginner's safety guard-rail; in the worst of situations they form an electric fence, trapping their victims in a sanitised, capture-safe prison." Can a similar case be brought out about memory management in systems programming languages, manual vs borrow checking? Tagore's [this poem](https://en.wikisource.org/wiki/The_Gardener_(Tagore)/6) is quite relevant in this regard, the security and comfort of the caged bird versus freedom and vulnerability of the free bird, with each having to live with their choices. It's quite bemusing how such a philosophical poem can be applied in such a context. > extreme difficulty, requiring enormous amount of effort to realize, or impossible to realize to its fullest generality Thus the initial disclaimer. I'm just putting it out there for posterity. Whether it is possible to realize any of these ideas and how far can they be realized, I have no idea. In certain respects, we are trying to contend with [the Real](https://en.wikipedia.org/wiki/The_Real), with implied inherent futility of such effort. How meaningful this effort would be, I don't know. I appreciate your patience in enduring reading till the end, taking time to think through various aspects of the idea presented here and would join in refining and developing the idea further. I look forward to thoughtful, in-depth and critical discussion in this regard. --- Created: 2025-11-27 Last updated: 2025-12-01