<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: John Samuel</title>
    <description>The latest articles on Forem by John Samuel (@jsamwrites).</description>
    <link>https://forem.com/jsamwrites</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3783683%2F10ffba0a-d43e-4f91-a059-33d724c426a3.png</url>
      <title>Forem: John Samuel</title>
      <link>https://forem.com/jsamwrites</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jsamwrites"/>
    <language>en</language>
    <item>
      <title>Chromatic Automata: How Simple Rules Paint Surprising Worlds of Color</title>
      <dc:creator>John Samuel</dc:creator>
      <pubDate>Sun, 05 Apr 2026 06:58:11 +0000</pubDate>
      <link>https://forem.com/jsamwrites/chromatic-automata-how-simple-rules-paint-surprising-worlds-of-color-2nc9</link>
      <guid>https://forem.com/jsamwrites/chromatic-automata-how-simple-rules-paint-surprising-worlds-of-color-2nc9</guid>
      <description>&lt;p&gt;When we think about cellular automata, we often imagine black-and-white grids ticking forward in time, like digital snowstorms marching across the screen. But once we add color — palettes, gradients, and seasonal hues — these same simple rules start to resemble mountain ranges, woven textiles, or abstract paintings.&lt;/p&gt;

&lt;p&gt;In this article, I explore how color transforms elementary cellular automata, starting from my earlier experiments with gradients and then moving into interactive, browser-based explorations.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Two Tones to Color Gradients
&lt;/h2&gt;

&lt;p&gt;In my previous piece, “&lt;a href="https://jsamwrites.medium.com/chromatic-evolution-expanding-the-color-palette-of-cellular-automata-b6a0d71b724b" rel="noopener noreferrer"&gt;Chromatic Evolution: Expanding the Color Palette of Cellular Automata&lt;/a&gt;,” I began with classic black‑and‑white rules and asked a simple question: what if each new row could have its own color gradient. By mapping cell states to smooth transitions between colors, the familiar triangular structures of rules like 50 or 30 suddenly looked like stylized mountain peaks and layered landscapes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5oygysg3fvnanal472el.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5oygysg3fvnanal472el.png" alt=" " width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even a fixed rule, when combined with evolving gradients, generates sequences of “paintings” rather than mere binary patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seasonal Palettes and Emergent Landscapes
&lt;/h2&gt;

&lt;p&gt;Instead of sticking to arbitrary RGB picks, I started choosing palettes inspired by nature — for example, spring shades with distinct background and foreground colors. With five carefully separated colors, simple one‑dimensional rules produced scenes that evoke snow‑capped peaks, multi‑layered hills, or bands of vegetation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 57
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltik1uzmh7g49ml0yzwg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltik1uzmh7g49ml0yzwg.png" alt=" " width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 150
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzo4gp24yc9qq0wxbvf1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzo4gp24yc9qq0wxbvf1.png" alt=" " width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 225
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl6qd5rgmxn032reje77.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl6qd5rgmxn032reje77.png" alt=" " width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Small tweaks to palette design — such as excluding the background from the foreground list — can make the main structures stand out more clearly while still preserving the underlying rule.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ezrc23u7lvx5qmzcq88.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ezrc23u7lvx5qmzcq88.png" alt=" " width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring Colorful Automata in the Browser
&lt;/h2&gt;

&lt;p&gt;To make these experiments accessible and reproducible, I built CellCosmos, a WebAssembly‑based explorer for elementary cellular automata. The core logic is written in a multilingual programming language and compiled to WASM, so it runs interactively in the browser while exposing parameters like rule, palette, and initial conditions.&lt;/p&gt;

&lt;p&gt;Live tool: &lt;a href="https://multilingualprogramming.github.io/cellcosmos/" rel="noopener noreferrer"&gt;https://multilingualprogramming.github.io/cellcosmos/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With CellCosmos, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select any of the 256 elementary rules and instantly see how it behaves with different color schemes.&lt;/li&gt;
&lt;li&gt;Experiment with multi‑stop gradients mapped to discrete states, turning a one‑dimensional rule into a rich chromatic texture.&lt;/li&gt;
&lt;li&gt;Share configurations via encoded URLs, making it easy to revisit or remix particularly striking patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Simple Rules Make Such Rich Colors
&lt;/h2&gt;

&lt;p&gt;What makes all of this so fascinating is that none of the underlying rules change: the automata remain local, deterministic update systems on a line of cells. All the perceived complexity comes from how we choose to encode states as colors, how we separate background and foreground, and how gradients evolve across rows.&lt;/p&gt;

&lt;p&gt;In other words, color acts as an interpretable lens on dynamics we already have, revealing mountains, waves, and tapestries that were always latent in the bit patterns.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>webassembly</category>
      <category>showdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Built a Cellular Automata Explorer in WebAssembly — Here Are 21 Visual Experiments</title>
      <dc:creator>John Samuel</dc:creator>
      <pubDate>Sat, 21 Mar 2026 21:14:40 +0000</pubDate>
      <link>https://forem.com/jsamwrites/i-built-a-cellular-automata-explorer-in-webassembly-here-are-21-visual-experiments-376o</link>
      <guid>https://forem.com/jsamwrites/i-built-a-cellular-automata-explorer-in-webassembly-here-are-21-visual-experiments-376o</guid>
      <description>&lt;h2&gt;
  
  
  The project
&lt;/h2&gt;

&lt;p&gt;Over 21 days in May 2025, I used cellular automata as a daily sketchbook: one tool, one new constraint, one visual experiment per day. The result is &lt;strong&gt;CellCosmos&lt;/strong&gt; — a browser-based elementary cellular automata explorer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The twist:&lt;/strong&gt; the core automaton logic is written in French-syntax source code using a &lt;a href="https://multilingualprogramming.github.io/docs/" rel="noopener noreferrer"&gt;multilingual programming language&lt;/a&gt; I've been building. That French source is compiled to &lt;strong&gt;WebAssembly (WASM)&lt;/strong&gt; and runs at near-native speed in the browser.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔗 Live tool: &lt;a href="https://multilingualprogramming.github.io/cellcosmos/" rel="noopener noreferrer"&gt;multilingualprogramming.github.io/cellcosmos&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📦 Source (GPL-3.0): &lt;a href="https://github.com/multilingualprogramming/cellcosmos" rel="noopener noreferrer"&gt;github.com/multilingualprogramming/cellcosmos&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5e4uach4ujwwt56bksl2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5e4uach4ujwwt56bksl2.png" alt=" " width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works technically
&lt;/h2&gt;

&lt;p&gt;A cellular automaton starts with a finite grid of cells. Each cell holds a discrete state (in CellCosmos, small integers representing phases or ages). At each time step, every cell updates simultaneously based on a lookup at a small local neighborhood.&lt;/p&gt;

&lt;p&gt;For a &lt;strong&gt;1D elementary CA&lt;/strong&gt; (the Wolfram model):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each cell looks at itself and its two immediate neighbors → 3 cells → 8 possible binary patterns → &lt;strong&gt;256 possible rules&lt;/strong&gt; (Rule 0 through Rule 255)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For &lt;strong&gt;2D automata&lt;/strong&gt;, the neighborhood is the 4 orthogonal neighbors (von Neumann) or 8 surrounding cells including diagonals (Moore).&lt;/p&gt;

&lt;h3&gt;
  
  
  The build pipeline
&lt;/h3&gt;

&lt;p&gt;The deployment is fully automated via GitHub Actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;French-syntax source is compiled to WAT/WASM&lt;/li&gt;
&lt;li&gt;The expected WASM exports are verified&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;public/&lt;/code&gt; directory is published to GitHub Pages as a static site — no server required&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Parameters exposed in the tool
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Options&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rule selector&lt;/td&gt;
&lt;td&gt;0–255, slider + named presets (Rule 30, 90, 110, 150, 184…)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canvas shape&lt;/td&gt;
&lt;td&gt;Rectangle, Circle, Ellipse, Triangle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initial state&lt;/td&gt;
&lt;td&gt;Centre seed or random distribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Color&lt;/td&gt;
&lt;td&gt;Background + multi-stop gradient mapped to cell states&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boundary&lt;/td&gt;
&lt;td&gt;Hard edge or toroidal wrapping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Probability&lt;/td&gt;
&lt;td&gt;0.0–1.0 stochastic transition strength&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Direction&lt;/td&gt;
&lt;td&gt;LTR or RTL rule application&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every configuration can be downloaded as a PNG or shared via a URL that encodes the full parameter state.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2c3sqjc6g3w6uw1w1397.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2c3sqjc6g3w6uw1w1397.png" alt=" " width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The 21 experiments
&lt;/h2&gt;

&lt;p&gt;Breathing Life into Cellular Automata with Color&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/breathing-life-into-cellular-automata-with-color-417064a82a30" rel="noopener noreferrer"&gt;Breathing Life into Cellular Automata with Color&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/painting-landscapes-cellular-automata-through-color-gradients-31101316bf02" rel="noopener noreferrer"&gt;Painting Landscapes: Cellular Automata Through Color Gradients&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/chromatic-evolution-expanding-the-color-palette-of-cellular-automata-b6a0d71b724b" rel="noopener noreferrer"&gt;Chromatic Evolution: Expanding the Color Palette of Cellular Automata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/shifting-origins-exploring-position-effects-in-cellular-automata-a2256b130d9d" rel="noopener noreferrer"&gt;Shifting Origins: Exploring Position Effects in Cellular Automata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/mirrored-emergence-shifting-origin-points-in-cellular-automata-fb982c68b99e" rel="noopener noreferrer"&gt;Mirrored Emergence: Shifting Origin Points in Cellular Automata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/symmetry-bidirectional-rule-generation-in-cellular-automata-d8fc42d1e531" rel="noopener noreferrer"&gt;Symmetry: Bidirectional Rule Generation in Cellular Automata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/the-wandering-point-reflective-symmetries-in-cellular-automata-2ac952220952" rel="noopener noreferrer"&gt;The Wandering Point: Reflective Symmetries in Cellular Automata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/pattern-emergence-how-position-transforms-cellular-automata-behavior-2d9d22345272" rel="noopener noreferrer"&gt;Pattern Emergence: How Position Transforms Cellular Automata Behavior&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/binary-genesis-patterns-emerging-from-two-initial-points-in-cellular-automata-fa7b7877fc00" rel="noopener noreferrer"&gt;Binary Genesis: Patterns Emerging from Two Initial Points&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/the-multiplicity-effect-scaling-initial-points-in-cellular-automata-systems-407851c17f8d" rel="noopener noreferrer"&gt;The Multiplicity Effect: Scaling Initial Points in Cellular Automata Systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/the-edge-effect-how-boundary-conditions-shape-cellular-automata-landscapes-b5db7d86b2ce" rel="noopener noreferrer"&gt;The Edge Effect: How Boundary Conditions Shape Cellular Automata Landscapes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/unveiling-the-grid-what-shape-reveals-about-cellular-behavior-1976737cb3d5" rel="noopener noreferrer"&gt;Unveiling the Grid: What Shape Reveals About Cellular Behavior&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/when-points-cluster-unexpected-emergent-patterns-in-cellular-automata-8c9280aef896" rel="noopener noreferrer"&gt;When Points Cluster: Unexpected Emergent Patterns in Cellular Automata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/rule-strata-the-aesthetic-potential-of-layered-color-generation-in-cellular-auto-d5c9c1d9186b" rel="noopener noreferrer"&gt;Rule Strata: The Aesthetic Potential of Layered Color Generation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/rule-strata-the-aesthetic-potential-of-layered-color-generation-in-cellular-auto-d5c9c1d9186b" rel="noopener noreferrer"&gt;Rule Strata (continued)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/layered-evolution-bidirectional-rule-generation-in-cellular-automata-2dcaee00fa68" rel="noopener noreferrer"&gt;Layered Evolution: Bidirectional Rule Generation in Cellular Automata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/vertical-initialization-reimagined-the-surprising-effects-of-layered-rule-application-e23382f707ec" rel="noopener noreferrer"&gt;Vertical Initialization Reimagined: The Surprising Effects of Layered Rule Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/chromatic-chaos-multi-layered-rule-applications-in-cellular-automata-2f7c69581e9a" rel="noopener noreferrer"&gt;Chromatic Chaos: Multi-layered Rule Applications in Cellular Automata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/rolling-the-dice-on-determinism-a-probabilistic-take-on-cellular-automata-e935073feb02" rel="noopener noreferrer"&gt;Rolling the Dice on Determinism: A Probabilistic Take on Cellular Automata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/when-three-points-meet-probability-natural-phenomena-in-cellular-automaton-patterns-47757c646970" rel="noopener noreferrer"&gt;When Three Points Meet Probability: Natural Phenomena in Cellular Automaton Patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@jsamwrites/reversing-the-flow-right-to-left-rule-application-in-cellular-automata-eaa8f5e044c4" rel="noopener noreferrer"&gt;Reversing the Flow: Right-to-Left Rule Application in Cellular Automata&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;What I took away&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Across these 21 posts, a few themes kept surfacing. Color is not decoration — it is a lens; the same rule under different palettes reads as geological strata, organic growth, digital glitch, or abstract painting. Space matters: moving the origin, wrapping the boundary, or changing the canvas shape transforms the composition even when the underlying dynamics are identical. Layering rules creates emergent complexity at the boundaries between regimes. And probability bridges the gap between crisp mathematical automata and the textures we recognize from nature.&lt;/p&gt;

&lt;p&gt;The unifying thread: cellular automata are endlessly configurable once you treat them as a &lt;em&gt;medium for visual exploration&lt;/em&gt; rather than only as objects of theoretical study. Every parameter — rule, palette, seed, boundary, shape, direction, probability — is a creative control.&lt;/p&gt;

&lt;p&gt;The 21 days are over, but the exploration continues.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Try it yourself&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live tool: &lt;a href="https://multilingualprogramming.github.io/cellcosmos/" rel="noopener noreferrer"&gt;multilingualprogramming.github.io/cellcosmos&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source code (GPL-3.0): &lt;a href="https://github.com/multilingualprogramming/cellcosmos" rel="noopener noreferrer"&gt;github.com/multilingualprogramming/cellcosmos&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Multilingual programming project: &lt;a href="https://github.com/multilingualprogramming" rel="noopener noreferrer"&gt;github.com/multilingualprogramming&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The "Copy link" button in the tool encodes the full parameter state into a shareable URL — rule, palette, canvas shape, seed position, probability, direction — so any configuration can be bookmarked or sent to someone else.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>webassembly</category>
      <category>opensource</category>
    </item>
    <item>
      <title>A Strange Permutation Substring Sequence: Introducing OEIS A359012</title>
      <dc:creator>John Samuel</dc:creator>
      <pubDate>Fri, 13 Mar 2026 21:53:42 +0000</pubDate>
      <link>https://forem.com/jsamwrites/a-strange-permutation-substring-sequence-introducing-oeis-a359012-1ha6</link>
      <guid>https://forem.com/jsamwrites/a-strange-permutation-substring-sequence-introducing-oeis-a359012-1ha6</guid>
      <description>&lt;p&gt;I’ve been exploring a new integer sequence on the OEIS, A359012, and turned it into a small experiment in “data‑driven number theory”. This post briefly introduces the sequence and shares links to the live dataset and code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is A359012?
&lt;/h2&gt;

&lt;p&gt;A359012 tracks integers (k) that reappear inside permutation numbers (xPy) when (k) is formed by concatenating the digits of (x) and (y). &lt;/p&gt;

&lt;p&gt;More concretely: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take natural numbers (x) and (y).
&lt;/li&gt;
&lt;li&gt;Form (k) by writing the digits of (x) followed by the digits of (y).
&lt;/li&gt;
&lt;li&gt;Compute (xPy), the number of permutations of (x) objects taken (y) at a time.
&lt;/li&gt;
&lt;li&gt;If the decimal expansion of (xPy) contains (k) as a contiguous substring, then (k) belongs to A359012. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first few terms (with one witness each) look like this: &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;k&lt;/th&gt;
&lt;th&gt;x&lt;/th&gt;
&lt;th&gt;y&lt;/th&gt;
&lt;th&gt;xPy (permutations)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;318&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;318073392000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;557&lt;/td&gt;
&lt;td&gt;55&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;1022755734000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;692&lt;/td&gt;
&lt;td&gt;69&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;4692&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;729&lt;/td&gt;
&lt;td&gt;72&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;30885807297945600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2226&lt;/td&gt;
&lt;td&gt;222&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;111822261510960&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In each case, (k) appears as a substring of the decimal representation of (xPy). &lt;/p&gt;

&lt;h2&gt;
  
  
  A few empirical facts
&lt;/h2&gt;

&lt;p&gt;Using a brute‑force generator up to (k &amp;lt; 10^6), the current dataset looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;712 terms below 997 398. &lt;/li&gt;
&lt;li&gt;Term lengths are heavily concentrated at 6 digits (565 out of 712 terms). &lt;/li&gt;
&lt;li&gt;708 of 712 witnesses end in zero.&lt;/li&gt;
&lt;li&gt;Only 4 palindromes appear so far: 9999, 29092, 343343, 805508. &lt;/li&gt;
&lt;li&gt;The largest gap between consecutive terms is 26 763. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So A359012 is quite sparse, with strong biases in how its terms are embedded inside permutation values. &lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;If you want to dig into the sequence or the code, here are the main entry points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;OEIS entry (definition and references):  &lt;a href="https://oeis.org/A359012" rel="noopener noreferrer"&gt;https://oeis.org/A359012&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Live “Sequence Atlas” with the canonical dataset and dashboards (all powered directly from the CSV):  &lt;a href="https://johnsamuel.info/A359012/" rel="noopener noreferrer"&gt;https://johnsamuel.info/A359012/&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Source code, generator, and analysis scripts (Python + static site): &lt;a href="https://github.com/johnsamuelwrites/A359012" rel="noopener noreferrer"&gt;https://github.com/johnsamuelwrites/A359012&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developers might be especially interested in how the project treats an OEIS sequence as a reproducible data pipeline: generator → CSV → analysis → visual exploration. &lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>maths</category>
      <category>datascience</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Building a Fractal Explorer to Test‑Drive My Homegrown Language</title>
      <dc:creator>John Samuel</dc:creator>
      <pubDate>Sun, 08 Mar 2026 11:37:50 +0000</pubDate>
      <link>https://forem.com/jsamwrites/building-a-fractal-explorer-to-test-drive-my-homegrown-language-5aad</link>
      <guid>https://forem.com/jsamwrites/building-a-fractal-explorer-to-test-drive-my-homegrown-language-5aad</guid>
      <description>&lt;p&gt;I’ve been building a &lt;a href="https://github.com/johnsamuelwrites/multilingual" rel="noopener noreferrer"&gt;small programming language&lt;/a&gt; and needed a project that was visual, demanding, and unforgiving about performance. Fractals turned out to be the perfect testbed: they’re embarrassingly parallel, heavy on floating‑point work, and any bug shows up immediately as a glitch on the screen. &lt;/p&gt;

&lt;p&gt;In this post I’ll walk through how I wired a &lt;a href="https://multilingualprogramming.github.io/fractales/" rel="noopener noreferrer"&gt;Fractal explorer&lt;/a&gt; in the browser using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A homegrown language as the “authoring layer”&lt;/li&gt;
&lt;li&gt;WebAssembly as the execution target&lt;/li&gt;
&lt;li&gt;A minimal JavaScript shell for input and rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq1s9yfpcsoo10srk9lb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq1s9yfpcsoo10srk9lb.png" alt=" " width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Fractals Make Great Language Benchmarks
&lt;/h2&gt;

&lt;p&gt;From a distance, a fractal is just an image. From the runtime’s point of view, it’s a brutal little benchmark:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Millions of pixels, same loop shape, different data&lt;/li&gt;
&lt;li&gt;Lots of floating‑point operations&lt;/li&gt;
&lt;li&gt;Clear performance feedback: do users see results in milliseconds or seconds?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That combination makes fractals a nice stress test for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code generation quality (are we emitting tight loops?)&lt;/li&gt;
&lt;li&gt;Numeric semantics (are we handling edge cases and precision consistently?)&lt;/li&gt;
&lt;li&gt;Runtime model (do we block the UI thread, do we stream, can we refine progressively?) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike a synthetic benchmark, you also get something beautiful at the end, which keeps motivation high.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture: Language → WASM → Canvas
&lt;/h2&gt;

&lt;p&gt;The overall architecture looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write fractal logic in my language &lt;/li&gt;
&lt;li&gt;Compile to WebAssembly.&lt;/li&gt;
&lt;li&gt;Call the exported functions from JavaScript.&lt;/li&gt;
&lt;li&gt;Stream results into an &lt;code&gt;ImageData&lt;/code&gt; buffer on a &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In more detail:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Language layer&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Describes the per‑pixel computation: given coordinates and parameters, return an “escape value” that we’ll later map to color.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;WebAssembly module&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Exposes functions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;render_region(centerX, centerY, scale, width, height, maxIterations)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Writes raw iteration counts into a linear memory buffer.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;JavaScript shell&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handles input (mouse, touch, wheel).&lt;/li&gt;
&lt;li&gt;Translates viewport changes into calls to &lt;code&gt;render_region&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Maps iteration counts → RGBA and blits to the canvas. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The nice thing about this layering: I can iterate on the language and the fractal formulas without touching the UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authoring Fractals in a Custom Language
&lt;/h2&gt;

&lt;p&gt;My language’s job here is: “describe what one pixel should do.” The core concept is a pure‑ish function that takes a coordinate and some parameters and returns a scalar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input: coordinate in the complex plane, global parameters (max iterations, escape radius, etc.).&lt;/li&gt;
&lt;li&gt;Output: a number representing how “quickly” the point escapes or stabilizes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Conceptually, the code you’d write in a conventional language looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// PSEUDOCODE – the real syntax is my language&lt;/span&gt;
&lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;iterate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// map (x, y) to complex plane&lt;/span&gt;
  &lt;span class="c1"&gt;// apply small iterative rule until escape or max iterations&lt;/span&gt;
  &lt;span class="c1"&gt;// return how long it took&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the language, I deliberately kept:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No classes, minimal state&lt;/li&gt;
&lt;li&gt;Simple control flow&lt;/li&gt;
&lt;li&gt;Explicit numeric types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the target is WebAssembly, avoiding hidden allocations and dynamic dispatch makes code generation much simpler. &lt;/p&gt;

&lt;h2&gt;
  
  
  WebAssembly: Trade‑offs and Lessons
&lt;/h2&gt;

&lt;p&gt;Compiling to WebAssembly gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Near‑native inner loops in the browser&lt;/li&gt;
&lt;li&gt;A simple, linear memory model&lt;/li&gt;
&lt;li&gt;Tooling that’s getting better every year &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this project, a few practical lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Linear memory as a frame buffer&lt;/strong&gt;
I allocate a chunk of WASM memory as a raw &lt;code&gt;u32&lt;/code&gt; buffer. Each pixel gets one slot, which I fill with an integer “escape value.” JavaScript reads that buffer and maps it to colors.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Progressive refinement&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Instead of rendering full quality in one go, I can render in passes: coarse grid first, then fill in gaps. This pattern gives users immediate feedback while the WASM loops keep working. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Responsiveness vs. throughput&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You quickly learn to balance batch sizes. Large chunks make WASM efficient but can freeze the main thread; smaller chunks keep the UI snappy but add overhead. A simple “time budget per frame” works well enough. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to go further, WebAssembly threads and &lt;code&gt;SharedArrayBuffer&lt;/code&gt; open the door to true multi‑core rendering, but I kept this explorer single‑threaded to focus on the language itself. &lt;/p&gt;

&lt;h2&gt;
  
  
  The JavaScript Shell: Minimal but Important
&lt;/h2&gt;

&lt;p&gt;JavaScript is the glue layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sets up the &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; and a 2D context.&lt;/li&gt;
&lt;li&gt;Manages the viewport (center, zoom).&lt;/li&gt;
&lt;li&gt;Handles user input (drag, wheel, touch gestures).&lt;/li&gt;
&lt;li&gt;Calls into WASM with the current viewport and reads back the buffer. 
A typical render cycle looks like:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;User pans or zooms.&lt;/li&gt;
&lt;li&gt;JS updates &lt;code&gt;centerX&lt;/code&gt;, &lt;code&gt;centerY&lt;/code&gt;, &lt;code&gt;scale&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;JS calls &lt;code&gt;render_region&lt;/code&gt; on the WASM module.&lt;/li&gt;
&lt;li&gt;WASM fills its output buffer with iteration counts.&lt;/li&gt;
&lt;li&gt;JS maps those values to colors and updates &lt;code&gt;ImageData&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This separation keeps the UI code tiny and lets the language + WASM do the heavy lifting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Fractals as a Language Design Tool
&lt;/h2&gt;

&lt;p&gt;Beyond having a cool demo, fractals turned out to be surprisingly useful for language design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Semantics become visible&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Off‑by‑one errors, numeric issues, or small semantic changes show up as visible artifacts. Great for debugging semantics and codegen.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance work is rewarding&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Tightening a loop or changing a data layout translates directly into smoother zooms or higher iteration counts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;New features can be validated interactively&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Adding a new numeric type, a control‑flow construct, or a standard library function can be exercised immediately by writing a new fractal “kernel” and seeing if it behaves.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s an ongoing feedback loop: improvements in the language make the explorer better, and new ideas from the explorer push the language forward.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>programming</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Inside the Multilingual Playground: How the Browser, WASM Runtime, and Language Packs Fit Together</title>
      <dc:creator>John Samuel</dc:creator>
      <pubDate>Sat, 28 Feb 2026 09:08:11 +0000</pubDate>
      <link>https://forem.com/jsamwrites/inside-the-multilingual-playground-how-the-browser-wasm-runtime-and-language-packs-fit-together-3f27</link>
      <guid>https://forem.com/jsamwrites/inside-the-multilingual-playground-how-the-browser-wasm-runtime-and-language-packs-fit-together-3f27</guid>
      <description>&lt;p&gt;In a &lt;a href="https://dev.to/jsamwrites/from-multilingual-syntax-to-multilingual-runtimes-taking-a-human-language-first-language-to-the-web-11kk"&gt;recent article&lt;/a&gt;, I explored how a human-language-first programming language can move from &lt;em&gt;multilingual syntax&lt;/em&gt; to &lt;em&gt;multilingual runtimes&lt;/em&gt; using WebAssembly.  This post goes a level deeper and opens the hood on the browser playground that makes this possible. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/multilingualprogramming/playground" rel="noopener noreferrer"&gt;Project repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://multilingualprogramming.github.io/playground/" rel="noopener noreferrer"&gt;Online playground&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/johnsamuelwrites/multilingual" rel="noopener noreferrer"&gt;Language core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have the playground open while reading, you can map each section here to something you can actually click, run, or modify. &lt;/p&gt;




&lt;h2&gt;
  
  
  The three layers of the playground
&lt;/h2&gt;

&lt;p&gt;At a high level, the playground is three things working together: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Browser UI&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A simple HTML/CSS/JavaScript interface with: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A code editor
&lt;/li&gt;
&lt;li&gt;A language selector (English, French, Spanish, …)
&lt;/li&gt;
&lt;li&gt;A “Run” button
&lt;/li&gt;
&lt;li&gt;Panels for program output and intermediate representations
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;WASM runtime&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The multilingual interpreter, compiled to WebAssembly, plus a few helper pieces that make it easy to call from JavaScript.  The interpreter does the heavy lifting: lexing, parsing, building the AST, and evaluating the program. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Language packs&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Data that describes how each human language maps to the shared semantic core: keywords, operators, sometimes punctuation, and eventually error messages.  Each pack is configuration, not a fork of the runtime, which is key to keeping the system maintainable. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can think of it as: &lt;strong&gt;HTML talks to JS, JS talks to WASM, WASM talks to your code — and language packs change only the “accent”, not the meaning.&lt;/strong&gt; &lt;/p&gt;




&lt;h2&gt;
  
  
  From source code to execution in the browser
&lt;/h2&gt;

&lt;p&gt;When you write a program in the playground and hit “Run”, the flow is roughly: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Collect source and language choice&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The UI grabs the text from the editor and the selected human language (for example, &lt;code&gt;fr&lt;/code&gt; or &lt;code&gt;en&lt;/code&gt;). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Call into the WASM module&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
JavaScript passes &lt;code&gt;{ source, language_id }&lt;/code&gt; into an exported WASM function via &lt;code&gt;WebAssembly.instantiate&lt;/code&gt; bindings.  Internally, the WASM module sees raw bytes and a language identifier, not “French” or “English” in any special way. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lexing and parsing with language packs&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Inside the WASM runtime, the lexer and parser look up the right keyword mapping for the chosen language pack.  &lt;code&gt;si&lt;/code&gt;, &lt;code&gt;wenn&lt;/code&gt;, and &lt;code&gt;if&lt;/code&gt; can all map to the same conditional AST node, regardless of the surface language. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build the unified AST&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The parser produces a single, language-agnostic AST.  From this point on, the runtime is completely indifferent to which human language you wrote in. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Evaluate and send results back&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The interpreter evaluates the AST, captures outputs and errors, and sends structured results back across the JS/WASM boundary.  The browser then renders them in the output panel. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All of this happens inside a sandboxed environment in your browser, which is why learners only need a URL to experiment. &lt;/p&gt;




&lt;h2&gt;
  
  
  How language packs plug into the core
&lt;/h2&gt;

&lt;p&gt;The language packs are what make the playground &lt;em&gt;multilingual&lt;/em&gt; instead of just another monolingual WebAssembly demo. &lt;/p&gt;

&lt;p&gt;A language pack typically contains things like: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keyword mappings: &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, etc. in a given language mapped to internal tokens or constructors
&lt;/li&gt;
&lt;li&gt;Logical operator names (&lt;code&gt;and&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt;, &lt;code&gt;not&lt;/code&gt;)
&lt;/li&gt;
&lt;li&gt;Literal conventions if they differ (for example, decimal separator)
&lt;/li&gt;
&lt;li&gt;Metadata like language name and code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, the runtime does something conceptually like this: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look up &lt;code&gt;language_id&lt;/code&gt; in a registry of packs
&lt;/li&gt;
&lt;li&gt;Build lexer/parser tables using that pack’s tokens
&lt;/li&gt;
&lt;li&gt;Produce the same internal AST no matter which pack you used&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the packs are configuration, adding a language is “just” adding some new lines and wiring it into the registry rather than forking the interpreter.  That design is what makes it realistic to experiment with 10+ human languages without drowning in maintenance. &lt;/p&gt;

&lt;p&gt;A nice side effect: the playground can show you the &lt;em&gt;same&lt;/em&gt; program rendered in different surface syntaxes while keeping the underlying semantics identical. &lt;/p&gt;




&lt;h2&gt;
  
  
  Error handling and diagnostics today (and tomorrow)
&lt;/h2&gt;

&lt;p&gt;Error handling is where multilingual runtimes get interesting. &lt;/p&gt;

&lt;p&gt;Right now, the playground leans on a simple but powerful separation: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The core interpreter produces &lt;strong&gt;language-agnostic error codes and structures&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;The browser UI is responsible for displaying those errors to the user in a friendly way. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That design opens the door to more advanced diagnostics: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Localized error message catalogs keyed by error code
&lt;/li&gt;
&lt;li&gt;The ability to show errors in the same human language as the source
&lt;/li&gt;
&lt;li&gt;Potentially toggling the language of diagnostics without rerunning the program&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, the same parse error could be rendered in French and then in English just by swapping the message catalog, while the underlying error object stays the same.  A WASM-based playground is a convenient place to prototype this because everything is already running in the browser and can react in real time. &lt;/p&gt;




&lt;h2&gt;
  
  
  Deployment and extensibility
&lt;/h2&gt;

&lt;p&gt;From a deployment perspective, the playground is just static assets: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML and CSS for the UI
&lt;/li&gt;
&lt;li&gt;JavaScript glue code
&lt;/li&gt;
&lt;li&gt;The compiled WASM binary
&lt;/li&gt;
&lt;li&gt;JSON or similar files for language packs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes it easy to host on GitHub Pages or a personal site, as in the current playground.  Once the interpreter is compiled to WASM, the same core can also be reused in other contexts: online textbooks, documentation, or even IDE extensions via a WASI environment. &lt;/p&gt;

&lt;p&gt;There are several natural directions to extend this setup: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More &lt;strong&gt;language packs&lt;/strong&gt;, including scripts and writing systems that stretch assumptions about keywords and layout
&lt;/li&gt;
&lt;li&gt;Richer &lt;strong&gt;visualizations&lt;/strong&gt; of the pipeline (for example, showing WAT or internal AST alongside your code)
&lt;/li&gt;
&lt;li&gt;Embeddable widgets where the multilingual runtime appears inside tutorials and interactive learning material&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try the playground and experiment with new languages or ideas for diagnostics, I would love feedback and contributions in the repository. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/multilingualprogramming/playground" rel="noopener noreferrer"&gt;Project repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://multilingualprogramming.github.io/playground/" rel="noopener noreferrer"&gt;Online playground&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/johnsamuelwrites/multilingual" rel="noopener noreferrer"&gt;Language core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webassembly</category>
      <category>programming</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>From Multilingual Syntax to Multilingual Runtimes: Taking a Human-Language-First Language to the Web</title>
      <dc:creator>John Samuel</dc:creator>
      <pubDate>Tue, 24 Feb 2026 18:25:51 +0000</pubDate>
      <link>https://forem.com/jsamwrites/from-multilingual-syntax-to-multilingual-runtimes-taking-a-human-language-first-language-to-the-web-11kk</link>
      <guid>https://forem.com/jsamwrites/from-multilingual-syntax-to-multilingual-runtimes-taking-a-human-language-first-language-to-the-web-11kk</guid>
      <description>&lt;p&gt;In my previous post, I introduced &lt;strong&gt;multilingual&lt;/strong&gt;, an experimental programming language where the same abstract syntax tree can be written in English, French, Spanish, and other human languages while preserving identical semantics. That work focused on the &lt;em&gt;surface&lt;/em&gt; of the language: how we let people read and write code in the language they are most comfortable with, without changing what the program does. &lt;/p&gt;

&lt;p&gt;In this follow-up, I want to go one step further and ask: what happens when you bring this idea to the &lt;strong&gt;Web&lt;/strong&gt; and to &lt;strong&gt;WebAssembly (WASM)&lt;/strong&gt;?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can a single semantic core, expressed in multiple human languages, also have a single, portable runtime story?&lt;/li&gt;
&lt;li&gt;How far can we push this idea before “multilingual” stops being just a toy language and starts looking like a serious experimentation platform for human-language–aware tooling?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To explore these questions, I’ve been experimenting with compiling the multilingual interpreter and tooling to WASM and exposing it through a browser playground.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project repository: &lt;a href="https://github.com/johnsamuelwrites/multilingual" rel="noopener noreferrer"&gt;https://github.com/johnsamuelwrites/multilingual&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Online playground: &lt;a href="https://johnsamuel.info/multilingual/playground.html" rel="noopener noreferrer"&gt;https://johnsamuel.info/multilingual/playground.html&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Recap: One Semantic Core, Many Human Languages
&lt;/h2&gt;

&lt;p&gt;The core idea of &lt;strong&gt;multilingual&lt;/strong&gt; is simple to state but surprisingly rich to work with: you write code in different human languages, but it all maps to the &lt;em&gt;same&lt;/em&gt; underlying AST and semantics. &lt;/p&gt;

&lt;p&gt;In practice, that means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is a single, language-agnostic core language: control flow, expressions, and data structures live here.&lt;/li&gt;
&lt;li&gt;Human languages appear as &lt;strong&gt;mappings&lt;/strong&gt; from localized keywords and identifiers to that core: for example, &lt;code&gt;if&lt;/code&gt; / &lt;code&gt;si&lt;/code&gt; / &lt;code&gt;si&lt;/code&gt; (English/French/Spanish) all map to the same conditional node. &lt;/li&gt;
&lt;li&gt;The interpreter never “cares” whether your source was French or English; by the time it runs, it is operating on the unified AST. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation is what enables &lt;strong&gt;multilingual&lt;/strong&gt; to be more than a localized syntax layer on top of an existing language: it is an experiment in treating human language as a first-class dimension of the programming environment itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why WebAssembly Matters for a Multilingual Language
&lt;/h2&gt;

&lt;p&gt;If you have a language whose goal is to welcome developers in multiple human languages, you want the &lt;strong&gt;runtime&lt;/strong&gt; to be equally portable.&lt;/p&gt;

&lt;p&gt;WebAssembly is particularly interesting in this context because it gives us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;sandboxed, predictable execution model&lt;/strong&gt; that runs in modern browsers and outside the browser in WASI environments. &lt;/li&gt;
&lt;li&gt;A well-defined &lt;strong&gt;binary target&lt;/strong&gt; for compilers and interpreters written in languages like C, C++, and Rust. &lt;/li&gt;
&lt;li&gt;A path to reuse the same core, even if the surface syntax varies dramatically across human languages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an experimental language like &lt;strong&gt;multilingual&lt;/strong&gt;, WASM offers two big advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can ship the whole interpreter and tooling directly into the browser, so learners only need a URL, not an installation guide.&lt;/li&gt;
&lt;li&gt;You can treat the Web as a live laboratory to test multilingual error messages, editor integrations, and teaching scenarios.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In other words, if the goal is to make programming more approachable in more human languages, WASM lets us &lt;em&gt;meet people where they already are&lt;/em&gt;: in the browser.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Playground: A Multilingual Interpreter in Your Browser
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;playground&lt;/strong&gt; is the first concrete step in that direction: it loads the language core in the browser and lets you write and run programs in different human languages side by side. &lt;/p&gt;

&lt;p&gt;Playground: &lt;a href="https://johnsamuel.info/multilingual/playground.html" rel="noopener noreferrer"&gt;https://johnsamuel.info/multilingual/playground.html&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;At a high level, the architecture looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The core interpreter is compiled to WebAssembly using a systems language toolchain. &lt;/li&gt;
&lt;li&gt;The browser page handles text input, language selection, and UI in plain HTML/CSS/JavaScript.&lt;/li&gt;
&lt;li&gt;When you run code, the UI sends your multilingual source to the WASM module, which parses it, builds the AST, and executes it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation mirrors the language design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;UI&lt;/strong&gt; is responsible for dealing with the user’s language preferences, fonts, directionality, and input quirks.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;WASM module&lt;/strong&gt; is responsible for understanding the core language and enforcing identical semantics regardless of human language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the interpreter runs entirely in the browser, you also get some nice side-effects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No server-side execution is required, which simplifies deployment.&lt;/li&gt;
&lt;li&gt;You can experiment with new keyword mappings and language packs and immediately see their behavior.&lt;/li&gt;
&lt;li&gt;The environment is inherently sandboxed, piggybacking on the browser’s security model.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Multilingual Error Messages and Diagnostics
&lt;/h2&gt;

&lt;p&gt;Once you have a language that can be written in multiple human languages and a runtime that can be delivered as WASM, the next natural step is &lt;strong&gt;tooling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In a traditional language, error messages are often an afterthought. In a multilingual language, they become central:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Syntax errors can be reported in the same human language as the source code.&lt;/li&gt;
&lt;li&gt;Error &lt;em&gt;hints&lt;/em&gt; can guide beginners using vocabulary that makes sense in their linguistic context.&lt;/li&gt;
&lt;li&gt;In mixed-language codebases, you can imagine selectively switching diagnostic languages without changing the underlying program.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A WASM-based playground is a great place to prototype this because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can build a small, &lt;strong&gt;interactive REPL&lt;/strong&gt; where users see errors in real time.&lt;/li&gt;
&lt;li&gt;You can experiment with toggling error-message languages without reloading or recompiling.&lt;/li&gt;
&lt;li&gt;You can embed teaching material directly in the browser, close to the diagnostics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From an implementation standpoint, this suggests a clear design direction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep error codes and structures language-agnostic in the core.&lt;/li&gt;
&lt;li&gt;Maintain localized message catalogs and explanations in separate resources, possibly keyed by the same identifiers used for keywords.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Thinking Ahead: Multilingual Tooling, IDEs, and Beyond
&lt;/h2&gt;

&lt;p&gt;WASM is not just a deployment target; it is a &lt;strong&gt;bridge&lt;/strong&gt; between language runtimes and modern developer tools.&lt;/p&gt;

&lt;p&gt;Once you have the &lt;strong&gt;multilingual&lt;/strong&gt; core compiled to WASM, several possibilities open up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Embeddable interpreters in online textbooks and tutorials, where each reader can choose their preferred human language.&lt;/li&gt;
&lt;li&gt;Language-server–like functionality running in the browser, providing autocompletion and diagnostics for multilingual code.&lt;/li&gt;
&lt;li&gt;Integration with “traditional” editors via a WASI runtime, so the same core can power both web and desktop experiences.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This also connects to broader work on multilingual programming and natural-language–friendly programming environments. The long-term question is not just “can we localize keywords?” but “what does a programming ecosystem look like when human language is no longer an afterthought?” &lt;a href="https://stackoverflow.com/questions/667720/truly-multi-lingual-programming-languages" rel="noopener noreferrer"&gt;stackoverflow&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;A few directions I am exploring and would love feedback on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Richer language packs&lt;/strong&gt;: extending and experimenting with scripts and writing systems that challenge our assumptions about syntax.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More powerful WASM integrations&lt;/strong&gt;: exploring how far we can push the browser-based environment (e.g., file-like APIs via WASI, richer visualization of program state).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community-contributed mappings&lt;/strong&gt;: making it easier for contributors to define and share mappings for their own languages via simple configuration files in the repository. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are interested in any of these ideas, want to try the language, or have thoughts on making programming more inclusive across human languages, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Experiment in the playground: &lt;a href="https://johnsamuel.info/multilingual/playground.html" rel="noopener noreferrer"&gt;https://johnsamuel.info/multilingual/playground.html&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Read the original post introducing the language: &lt;a href="https://dev.to/jsamwrites/a-multilingual-programming-language-where-the-same-ast-runs-english-french-spanish-etc-23bd"&gt;https://dev.to/jsamwrites/a-multilingual-programming-language-where-the-same-ast-runs-english-french-spanish-etc-23bd&lt;/a&gt; &lt;a href="https://www.reddit.com/r/ProgrammingLanguages/comments/1r860hw/multilingual_a_programming_language_with_one/" rel="noopener noreferrer"&gt;reddit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Browse or contribute to the source: &lt;a href="https://github.com/johnsamuelwrites/multilingual" rel="noopener noreferrer"&gt;https://github.com/johnsamuelwrites/multilingual&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would love to hear how you imagine using a human-language–first programming environment in your own work or teaching.&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>programming</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A multilingual programming language where the same AST runs English, French, Spanish, etc.</title>
      <dc:creator>John Samuel</dc:creator>
      <pubDate>Sat, 21 Feb 2026 14:37:49 +0000</pubDate>
      <link>https://forem.com/jsamwrites/a-multilingual-programming-language-where-the-same-ast-runs-english-french-spanish-etc-23bd</link>
      <guid>https://forem.com/jsamwrites/a-multilingual-programming-language-where-the-same-ast-runs-english-french-spanish-etc-23bd</guid>
      <description>&lt;h2&gt;
  
  
  What if the only thing that changed between English and French code was the surface syntax, not the interpreter?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;tl;dr&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. One tiny semantic core, many language-specific “frontends”.&lt;/li&gt;
&lt;li&gt;2. Code written in French, English, etc. maps to the same AST and runtime.&lt;/li&gt;
&lt;li&gt;3. You can swap surface languages without changing the underlying program.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F676fzf4lkmigjsnacxqp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F676fzf4lkmigjsnacxqp.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most programming languages quietly assume that you think in English.&lt;br&gt;&lt;br&gt;
Keywords, error messages, tutorials, library names – everything is shaped around one language, even when the underlying semantics are universal.&lt;/p&gt;

&lt;p&gt;I’ve been experimenting with a different approach: keep a tiny, shared semantic core, and let the &lt;em&gt;surface syntax&lt;/em&gt; (keywords, word order) adapt to the programmer’s natural language.&lt;br&gt;&lt;br&gt;
The result is an interpreter where the &lt;strong&gt;same AST&lt;/strong&gt; can execute code written in French, English, Spanish, Arabic, Japanese, and more – without a translation step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repository&lt;/strong&gt;: &lt;a href="https://github.com/johnsamuelwrites/multilingual" rel="noopener noreferrer"&gt;https://github.com/johnsamuelwrites/multilingual&lt;/a&gt;  &lt;/p&gt;


&lt;h3&gt;
  
  
  Why separate surface syntax from the core?
&lt;/h3&gt;

&lt;p&gt;When we teach or learn programming, we often say “syntax is just sugar, what really matters is semantics.”&lt;br&gt;&lt;br&gt;
But in practice, syntax is where beginners feel the most friction – especially if they’re also learning English at the same time.&lt;/p&gt;

&lt;p&gt;The idea here is to pull that intuition to the extreme:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep one small semantic core (conditions, functions, variables, blocks, etc.).
&lt;/li&gt;
&lt;li&gt;Describe each human language as a thin “frontend” that maps its own keywords and patterns into that core.
&lt;/li&gt;
&lt;li&gt;Make these mappings explicit and inspectable, instead of hard-coding English everywhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This lets you ask questions like: &lt;em&gt;what would this program look like if all the keywords were in French or Spanish?&lt;/em&gt; – while still running through the same interpreter pipeline.&lt;/p&gt;


&lt;h3&gt;
  
  
  How the interpreter is structured
&lt;/h3&gt;

&lt;p&gt;How the interpreter is structured&lt;br&gt;
At a high level, the interpreter is split into three layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Surface syntax layer&lt;/strong&gt; – Knows about keywords and word order for a specific human language (e.g., if vs si, print vs afficher). It only parses and normalizes, it never executes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic core&lt;/strong&gt; – A small, language‑agnostic core with expressions, statements, control flow, function calls, and environments. This is where the AST lives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime / execution engine&lt;/strong&gt; – Walks the core AST and evaluates it. At this point, the runtime is completely blind to the human language you used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each surface syntax module is responsible for normalizing its input into the same core representation.&lt;br&gt;&lt;br&gt;
That’s where most of the interesting language-design questions arise.&lt;/p&gt;


&lt;h3&gt;
  
  
  A tiny example
&lt;/h3&gt;

&lt;p&gt;Suppose you want to express a simple conditional and a loop.&lt;/p&gt;

&lt;p&gt;In an English-shaped surface syntax, you might write something close to Python-like pseudocode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if x &amp;gt; 0:
    print("positive")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a French surface syntax, the structure is analogous but with French keywords (this is illustrative – see the repo for the real examples):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;si x &amp;gt; 0:
    afficher("positif")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both of these are parsed into the &lt;em&gt;same&lt;/em&gt; core AST node: a conditional expression with a predicate and a block.&lt;br&gt;&lt;br&gt;
The runtime never needs to know whether the original keyword was &lt;code&gt;if&lt;/code&gt; or &lt;code&gt;si&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The same idea extends to loops, function definitions, and so on.&lt;/p&gt;




&lt;h3&gt;
  
  
  Another tiny example
&lt;/h3&gt;

&lt;p&gt;Suppose you want to write a function that prints numbers from 1 to 3 if a flag is set.&lt;/p&gt;

&lt;h1&gt;
  
  
  English-shaped surface syntax
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if enabled:
  for n in 1..3:
    print(n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  French-shaped surface syntax (illustrative)
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;si actif:
  pour n dans 1..3:
    afficher(n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both programs are parsed into the same core AST: a conditional node whose body contains a loop over a range and a call to a print function. The runtime never needs to know whether the original keyword was if or si.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this might be useful
&lt;/h3&gt;

&lt;p&gt;This is still an experiment, but a few potential use cases are emerging:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Teaching in non-English contexts&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Instructors can show code with keywords in the students’ own language, while still having a single, shared semantic model under the hood.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Research on multilingual PL design&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
It becomes easier to compare how different natural languages “want” to express the same control structures, and where word-order differences start to matter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Accessibility and experimentation&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
People can prototype their own keyword sets or dialects without forking the whole interpreter, as long as they can map back to the core.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Open questions and limitations
&lt;/h3&gt;

&lt;p&gt;There are plenty of hard questions I’m still exploring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How far can you push word-order differences before the surface layer becomes too complex?
&lt;/li&gt;
&lt;li&gt;How do you keep each mapping semantics-preserving, and how do you &lt;em&gt;test&lt;/em&gt; that rigorously?
&lt;/li&gt;
&lt;li&gt;Where do you draw the line between “just syntax” and constructs that really should live in the core language?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Right now, the project is deliberately small and experimental; the focus is on keeping the core minimal and making the mappings explicit, rather than covering every possible language feature.&lt;/p&gt;




&lt;h3&gt;
  
  
  How to try it, and how you can help
&lt;/h3&gt;

&lt;p&gt;If this idea interests you, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check out the repo: &lt;a href="https://github.com/johnsamuelwrites/multilingual" rel="noopener noreferrer"&gt;https://github.com/johnsamuelwrites/multilingual&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Run the examples and look at how the surface syntax modules map into the core.
&lt;/li&gt;
&lt;li&gt;Open issues or PRs with:

&lt;ul&gt;
&lt;li&gt;new language mappings,
&lt;/li&gt;
&lt;li&gt;critiques of the core design,
&lt;/li&gt;
&lt;li&gt;ideas for better ways to specify and test the semantics.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>showdev</category>
      <category>beginners</category>
      <category>python</category>
    </item>
  </channel>
</rss>
