<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>foss &amp;mdash; Noordstar Blog</title>
    <link>https://noordstar.me/tag:foss</link>
    <description>Homepage and blog by Bram Noordstar</description>
    <pubDate>Thu, 16 Apr 2026 04:43:51 +0000</pubDate>
    <item>
      <title>Hey, you found my blog</title>
      <link>https://noordstar.me/hey-you-found-my-blog</link>
      <description>&lt;![CDATA[I write here because I like writing. Simple as that. Some of it is technical, some of it is just thoughts and little ideas. No tracking, no engagement farming or ads - just words on a page.&#xA;&#xA;Things you might be looking for&#xA;&#xA;Blog posts - Browse the latest or check out posts by topic&#xA;Code &amp; Projects - My GitHub or Git server&#xA;Self-hosted services - If you&#39;re a friend or family member looking for something, you probably already know where to go. If not, ask me directly.&#xA;Contact - Reach out to me on Matrix&#xA;&#xA;Who I am&#xA;&#xA;I like open source, decentralized tech, and figuring things out for myself. I love D&amp;D, public transport and Europe. I would&#39;ve liked to use the term cyberpunk to describe my blog, hadn&#39;t it already been used to describe a dystopian hyper-capitalist setting.&#xA;&#xA;Hashtags&#xA;&#xA;Use any of these hashtags to find posts about that topic!&#xA;&#xA;#bayesian #doomsdayargument #foss #functional #korea #languagedesign #maths #philosophy #politics #publictransport #regulation #segmentdisplay #traffic]]&gt;</description>
      <content:encoded><![CDATA[<p>I write here because I like writing. Simple as that. Some of it is technical, some of it is just thoughts and little ideas. No tracking, no engagement farming or ads – just words on a page.</p>

<h2 id="things-you-might-be-looking-for" id="things-you-might-be-looking-for">Things you might be looking for</h2>
<ul><li><strong>Blog posts</strong> – Browse the latest or check out posts by topic</li>
<li><strong>Code &amp; Projects</strong> – My <a href="https://github.com/BramvdnHeuvel">GitHub</a> or <a href="https://git.noordstar.me/explore/repos">Git server</a></li>
<li><strong>Self-hosted services</strong> – If you&#39;re a friend or family member looking for something, you probably already know where to go. If not, ask me directly.</li>
<li><strong>Contact</strong> – Reach out to me on <a href="https://matrix.to/#/@bram:matrix.directory">Matrix</a></li></ul>

<h2 id="who-i-am" id="who-i-am">Who I am</h2>

<p>I like open source, decentralized tech, and figuring things out for myself. I love D&amp;D, public transport and Europe. I would&#39;ve liked to use the term cyberpunk to describe my blog, hadn&#39;t it already been used to describe a dystopian hyper-capitalist setting.</p>

<h2 id="hashtags" id="hashtags">Hashtags</h2>

<p>Use any of these hashtags to find posts about that topic!</p>

<p><a href="https://noordstar.me/tag:bayesian" class="hashtag"><span>#</span><span class="p-category">bayesian</span></a> <a href="https://noordstar.me/tag:doomsdayargument" class="hashtag"><span>#</span><span class="p-category">doomsdayargument</span></a> <a href="https://noordstar.me/tag:foss" class="hashtag"><span>#</span><span class="p-category">foss</span></a> <a href="https://noordstar.me/tag:functional" class="hashtag"><span>#</span><span class="p-category">functional</span></a> <a href="https://noordstar.me/tag:korea" class="hashtag"><span>#</span><span class="p-category">korea</span></a> <a href="https://noordstar.me/tag:languagedesign" class="hashtag"><span>#</span><span class="p-category">languagedesign</span></a> <a href="https://noordstar.me/tag:maths" class="hashtag"><span>#</span><span class="p-category">maths</span></a> <a href="https://noordstar.me/tag:philosophy" class="hashtag"><span>#</span><span class="p-category">philosophy</span></a> <a href="https://noordstar.me/tag:politics" class="hashtag"><span>#</span><span class="p-category">politics</span></a> <a href="https://noordstar.me/tag:publictransport" class="hashtag"><span>#</span><span class="p-category">publictransport</span></a> <a href="https://noordstar.me/tag:regulation" class="hashtag"><span>#</span><span class="p-category">regulation</span></a> <a href="https://noordstar.me/tag:segmentdisplay" class="hashtag"><span>#</span><span class="p-category">segmentdisplay</span></a> <a href="https://noordstar.me/tag:traffic" class="hashtag"><span>#</span><span class="p-category">traffic</span></a></p>
]]></content:encoded>
      <guid>https://noordstar.me/hey-you-found-my-blog</guid>
      <pubDate>Wed, 21 Jan 2026 11:43:26 +0000</pubDate>
    </item>
    <item>
      <title>Delving into language design: what I&#39;ve learned so far</title>
      <link>https://noordstar.me/delving-into-language-design-what-ive-learned-so-far</link>
      <description>&lt;![CDATA[As can be read in my first blog post, I intend to build an Elm-like language with some unique design choices - and the community has taught me some valuable things!&#xA;&#xA;TLDR: My design seems akin to cutting-edge programming languages. I have a functional proof-of-concept! I&#39;m not content with the syntax yet.&#xA;&#xA;My idea isn&#39;t original - but it seems new&#xA;&#xA;One of the most intriguing parallels to selective mutability I&#39;ve discovered is the &#34;resurrection hypothesis&#34; mentioned in a 2019 paper called Counting Immutable Beans. The resurrection hypothesis mentions the idea that many objects die just before the creation of an object of the same kind.&#xA;&#xA;The map function is a great example to this:&#xA;&#xA;type Tree a = Leaf a | Node (Tree a) (Tree a)&#xA;&#xA;map : (a -  b) -  Tree a -  Tree b&#xA;map f tree =&#xA;    case tree of&#xA;        Leaf x -  Leaf (f x)&#xA;&#xA;        Node tree1 tree2 -  Node (map f tree1) (map f tree2)&#xA;&#xA;If the language is purely immutable, then you might use twice the memory necessary: you would traverse through the tree, build a new tree with the identical structure, and then discard the old one. But imagine that the update function of our MUV-system looks like this:&#xA;&#xA;type alias Model = { name : String, tree : Tree Int }&#xA;&#xA;update : Int -  Model -  Model&#xA;update n model =&#xA;    { model | tree = map (\x -  x * 2 } model.tree }&#xA;&#xA;Most immutable languages would duplicate the tree and discard the old one, effectively doubling memory usage. But with selective mutability, the tree could be updated in-place.&#xA;&#xA;There&#39;s also other programming languages developing similar ideas. Research language Koka uses Perceus, an algorithm that offers reference counting in a way that avoids a garbage collector. Similarly, Neut does what they call static memory management, where they find malloc/free pairs of matching sizes to optimize around the resurrection hypothesis.&#xA;&#xA;A proof-of-concept works - for now&#xA;&#xA;As an experiment, I have built a proof-of-concept transpiled version. A major challenge with catching memory problems is that most OS systems aren&#39;t built for catching memory issues. From my understanding, C, LLVM and Rust typically rely on the OS to manage the stack &amp; heap. If there&#39;s an overflow, or some other problem, the OS terminates the program, reporting a segmentation fault. Not very helpful!&#xA;&#xA;As a result, I have designed my own stack/heap system in a C program. Similar to a VM, the code runs in a single block of memory that&#39;s assigned to the program on startup. It functions reliably, regardless of available memory size.&#xA;&#xA;For now, this snippet represents the decompiled version of the file low.c:&#xA;&#xA;main =&#xA;    h &#34;Kaokkokos shall prevail by the hands of Alkbaard!&#34;&#xA;&#xA;h : String -  String&#xA;h x = f ( g x )&#xA;&#xA;f : String -  String&#xA;f = String.upper&#xA;&#xA;g : String -  String&#xA;g = Console.print -- currently an identity function with side-effects&#xA;&#xA;This proof-of-concept shows that a memory-aware runtime is feasible, though Mem.withDefault handling is still pending implementation.&#xA;&#xA;Memory-aware language design might need some changes&#xA;&#xA;There&#39;s two major challenges with a design using =   operations. It&#39;s a difficult concept to understand, and it limits the capability for the language to compile to environments where memory cannot be managed.&#xA;&#xA;As a result, it might be rewarding to design the types in a Mem module that is only usable in environments where memory CAN be managed. This has several downsides to be considered, but the confusion of the =   operation might not necessarily be a better directly. For example, consider the following two functions:&#xA;&#xA;-- Example 1&#xA;foo1 : Foo =  Foo -  Foo&#xA;foo1 x =&#xA;    (\y -  bar x y )&#xA;        |  Mem.withDefault identity&#xA;&#xA;-- Example 2&#xA;foo2 : Foo -  Foo =  Foo&#xA;foo2 x y =&#xA;    bar x y&#xA;        |  Mem.withDefault defaultFoo&#xA;&#xA;Both functions are essentially different, offering different guarantees in different scenarios. While foo1 is guaranteeing to return a Foo type when two Foo types have been inserted, foo2 guarantees to return a Foo -  Foo function after one Foo type has been inserted. This works, but is it easy to understand?&#xA;&#xA;Also, the guarantee of memory sounds relatively reasonable when you look at the code, but how much effort would it cost to write a function that is 100% memory aware?&#xA;&#xA;foo : Foo =  Foo =  Foo&#xA;foo x =&#xA;    (\y -  bar x y |  Mem.withDefault defaultFoo )&#xA;        |  Mem.withDefault identity&#xA;&#xA;This is a rather unappealing way to write code, and quite difficult to read. This might need some reworking.&#xA;&#xA;Conclusion&#xA;&#xA;I have learned a few more concepts and the development seems to go rather well! I am encountering less hurdles than expected, and the design seems manageable.&#xA;&#xA;As with the previous post, I am very much open to ideas. Let me know if you have any thoughts to share!&#xA;&#xA;#foss #functional #languagedesign&#xA;&#xA;---&#xA;&#xA;Older English post &lt;&lt;     Newer English post&#xA;&#xA;Older post &lt;&lt;     Newer post]]&gt;</description>
      <content:encoded><![CDATA[<p>As can be read in my <a href="https://blog.noordstar.me/designing-a-memory-safe-purely-functional-programming-language">first blog post</a>, I intend to build an Elm-like language with some unique design choices – and the community has taught me some valuable things!</p>

<p><strong>TLDR:</strong> My design seems akin to cutting-edge programming languages. I have a <a href="https://git.noordstar.me/Bram/new-lang">functional proof-of-concept</a>! I&#39;m not content with the syntax yet.</p>

<h2 id="my-idea-isn-t-original-but-it-seems-new" id="my-idea-isn-t-original-but-it-seems-new">My idea isn&#39;t original – but it seems new</h2>

<p>One of the most intriguing parallels to <strong>selective mutability</strong> I&#39;ve discovered is the “resurrection hypothesis” mentioned in a 2019 paper called <a href="https://arxiv.org/abs/1908.05647">Counting Immutable Beans</a>. The resurrection hypothesis mentions the idea that many objects die just before the creation of an object of the same kind.</p>

<p>The <code>map</code> function is a great example to this:</p>

<pre><code class="language-elm">type Tree a = Leaf a | Node (Tree a) (Tree a)

map : (a -&gt; b) -&gt; Tree a -&gt; Tree b
map f tree =
    case tree of
        Leaf x -&gt;
            Leaf (f x)

        Node tree1 tree2 -&gt;
           Node (map f tree1) (map f tree2)
</code></pre>

<p>If the language is purely immutable, then you might use twice the memory necessary: you would traverse through the tree, build a new tree with the identical structure, and then discard the old one. But imagine that the <code>update</code> function of our MUV-system looks like this:</p>

<pre><code class="language-elm">type alias Model = { name : String, tree : Tree Int }

update : Int -&gt; Model -&gt; Model
update n model =
    { model | tree = map (\x -&gt; x * 2 } model.tree }
</code></pre>

<p>Most immutable languages would duplicate the tree and discard the old one, effectively doubling memory usage. But with selective mutability, the tree could be updated in-place.</p>

<p>There&#39;s also other programming languages developing similar ideas. Research language <a href="https://koka-lang.github.io/koka/doc/index.html">Koka</a> uses <a href="https://www.microsoft.com/en-us/research/publication/perceus-garbage-free-reference-counting-with-reuse/">Perceus</a>, an algorithm that offers reference counting in a way that avoids a garbage collector. Similarly, <a href="https://vekatze.github.io/neut/overview.html">Neut</a> does what they call <a href="https://vekatze.github.io/neut/static-memory-management.html">static memory management</a>, where they find malloc/free pairs of matching sizes to optimize around the resurrection hypothesis.</p>

<h2 id="a-proof-of-concept-works-for-now" id="a-proof-of-concept-works-for-now">A proof-of-concept works – for now</h2>

<p>As an experiment, I have built <a href="https://git.noordstar.me/Bram/new-lang">a proof-of-concept transpiled version</a>. A major challenge with catching memory problems is that most OS systems aren&#39;t built for catching memory issues. From my understanding, C, LLVM and Rust typically rely on the OS to manage the stack &amp; heap. If there&#39;s an overflow, or some other problem, the OS terminates the program, reporting a segmentation fault. Not very helpful!</p>

<p>As a result, I have designed my own stack/heap system in a C program. Similar to a VM, the code runs in a single block of memory that&#39;s assigned to the program on startup. It functions reliably, regardless of available memory size.</p>

<p>For now, this snippet represents the decompiled version of the <a href="https://git.noordstar.me/Bram/new-lang/src/commit/d54125daa6d1f42dc844ba425c122ba2d739235c/low.c">file low.c</a>:</p>

<pre><code class="language-elm">main =
    h &#34;Kaokkokos shall prevail by the hands of Alkbaard!&#34;

h : String -&gt; String
h x = f ( g x )

f : String -&gt; String
f = String.upper

g : String -&gt; String
g = Console.print -- currently an identity function with side-effects
</code></pre>

<p>This proof-of-concept shows that a memory-aware runtime is feasible, though Mem.withDefault handling is still pending implementation.</p>

<h2 id="memory-aware-language-design-might-need-some-changes" id="memory-aware-language-design-might-need-some-changes">Memory-aware language design might need some changes</h2>

<p>There&#39;s two major challenges with a design using <code>=&gt;</code> operations. It&#39;s a difficult concept to understand, and it limits the capability for the language to compile to environments where memory cannot be managed.</p>

<p>As a result, it might be rewarding to design the types in a <code>Mem</code> module that is only usable in environments where memory <strong>CAN</strong> be managed. This has several downsides to be considered, but the confusion of the <code>=&gt;</code> operation might not necessarily be a better directly. For example, consider the following two functions:</p>

<pre><code class="language-elm">-- Example 1
foo1 : Foo =&gt; Foo -&gt; Foo
foo1 x =
    (\y -&gt; bar x y )
        |&gt; Mem.withDefault identity

-- Example 2
foo2 : Foo -&gt; Foo =&gt; Foo
foo2 x y =
    bar x y
        |&gt; Mem.withDefault defaultFoo
</code></pre>

<p>Both functions are essentially different, offering different guarantees in different scenarios. While <code>foo1</code> is guaranteeing to return a <code>Foo</code> type when two <code>Foo</code> types have been inserted, <code>foo2</code> guarantees to return a <code>Foo -&gt; Foo</code> function after one <code>Foo</code> type has been inserted. This works, but is it easy to understand?</p>

<p>Also, the guarantee of memory sounds relatively reasonable when you look at the code, but how much effort would it cost to write a function that is 100% memory aware?</p>

<pre><code class="language-elm">foo : Foo =&gt; Foo =&gt; Foo
foo x =
    (\y -&gt; bar x y |&gt; Mem.withDefault defaultFoo )
        |&gt; Mem.withDefault identity
</code></pre>

<p>This is a rather unappealing way to write code, and quite difficult to read. This might need some reworking.</p>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>I have learned a few more concepts and the development seems to go rather well! I am encountering less hurdles than expected, and the design seems manageable.</p>

<p>As with the <a href="https://blog.noordstar.me/designing-a-memory-safe-purely-functional-programming-language">previous post</a>, I am very much open to ideas. Let me know if you have any thoughts to share!</p>

<p><a href="https://noordstar.me/tag:foss" class="hashtag"><span>#</span><span class="p-category">foss</span></a> <a href="https://noordstar.me/tag:functional" class="hashtag"><span>#</span><span class="p-category">functional</span></a> <a href="https://noordstar.me/tag:languagedesign" class="hashtag"><span>#</span><span class="p-category">languagedesign</span></a></p>

<hr>

<p><a href="https://blog.noordstar.me/designing-a-memory-safe-purely-functional-programming-language">Older English post</a> &lt;&lt;&lt; &gt;&gt;&gt; <a href="https://noordstar.me/counter-argument-to-the-doomsday-argument">Newer English post</a></p>

<p><a href="https://blog.noordstar.me/trams-in-de-knoop-op-leidseplein">Older post</a> &lt;&lt;&lt; &gt;&gt;&gt; <a href="https://noordstar.me/counter-argument-to-the-doomsday-argument">Newer post</a></p>
]]></content:encoded>
      <guid>https://noordstar.me/delving-into-language-design-what-ive-learned-so-far</guid>
      <pubDate>Fri, 21 Feb 2025 17:50:57 +0000</pubDate>
    </item>
    <item>
      <title>Designing a Memory-Safe, Purely Functional Programming Language</title>
      <link>https://noordstar.me/designing-a-memory-safe-purely-functional-programming-language</link>
      <description>&lt;![CDATA[Introduction&#xA;&#xA;As a programmer who has experienced the elegance of writing Elm, I’ve often wished for a language that extends Elm’s core philosophy beyond the browser. While many programming languages emphasize type safety, immutability, and purity, few address memory safety as a core language feature.&#xA;&#xA;What if we designed a programming language where memory failures never crash a program? Where aggressive dead code elimination produces highly optimized output? And where every function is guaranteed to be pure and immutable?&#xA;&#xA;This article outlines a conceptual framework for such a language—its principles, challenges, and potential optimizations.&#xA;&#xA;---&#xA;&#xA;Core Principles&#xA;&#xA;1. Functional, Pure &amp; Immutable&#xA;&#xA;Everything in the language is a function. Functions are pure, meaning they always return the same output for the same input, and immutability is enforced throughout. Even variables are just functions with zero arguments.&#xA;&#xA;This ensures strong guarantees for compiler optimization and program correctness.&#xA;&#xA;2. Side-Effects Managed by the Runtime&#xA;&#xA;Like Elm, side-effects cannot be executed directly by user code. Instead, side-effects must be passed to the runtime for execution. This delegates responsibility to the runtime designers and allows the compiler to assume that all side-effects are managed safely.&#xA;&#xA;3. Memory Safety as a Core Language Feature&#xA;&#xA;This language ensures programs never crash due to memory exhaustion. A special memory-safe module (Mem) allows functions to specify default return values in case of memory failure:&#xA;&#xA;add : Int -  Int =  Int&#xA;add x y =&#xA;    x + y&#xA;        |  Mem.withDefault 0&#xA;&#xA;Mechanism&#xA;&#xA;The =   syntax signals a memory-safe function.&#xA;Mem.withDefault 0 ensures a fallback return value in case of failure.&#xA;Default values are allocated at startup to prevent mid-execution failures.&#xA;&#xA;By guaranteeing upfront memory allocation, runtime failures are prevented once the runtime passes the initial startup phase.&#xA;&#xA;---&#xA;&#xA;Handling Dynamic Data Structures&#xA;&#xA;Since the language enforces immutability, dynamically sized data structures must be created at runtime. If memory limits are reached, functions must define fallback strategies:&#xA;&#xA;Return the original input if allocation fails.&#xA;Return an default value specified by the developer.&#xA;&#xA;Ideally, memory exhaustion can be explicitly handled with a dedicated return type:&#xA;&#xA;type Answer = Number Int | OutOfMemory&#xA;&#xA;fib : Int =  Answer&#xA;fib n =&#xA;    case n of&#xA;        0 -  Number 1&#xA;        1 -  Number 1&#xA;         -  case (fib (n - 1), fib (n - 2)) of&#xA;                (Number a, Number b) -  Number (a + b)&#xA;                 -  OutOfMemory&#xA;    |  Mem.withDefault OutOfMemory&#xA;&#xA;---&#xA;&#xA;Extreme Dead Code Elimination&#xA;&#xA;The compiler aggressively removes unused computations, reducing program size. Consider:&#xA;&#xA;type alias Message =&#xA;    { happy : String&#xA;    , angry : String&#xA;    , sad : String&#xA;    , mood : Bool&#xA;    }&#xA;&#xA;toText : Message -  String&#xA;toText msg =&#xA;    if msg.mood then msg.happy else msg.angry&#xA;&#xA;main =&#xA;    { happy = &#34;I am happy today.&#34;&#xA;    , angry = &#34;I am extremely mad!&#34;&#xA;    , sad = &#34;I am kinda sad...&#34;&#xA;    , mood = True&#xA;    }&#xA;    |  toText&#xA;    |  Mem.withDefault &#34;Ran out of memory&#34;&#xA;    |  Console.print&#xA;&#xA;Optimization Process&#xA;&#xA;Since mood is always True, the else branch is never used.&#xA;The function simplifies to toText msg = msg.happy.&#xA;The .angry, .sad, and .mood fields are removed.&#xA;Message reduces to type alias Message = String.&#xA;The toText function is removed as a redundant identity function.&#xA;&#xA;Final optimized output:&#xA;&#xA;main = Console.print &#34;I am happy today!&#34;&#xA;&#xA;While this may require too many computations at compile-time, all of these optimizations seem fair assessments to make.&#xA;&#xA;---&#xA;&#xA;Compiler-Assisted Mutability for Performance&#xA;&#xA;While immutability is enforced, the compiler introduces selective mutability when safe. If an old value is provably unused, it can be mutated in place to reduce memory allocations.&#xA;&#xA;Example:&#xA;&#xA;type alias Model = { name : String, age : Int }&#xA;&#xA;capitalizeName : Model -  Model&#xA;capitalizeName model =&#xA;    { model | name = String.capitalize model.name }&#xA;&#xA;Normally, this creates a new string and record. However, if the previous model.name isn&#39;t referenced anywhere else, the compiler mutates the name field in place, optimizing memory usage.&#xA;&#xA;---&#xA;&#xA;Compiler &amp; Debugging Considerations&#xA;&#xA;For effective optimizations, the compiler tracks:&#xA;&#xA;Global variable usage to detect always-true conditions.&#xA;Usage patterns (e.g., optimizing predictable structures like Message).&#xA;External data sources, which are excluded from optimizations.&#xA;&#xA;To aid debugging, the compiler could provide:&#xA;&#xA;Graph-based visualization of variable flow.&#xA;Debugging toggles to disable optimizations selectively.&#xA;&#xA;---&#xA;&#xA;Conclusion: A New Paradigm for Functional Memory Safety?&#xA;&#xA;Most languages handle memory safety through garbage collection (Java, Python), manual management (C, C++), or borrow-checking (Rust). This language proposes a fourth approach:&#xA;&#xA;Memory-aware functional programming&#xA;&#xA;By making memory failures a core language feature with predictable handling, functional programming can become more robust.&#xA;&#xA;Would this approach be practical? The next step is to prototype a minimal interpreter to explore these ideas further.&#xA;&#xA;If you&#39;re interested in language design, memory safety, and functional programming, I’d love to hear your thoughts!&#xA;&#xA;#foss #functional #languagedesign&#xA;&#xA;---&#xA;&#xA;Older English post &lt;&lt;     Newer English post&#xA;&#xA;Older post &lt;&lt;     Newer post&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="introduction" id="introduction">Introduction</h2>

<p>As a programmer who has experienced the elegance of writing Elm, I’ve often wished for a language that extends Elm’s core philosophy beyond the browser. While many programming languages emphasize type safety, immutability, and purity, few address memory safety as a core language feature.</p>

<p>What if we designed a programming language where memory failures never crash a program? Where aggressive dead code elimination produces highly optimized output? And where every function is guaranteed to be pure and immutable?</p>

<p>This article outlines a conceptual framework for such a language—its principles, challenges, and potential optimizations.</p>

<hr>

<h2 id="core-principles" id="core-principles">Core Principles</h2>

<h3 id="1-functional-pure-immutable" id="1-functional-pure-immutable">1. Functional, Pure &amp; Immutable</h3>

<p>Everything in the language is a function. Functions are pure, meaning they always return the same output for the same input, and immutability is enforced throughout. Even variables are just functions with zero arguments.</p>

<p>This ensures strong guarantees for compiler optimization and program correctness.</p>

<h3 id="2-side-effects-managed-by-the-runtime" id="2-side-effects-managed-by-the-runtime">2. Side-Effects Managed by the Runtime</h3>

<p>Like Elm, side-effects cannot be executed directly by user code. Instead, side-effects must be passed to the runtime for execution. This delegates responsibility to the runtime designers and allows the compiler to assume that all side-effects are managed safely.</p>

<h3 id="3-memory-safety-as-a-core-language-feature" id="3-memory-safety-as-a-core-language-feature">3. Memory Safety as a Core Language Feature</h3>

<p>This language ensures programs never crash due to memory exhaustion. A special memory-safe module (<code>Mem</code>) allows functions to specify default return values in case of memory failure:</p>

<pre><code class="language-elm">add : Int -&gt; Int =&gt; Int
add x y =
    x + y
        |&gt; Mem.withDefault 0
</code></pre>

<h4 id="mechanism" id="mechanism">Mechanism</h4>
<ul><li>The <code>=&gt;</code> syntax signals a <strong>memory-safe function</strong>.</li>
<li><code>Mem.withDefault 0</code> ensures a fallback return value in case of failure.</li>
<li>Default values are allocated at startup to prevent mid-execution failures.</li></ul>

<p>By guaranteeing upfront memory allocation, runtime failures are prevented once the runtime passes the initial startup phase.</p>

<hr>

<h2 id="handling-dynamic-data-structures" id="handling-dynamic-data-structures">Handling Dynamic Data Structures</h2>

<p>Since the language enforces immutability, dynamically sized data structures must be created at runtime. If memory limits are reached, functions must define fallback strategies:</p>
<ul><li>Return the original input if allocation fails.</li>
<li>Return an default value specified by the developer.</li></ul>

<p>Ideally, memory exhaustion can be explicitly handled with a dedicated return type:</p>

<pre><code class="language-elm">type Answer = Number Int | OutOfMemory

fib : Int =&gt; Answer
fib n =
    case n of
        0 -&gt; Number 1
        1 -&gt; Number 1
        _ -&gt;
            case (fib (n - 1), fib (n - 2)) of
                (Number a, Number b) -&gt; Number (a + b)
                _ -&gt; OutOfMemory
    |&gt; Mem.withDefault OutOfMemory
</code></pre>

<hr>

<h2 id="extreme-dead-code-elimination" id="extreme-dead-code-elimination">Extreme Dead Code Elimination</h2>

<p>The compiler aggressively removes unused computations, reducing program size. Consider:</p>

<pre><code class="language-elm">type alias Message =
    { happy : String
    , angry : String
    , sad : String
    , mood : Bool
    }

toText : Message -&gt; String
toText msg =
    if msg.mood then msg.happy else msg.angry

main =
    { happy = &#34;I am happy today.&#34;
    , angry = &#34;I am extremely mad!&#34;
    , sad = &#34;I am kinda sad...&#34;
    , mood = True
    }
    |&gt; toText
    |&gt; Mem.withDefault &#34;Ran out of memory&#34;
    |&gt; Console.print
</code></pre>

<h4 id="optimization-process" id="optimization-process"><strong>Optimization Process</strong></h4>
<ol><li>Since <code>mood</code> is always <code>True</code>, the <code>else</code> branch is never used.</li>
<li>The function simplifies to <code>toText msg = msg.happy</code>.</li>
<li>The <code>.angry</code>, <code>.sad</code>, and <code>.mood</code> fields are removed.</li>
<li><code>Message</code> reduces to <code>type alias Message = String</code>.</li>
<li>The <code>toText</code> function is removed as a redundant <code>identity</code> function.</li></ol>

<p>Final optimized output:</p>

<pre><code class="language-elm">main = Console.print &#34;I am happy today!&#34;
</code></pre>

<p>While this may require too many computations at compile-time, all of these optimizations seem fair assessments to make.</p>

<hr>

<h2 id="compiler-assisted-mutability-for-performance" id="compiler-assisted-mutability-for-performance">Compiler-Assisted Mutability for Performance</h2>

<p>While immutability is enforced, the compiler introduces <strong>selective mutability</strong> when safe. If an old value is provably unused, it can be mutated in place to reduce memory allocations.</p>

<p>Example:</p>

<pre><code class="language-elm">type alias Model = { name : String, age : Int }

capitalizeName : Model -&gt; Model
capitalizeName model =
    { model | name = String.capitalize model.name }
</code></pre>

<p>Normally, this creates a new string and record. However, if the previous <code>model.name</code> isn&#39;t referenced anywhere else, the compiler mutates the <code>name</code> field in place, optimizing memory usage.</p>

<hr>

<h2 id="compiler-debugging-considerations" id="compiler-debugging-considerations">Compiler &amp; Debugging Considerations</h2>

<p>For effective optimizations, the compiler tracks:</p>
<ul><li><strong>Global variable usage</strong> to detect always-true conditions.</li>
<li><strong>Usage patterns</strong> (e.g., optimizing predictable structures like <code>Message</code>).</li>
<li><strong>External data sources</strong>, which are excluded from optimizations.</li></ul>

<p>To aid debugging, the compiler could provide:</p>
<ul><li><strong>Graph-based visualization</strong> of variable flow.</li>
<li><strong>Debugging toggles</strong> to disable optimizations selectively.</li></ul>

<hr>

<h2 id="conclusion-a-new-paradigm-for-functional-memory-safety" id="conclusion-a-new-paradigm-for-functional-memory-safety">Conclusion: A New Paradigm for Functional Memory Safety?</h2>

<p>Most languages handle memory safety through garbage collection (Java, Python), manual management (C, C++), or borrow-checking (Rust). This language proposes a <strong>fourth approach</strong>:</p>

<h3 id="memory-aware-functional-programming" id="memory-aware-functional-programming"><strong>Memory-aware functional programming</strong></h3>

<p>By making memory failures a core language feature with predictable handling, functional programming can become more robust.</p>

<p>Would this approach be practical? The next step is to prototype a minimal interpreter to explore these ideas further.</p>

<p>If you&#39;re interested in language design, memory safety, and functional programming, I’d love to hear your thoughts!</p>

<p><a href="https://noordstar.me/tag:foss" class="hashtag"><span>#</span><span class="p-category">foss</span></a> <a href="https://noordstar.me/tag:functional" class="hashtag"><span>#</span><span class="p-category">functional</span></a> <a href="https://noordstar.me/tag:languagedesign" class="hashtag"><span>#</span><span class="p-category">languagedesign</span></a></p>

<hr>

<p><a href="https://blog.noordstar.me/why-don-t-cars-have-brake-lights-on-the-front">Older English post</a> &lt;&lt;&lt; &gt;&gt;&gt; <a href="https://blog.noordstar.me/delving-into-language-design-what-ive-learned-so-far">Newer English post</a></p>

<p><a href="https://blog.noordstar.me/why-don-t-cars-have-brake-lights-on-the-front">Older post</a> &lt;&lt;&lt; &gt;&gt;&gt; <a href="https://blog.noordstar.me/trams-in-de-knoop-op-leidseplein">Newer post</a></p>
]]></content:encoded>
      <guid>https://noordstar.me/designing-a-memory-safe-purely-functional-programming-language</guid>
      <pubDate>Tue, 18 Feb 2025 00:54:20 +0000</pubDate>
    </item>
  </channel>
</rss>