<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title></title>
    <link rel="self" type="application/atom+xml" href="https://lasernoises.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://lasernoises.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-08-25T00:00:00+00:00</updated>
    <id>https://lasernoises.com/atom.xml</id>
    <entry xml:lang="en">
        <title>A Shared Syntax for Custom Languages</title>
        <published>2026-08-25T00:00:00+00:00</published>
        <updated>2026-08-25T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://lasernoises.com/blog/universal-syntax/"/>
        <id>https://lasernoises.com/blog/universal-syntax/</id>
        
        <content type="html" xml:base="https://lasernoises.com/blog/universal-syntax/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&#39;ve been thinking about a universal syntax for programming languages, DSLs and data formats /
config files.
The motivation comes from a few different angles:&lt;/p&gt;
&lt;h3 id=&quot;s-expressions&quot;&gt;S-Expressions&lt;/h3&gt;
&lt;p&gt;I find Lisp&#39;s S-Expressions very intriguing.
They are universal in a way the syntax of other languages doesn&#39;t tend to be.&lt;/p&gt;
&lt;p&gt;Yet I don&#39;t quite want to use them.
A lack of experience is certainly a part of it, but I find them quite hard to read.&lt;/p&gt;
&lt;p&gt;Then there&#39;s also the formatter thing.
Since the same syntax is used for everything it&#39;s quite hard for a formatter to know which
formatting would be appropriate.&lt;/p&gt;
&lt;h3 id=&quot;data-formats&quot;&gt;Data Formats&lt;/h3&gt;
&lt;p&gt;I also like using formats like JSON and RON.
Especially in combination with Serde.&lt;/p&gt;
&lt;p&gt;There is one persistent frustration however.
And that is the lack of language server support.&lt;/p&gt;
&lt;p&gt;It&#39;s quite frustrating to have a static schema in the form of type definitions, but to still get no
support in the editor with finding the right names and seeing available fields.&lt;/p&gt;
&lt;p&gt;There are solutions for this, like &lt;a rel=&quot;external&quot; href=&quot;https://tombi-toml.github.io/tombi/&quot;&gt;Tombi&lt;/a&gt;, but that&#39;s limited
to JSON Schema.
While a static schema is the baseline of what I want it&#39;s not quite sufficient.&lt;/p&gt;
&lt;p&gt;To illustrate, let me talk about a templating language for PDFs I started to build once.
The idea was to template &lt;a rel=&quot;external&quot; href=&quot;https://github.com/laser-pdf/laser-pdf&quot;&gt;Laser-PDF&lt;/a&gt; elements with a
structure like Mustache.
There was an external definition of available fields.&lt;/p&gt;
&lt;p&gt;Notably the fields could be recursive, like a GraphQL schema.
The template would first be evaluated to get a tree of used fields.
That tree would then be used to actually fetch the data.&lt;/p&gt;
&lt;p&gt;I was building this on top of RON and Serde at the time, so I couldn&#39;t even get the static list of
elements in my editor.
But to fully support this I would have needed to get the available templating fields in the editor
as well.&lt;/p&gt;
&lt;p&gt;Those weren&#39;t static.
The program would read the schema from a file at runtime.&lt;/p&gt;
&lt;p&gt;So this can&#39;t be done with a JSON Schema style solution.
We need to be able to execute code in the LSP implementation.&lt;/p&gt;
&lt;h3 id=&quot;llms-and-non-turing-complete-languages&quot;&gt;LLMs and Non-Turing-Complete Languages&lt;/h3&gt;
&lt;p&gt;As I expanded on &lt;a rel=&quot;external&quot; href=&quot;https://lasernoises.com/blog/non-turing-complete-languages/&quot;&gt;here&lt;/a&gt;, I think it&#39;s a
good idea to have as much of LLM generated code as possible be in very restricted languages that
aren&#39;t Turing-complete.&lt;/p&gt;
&lt;p&gt;Unfortunately today, switching to a custom DSL or a config format often means loosing most of the
editor support you get from your main general purpose language.&lt;/p&gt;
&lt;h3 id=&quot;why-not-kdl&quot;&gt;Why not KDL?&lt;/h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https://kdl.dev/&quot;&gt;KDL&lt;/a&gt; language is very interesting and seems to want to solve some of the same
problems.
However, it&#39;s clearly not meant to be used for anything that starts to resemble a programming
language too much.
It is very focused on an XML style structure of nodes with attributes and children and since the
values of attributes can&#39;t contain other nodes, representing a programming language or certain kinds
of DSLs with it would become very awkward.&lt;/p&gt;
&lt;h2 id=&quot;an-attempt-at-a-solution&quot;&gt;An Attempt at a Solution&lt;/h2&gt;
&lt;p&gt;I really like using Nushell.
One interesting thing about it (and most shells to a degree) is the way nested commands start
looking like S-Expressions.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;nushell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;ls&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;pwd&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt; -&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Nushell the resemblence grows when you have to add parens toplevel when you want to split a
command over multiple lines.&lt;/p&gt;
&lt;p&gt;What if we use this as the starting point for our universal language?
Meaning top level calls (whatever that means in the particular language; in a config format they&#39;d
be used for enum variants for example) don&#39;t need parens around them.&lt;/p&gt;
&lt;p&gt;In order to avoid newline sensitivity and needing toplevel parens around multiline calls we&#39;ll add
semicolons to separate them.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foo 12;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bar &amp;quot;12&amp;quot; (nested_call 12);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now since any real laguage has some form of nesting we need something like blocks.
Since we don&#39;t want to make any decisions that are specific to procedural languages where a block is
a list of statements, we&#39;ll use the same syntax for blocks and lists.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;foo [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  bar 12;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;maps&quot;&gt;Maps&lt;/h3&gt;
&lt;p&gt;Now we get to something annoying.&lt;/p&gt;
&lt;p&gt;Clojure has a dedicated syntax for maps.
And it&#39;s a little bit awkward.
Since, as a Lisp, Clojure aims to be &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Homoiconicity&quot;&gt;homoiconic&lt;/a&gt;, the
quoted form of a map is also a map.&lt;/p&gt;
&lt;p&gt;This means you can&#39;t have the same function call multiple times as a map key:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;  (&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;my_function&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt; 12&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;  (&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;my_function&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt; 13&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gets rejected even though &lt;code&gt;my_function&lt;/code&gt; might have some internal state that makes it produce a
unique key each time, which is possible since Clojure isn&#39;t a purely functional language.&lt;/p&gt;
&lt;p&gt;Of course this isn&#39;t a huge deal in practice, since there are more ways to create maps, but it&#39;s
still a little awkward.&lt;/p&gt;
&lt;p&gt;Maps are also a bit of a point of weirdness in JSON.
For the most part JSON is just a syntax and thus doesn&#39;t say anything about the uniqueness of object
keys or whether the order of keys matters.
&lt;a rel=&quot;external&quot; href=&quot;https://datatracker.ietf.org/doc/html/rfc8259#section-4&quot;&gt;RFC-8259&lt;/a&gt; merely makes uniqueness a
SHOULD.&lt;/p&gt;
&lt;p&gt;I&#39;ve actually ran into this with MariaDB&#39;s &lt;code&gt;EXPLAIN FORMAT=JSON&lt;/code&gt;, which sometimes produces duplicate
&lt;code&gt;&quot;table&quot;&lt;/code&gt; keys instead of making it an array.
This is valid JSON, but means you&#39;ll have a hard time processing it with standard tools like JQ.&lt;/p&gt;
&lt;p&gt;I want my language to also have the property of just being a syntax, but I want to avoid the problem
of unclear semantics.
I also want to make it possible to build a Lisp style homoiconic language.&lt;/p&gt;
&lt;p&gt;Because of this I decided to just represent maps as lists of calls,
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/kdl-org/kdl/blob/main/JSON-IN-KDL.md&quot;&gt;a bit like you&#39;d do in KDL&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;map [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    my_key 12;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    my_other_key 12;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;map&lt;/code&gt; here would be how you would handle it in the hypothetical homoiconic language, in other
usecases like Serde deserialization it would be clear from context that the list needs to be parsed
into a map.
If you were to implement a Rust-style language with this syntax you&#39;d also use that pattern for
structs:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MyStruct [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  field_a 12;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  field_b 12;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And for struct definitions:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;struct MyStruct [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  field_a u32;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  field_b i16;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can already see how the call syntax can be used for more than just representing actual function
calls.
For example enum variants would also fit this pattern.&lt;/p&gt;
&lt;h3 id=&quot;pipes&quot;&gt;Pipes&lt;/h3&gt;
&lt;p&gt;There&#39;s another thing I want to steal from shells.
Pipes.&lt;/p&gt;
&lt;p&gt;I really like how you can use pipes allmost like method calls in Nushell for example:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;nushell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;start&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;ls&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt; --&lt;/span&gt;&lt;span&gt;long&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt; ~/tmp&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt; | sort-by --&lt;/span&gt;&lt;span&gt;reverse&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt; created&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt; | first | get&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Many programming languages implement pipes in a way that that inserts the expression before the pipe
as the first argument to the function after the pipe.
For example consider this Gleam code from their
&lt;a rel=&quot;external&quot; href=&quot;https://tour.gleam.run/functions/pipelines/&quot;&gt;language tour&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;gleam&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt;&amp;quot;Hello, Mike!&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;  |&amp;gt;&lt;/span&gt;&lt;span&gt; string.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;drop_end&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;  |&amp;gt;&lt;/span&gt;&lt;span&gt; string.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;drop_start&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;7&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;  |&amp;gt;&lt;/span&gt;&lt;span&gt; io.println&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is equivalent to this nested call:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;gleam&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;io.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;println&lt;/span&gt;&lt;span&gt;(string.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;drop_start&lt;/span&gt;&lt;span&gt;(string.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;drop_end&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt;&amp;quot;Hello, Mike!&amp;quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;1&lt;/span&gt;&lt;span&gt;), &lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;7&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes it tempting to support pipelines as a purely syntactic transformation while parsing.&lt;/p&gt;
&lt;p&gt;So we would take syntax like this:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;quot;Hello, Mike!&amp;quot; | drop_end 1 | drop_start 7 | println&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And parse it to the same AST as:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;println (drop_start (drop_end &amp;quot;Hello, Mike!&amp;quot; 1) 7)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don&#39;t want to do it in this way, however.
The reason is that a lot of languages have their own way of handling pipelines or method calls, that
isn&#39;t simply equivalent to passing a first parameter.&lt;/p&gt;
&lt;p&gt;For example in shells it means piping to &lt;code&gt;stdin&lt;/code&gt;.
Or in most object-oriented or adjacent languages method calls get resolved in the scope of the type
(meaning something like method definitions inside the class defintion instead of just calling
freestanding function with the given name).&lt;/p&gt;
&lt;p&gt;So I think it makes sense to unify all those usecases with a single pipe syntax and let the
particular language decide what they mean of whether to support them at all.&lt;/p&gt;
&lt;h3 id=&quot;beginnings-of-an-implementation&quot;&gt;Beginnings of an Implementation&lt;/h3&gt;
&lt;p&gt;So far I&#39;ve mostly been thinking about this language, but I have started to implement something.&lt;/p&gt;
&lt;p&gt;I&#39;ve made a declarative macro in Rust that parses my syntax into an enum.
I mostly just wanted to stop myself from thinking about parser libraries and whether to just write
my own parser.&lt;/p&gt;
&lt;p&gt;I do however think supporting usage from a macro as well as parsing from strings will stay useful
even after we have a proper parser.
Though it&#39;ll probably become more of a function that gets called in procedural macros that define
DSLs.&lt;/p&gt;
&lt;p&gt;The goal of the syntax is to not have any special keywords.
So anything from &lt;code&gt;true&lt;/code&gt; to &lt;code&gt;async&lt;/code&gt; just gets parsed as an identifier on the syntax level.
It&#39;s up to the language whether those will then be handled specially or not.&lt;/p&gt;
&lt;p&gt;The same goes for most symbols like &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt; and so on.
The exceptions are the few symbols that are needed for the structure: &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt;, &lt;code&gt;[&lt;/code&gt;, &lt;code&gt;]&lt;/code&gt; and &lt;code&gt;|&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As a declarative macro we can&#39;t implement these rules perfectly.
So for example &lt;code&gt;some-thing&lt;/code&gt; is parsed the same as &lt;code&gt;some - thing&lt;/code&gt;.
With procedural macros we could look at the byte offsets, but I&#39;m not sure I like that.&lt;/p&gt;
&lt;p&gt;I think it&#39;s ok for the macro version to not be perfectly identical to the actual language.
It&#39;s just about having an easy way to use a custom language inline sometimes.
For example it could be useful for testing an implementation of a DSL without having string literals
all over your tests.&lt;/p&gt;
&lt;p&gt;I&#39;ve also started implementing a Serde deserializer that operates on this data-structure.
Of course a real one should be more efficient than this and skip the AST entirely.&lt;/p&gt;
&lt;p&gt;The interesting part is that we can&#39;t fully support being self-describing using &lt;code&gt;deserialize_any&lt;/code&gt;
because our syntax doesn&#39;t differentiate between maps and lists and so we need the hint for those.&lt;/p&gt;
&lt;p&gt;Let&#39;s see if I have the motivation and time to build out this implementation enough to make it
useable.
I decided to write this post mostly because I want to at least get the idea written down in case I
don&#39;t.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>GUI Experiments Link Collection</title>
        <published>2026-03-29T00:00:00+00:00</published>
        <updated>2026-03-29T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://lasernoises.com/blog/gui-experiments-links/"/>
        <id>https://lasernoises.com/blog/gui-experiments-links/</id>
        
        <content type="html" xml:base="https://lasernoises.com/blog/gui-experiments-links/">&lt;p&gt;This is just a collection of links to my various experiments around building GUI libraries.
I&#39;ll expand this with new stuff over time.&lt;/p&gt;
&lt;p&gt;These all have readmes that go into a little bit of detail about how they work.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/lasernoises/wraptatui&quot;&gt;https://github.com/lasernoises/wraptatui&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a Ratatui wrapper where I implemented a bit of a weird widget API to work around limitations
in the Rust type system.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/lasernoises/spicetime&quot;&gt;https://github.com/lasernoises/spicetime&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a small crate that implements owned and weak generational references. Weak references are
&lt;code&gt;Copy&lt;/code&gt;, but require a runtime generation check to read.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/lasernoises/fluorine&quot;&gt;https://github.com/lasernoises/fluorine&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a reactivity library with a design that is quite different from the ones I usually see.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/lasernoises/egrikor&quot;&gt;https://github.com/lasernoises/egrikor&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is an older repo from a long abandoned attempt. I recently updated it with a readme that
explains some of the problems I ran into at the time. I made some
&lt;a rel=&quot;external&quot; href=&quot;https://www.youtube.com/watch?v=4Fl_SsmdtcU&quot;&gt;YouTube videos&lt;/a&gt; back when I was working on this that
go into a lot more detail.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Is it time for more non-Turing-complete languages?</title>
        <published>2026-03-26T00:00:00+00:00</published>
        <updated>2026-03-26T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://lasernoises.com/blog/non-turing-complete-languages/"/>
        <id>https://lasernoises.com/blog/non-turing-complete-languages/</id>
        
        <content type="html" xml:base="https://lasernoises.com/blog/non-turing-complete-languages/">&lt;p&gt;I&#39;ve been thinking a lot about our AI future and how we can manage the growing complexity associated
with that.
It&#39;s a topic that is being discussed a lot, but what I haven&#39;t seen being talked about a lot is the
role of non-Turing-complete languages could play.&lt;/p&gt;
&lt;p&gt;A different term for this would be DSLs (domain-specific langauge).
And DSLs are of course a bit of a classic topic people have very different opinions about.
I think it&#39;s a bit clearer to talk about non-Turing-complete langauges though, since nothing says
that a DSL can&#39;t be turing complete.
And I think it&#39;s usually bad when a DSL becomes turing complete (deliberately or not).&lt;/p&gt;
&lt;p&gt;I think non-Turing-complete langauges have a lot of potential because there are so many thing that
can&#39;t go wrong when a language is restricted by design.
And the poperties that can&#39;t be violated can be designed into the language.
Which tends to be much harder, if not impossible to design into a programming framework or library
for the same problem space.&lt;/p&gt;
&lt;h2 id=&quot;an-example&quot;&gt;An example&lt;/h2&gt;
&lt;p&gt;A concrete thing I&#39;ve been thinking about HTML templating.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://mustache.github.io/&quot;&gt;Mustache&lt;/a&gt; is a good example of non-Turing-complete HTML templating,
but I would suggest going a bit further.&lt;/p&gt;
&lt;p&gt;Firstly I&#39;d prefer the templating to be structure aware and while we&#39;re at it we can ditch the ugly
SGML syntax.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;div {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;quot;Some text&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  for my_var {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    span {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;quot;some other text with a {{ variable }}&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This has the property that we can statically prevent it from generating invalid html.&lt;/p&gt;
&lt;p&gt;This is nothing special by itself, but there is one very interesting property that a Mustache-style
language has.
You can easily extract a tree of the variables and fields it uses.
And that is quite close to a GraphQL query.&lt;/p&gt;
&lt;p&gt;So I think we could build a query langauge that integrates with GraphQL (it doesn&#39;t have to be
GraphQL in principle, just some tree structured query system).
If you then combine that with a GraphQL server generated from a DB schema, you can basically build
simple CRUD apps without any need for a Turing-complete language.&lt;/p&gt;
&lt;p&gt;(Maybe something like this already exists. I haven&#39;t really researched this.)&lt;/p&gt;
&lt;p&gt;I think a sensible next step would be to actually restrict the HTML tags and attributes to forbid
any JavaScript directly in the template.&lt;/p&gt;
&lt;h2 id=&quot;making-it-work-in-practice&quot;&gt;Making it work in practice&lt;/h2&gt;
&lt;p&gt;I think there are some important things to make non-Turing-complete languages not a bad idea in
practice.&lt;/p&gt;
&lt;h3 id=&quot;lsp-integration&quot;&gt;LSP integration&lt;/h3&gt;
&lt;p&gt;This might be the hardest bit.&lt;/p&gt;
&lt;p&gt;I often find config files written in something like TOML to be a bit annoying in practice for a
relatively dumb reason.
And that is that my editor can&#39;t tell me what kind of keys I can use where.
But there isn&#39;t really a good reason it should be this way.
In principle writing a language server for such a language should be a whole lot easier than for a
full general purpose programming language.&lt;/p&gt;
&lt;p&gt;And it seems there&#39;s projects like &lt;a rel=&quot;external&quot; href=&quot;https://github.com/tombi-toml/tombi&quot;&gt;Tombi&lt;/a&gt; that solve this
problem.
Though I think it&#39;s a bit unfortunate having to determine the relevant schema based on the filename.
Maybe the XML idea of directly referencing the schema in the file itself isn&#39;t the worst idea (just
please keep that ugly XML syntax away from me).&lt;/p&gt;
&lt;p&gt;It seems the &lt;a rel=&quot;external&quot; href=&quot;https://kdl.dev/&quot;&gt;KDL&lt;/a&gt; language is going in an interesting direction there.&lt;/p&gt;
&lt;h3 id=&quot;escape-hatches&quot;&gt;Escape hatches&lt;/h3&gt;
&lt;p&gt;The other thing is that you need a way to get to code written in a general purpose language for
things that the non-Turing-complete langauge can&#39;t do.&lt;/p&gt;
&lt;p&gt;I think for the HTML templating + GraphQL example this would be done at multiple layers.
Firstly for the frontend you could use web components for things that can&#39;t be done in plain HTML.
I think that&#39;s a better idea than allowing JavaScript in attributes.&lt;/p&gt;
&lt;p&gt;Then of course if you have a generated GraphQL server you need a way to call custom code there.
And maybe you even need a way to run custom code for HTML generation, but I&#39;m not so sure how common
that would be.&lt;/p&gt;
&lt;p&gt;I think the important thing for all of these is that the escape hatch should be very explicit.
And that the code it calls shouldn&#39;t be inline with the non-Turing-complete langauge, but in a
separate place where you can keep an eye on its complexity.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What is a monad again?</title>
        <published>2026-03-03T00:00:00+00:00</published>
        <updated>2026-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://lasernoises.com/blog/monads/"/>
        <id>https://lasernoises.com/blog/monads/</id>
        
        <content type="html" xml:base="https://lasernoises.com/blog/monads/">&lt;p&gt;I keep being confused about what a monad is.
I have previously convinced myself that I understand, but the feeling of understanding doesn&#39;t seem
to last very long.
So I thought I&#39;d just write it down here in a way that is easy for me to understand should I get
confused again in the future.&lt;/p&gt;
&lt;p&gt;Monads are a mathematical thing defined in terms of operations and properties that need to hold.
Haskell and some other languages have typesystems advanced enough to specify a monad as construct
in the language.
While other languages don&#39;t necessarily have sufficiently advanced typesystems to be able to
represent a monad as an interface you can implement, any combination of a type and functions that
satisfy the right properties is still a monad.&lt;/p&gt;
&lt;p&gt;In Haskell the &lt;code&gt;Monad&lt;/code&gt; typeclass looks like this:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt; Monad&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; m&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt; where&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;  (&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;  ::&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; m a&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;  a&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; m b&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; m b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;  (&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;   ::&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; m a&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;  m b&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;         -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; m b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; ::&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;   a&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;                 -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; m a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&#39;re like me this looks like absolute gibberish, so let&#39;s decode it a little bit.
&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; and &lt;code&gt;return&lt;/code&gt; are functions.
&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt; is called bind and &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; is sometimes called then.
&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; is just a shortcut for &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt; with a value instead of a function for when &lt;code&gt;m b&lt;/code&gt; doesn&#39;t depend
on &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With that sorted out, let&#39;s transform this typeclass definition into a pseudo syntax that a
curly-bracket-brained person like me can read more easily:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;gleam&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;class &lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;Monad&lt;/span&gt;&lt;span&gt; m {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;  fn&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; bind&lt;/span&gt;&lt;span&gt;(m&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;fn&lt;/span&gt;&lt;span&gt;(a)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; m&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; m&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;  fn&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; then&lt;/span&gt;&lt;span&gt;(m&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;, m&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; m&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;  fn&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; return&lt;/span&gt;&lt;span&gt;(a)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; m&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are also rules associated with this interface: &lt;a rel=&quot;external&quot; href=&quot;https://wiki.haskell.org/index.php?title=Monad_laws&quot;&gt;https://wiki.haskell.org/index.php?title=Monad_laws&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&#39;s translate these to our pseudo-syntax as well:&lt;/p&gt;
&lt;p&gt;Left identity: &lt;code&gt;bind(return(a), h) == h(a)&lt;/code&gt;&lt;br /&gt;
Right identity: &lt;code&gt;bind(m, return) == m&lt;/code&gt;&lt;br /&gt;
Associativity: &lt;code&gt;bind(bind(m, g), h) == bind(m, fn(x) -&amp;gt; bind(g(x), h))&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;monadic-i-o&quot;&gt;Monadic I/O&lt;/h2&gt;
&lt;p&gt;A while ago I made a very simple Rust implementation of an I/O monad to help me understand how
monads are helpful for purely functional I/O.
This isn&#39;t practically usable because bind accepts a function pointer and so you can&#39;t use closures
there.
And closures are an important part of making monadic I/O actually work of course.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;enum IO&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;    GetChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;Box&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;dyn&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt; FnOnce&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt;&amp;gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;    PutChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;IO&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt;&amp;gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;    Done&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; bind&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;        match&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;GetChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;GetChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span&gt;Box&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;move&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; g&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;bind&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;))),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;PutChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;PutChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Box&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;bind&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;))),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;Done&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; then&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;:&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;        match&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;GetChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;GetChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span&gt;Box&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;move&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; g&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;))),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;PutChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;PutChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Box&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;))),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;Done&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; ret&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt; A&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Self&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Self&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;Done&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; eval&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt; A&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;        match&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;GetChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;                let&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; c&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;stdin&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;bytes&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;unwrap&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;unwrap&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt; char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;                let&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; next&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; g&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;                next&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;eval&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;PutChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;                print!&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&amp;quot;{&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;}&amp;quot;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                std&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;stdout&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;flush&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;unwrap&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;                x&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;eval&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;Done&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; put_char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt; char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;()&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;PutChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Box&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span&gt;IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;Done&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(())))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; get_char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;GetChar&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span&gt;Box&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;|&lt;/span&gt;&lt;span&gt; IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;Done&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This can then be used like this:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;get_char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;bind&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; put_char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;put_char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt;h&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;#39;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;get_char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;get_char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span&gt;IO&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;ret&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt;r&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;#39;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;bind&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; put_char&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;to_ascii_uppercase&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;eval&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Lisp Formatting</title>
        <published>2026-02-27T00:00:00+00:00</published>
        <updated>2026-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://lasernoises.com/blog/lisp-formatting/"/>
        <id>https://lasernoises.com/blog/lisp-formatting/</id>
        
        <content type="html" xml:base="https://lasernoises.com/blog/lisp-formatting/">&lt;p&gt;This is just a quick rant about formatting in Lisp that I felt the urge to write down.&lt;/p&gt;
&lt;p&gt;I&#39;ve been reading more about Lisp and I do really like the simplicity of
S-expressions.
What really annoys me though is the typical convention about formatting that everyone seems to use.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;scheme&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;let&lt;/span&gt;&lt;span&gt; loop &lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;((&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;  (&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;    &amp;#39;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;    (&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;cons&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;      (&lt;/span&gt;&lt;span&gt;loop &lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;+&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)))))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is just a random example from the Scheme Wikipedia page.
What really bothers me is how all the closing parens are just piled up at the end.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;scheme&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;let&lt;/span&gt;&lt;span&gt; loop &lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;((&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;  (&lt;/span&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;    &amp;#39;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;    (&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;cons&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;      (&lt;/span&gt;&lt;span&gt;loop &lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;+&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;  )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is how I&#39;d want to format that.
It feels immediately much more readable to me that way.&lt;/p&gt;
&lt;p&gt;I get that it uses more space, but I don&#39;t think that&#39;s actually a bad thing necessarily.
Imagine I formatted my Rust code like this:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt; abc&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #A96BC0;&quot;&gt; bool&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;  some_other_function&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;    1&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt; a&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;      def&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #40B4C4;&quot;&gt;    else&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;      2&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;})}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Doesn&#39;t that feel cursed?
It just looks like I&#39;d rather be programming in Python.&lt;/p&gt;
&lt;p&gt;Well this is how I feel whenever I read some Lisp code.
It just feels like whoever wrote it would rather be using a whitespace sensitive language.&lt;/p&gt;
&lt;p&gt;I actually kind of think this is the reason people make jokes about all the parens in Lisp.
Aside from basic arithmetic Lisp doesn&#39;t really have more brackets than other languages, it&#39;s just
that piling them up on the end of a line really draws attention to them.&lt;/p&gt;
&lt;p&gt;But of course this is a personal preference thing.
I&#39;m sure you can get used to this formatting, though I think at that point you have to actually
ignore the closing parens and look at the indentation.
And I&#39;m also sure that using a structural editor helps with this as well.&lt;/p&gt;
&lt;p&gt;I&#39;m also a bit of an extremist when it comes to putting closing syntax on new lines.
For example, before using a formatter I was known for doing this:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;  .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;  .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;  .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And even this:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;some_function&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;  a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #74DFC4;&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #EB64B9;&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;  ,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt;  12&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This also has the advantage of making the diff cleaner when you insert an additional call at the
end of the chain, similar to trailing commas.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Creating a VGA Signal in Hubris</title>
        <published>2025-09-15T00:00:00+00:00</published>
        <updated>2025-09-15T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://lasernoises.com/blog/hubris-vga/"/>
        <id>https://lasernoises.com/blog/hubris-vga/</id>
        
        <content type="html" xml:base="https://lasernoises.com/blog/hubris-vga/">&lt;p&gt;A while ago I got a ST Nucleo-H753ZI evaluation board because I wanted to try out Hubris, Oxide&#39;s embedded operating system.
After getting the basic demo app with the blinking lights running I set it aside for a lack of an idea what to do with it.
A few weeks ago I was looking through old Raspberry Pi accessories on the hunt for a project.
What stuck out to me wasn&#39;t any of the Raspberry Pi stuff, but the old 4 by 3 VGA monitor I had standing around.
Could I just wire those pins in the VGA cable up to the GPIOs and produce a signal?
As it turns out, yes you can just do that.&lt;/p&gt;
&lt;div style=&quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));&quot; &gt;
  &lt;img src=&quot;./14.jpg&quot;&gt;
  &lt;img src=&quot;./13.jpg&quot;&gt;
  &lt;img src=&quot;./0.jpg&quot;&gt;
  &lt;img src=&quot;./1.jpg&quot;&gt;
  &lt;img src=&quot;./2.jpg&quot;&gt;
  &lt;img src=&quot;./3.jpg&quot;&gt;
  &lt;img src=&quot;./4.jpg&quot;&gt;
  &lt;img src=&quot;./5.jpg&quot;&gt;
  &lt;img src=&quot;./5.jpg&quot;&gt;
  &lt;img src=&quot;./6.jpg&quot;&gt;
  &lt;img src=&quot;./7.jpg&quot;&gt;
  &lt;img src=&quot;./8.jpg&quot;&gt;
  &lt;img src=&quot;./9.jpg&quot;&gt;
  &lt;img src=&quot;./10.jpg&quot;&gt;
  &lt;img src=&quot;./11.jpg&quot;&gt;
  &lt;img src=&quot;./12.jpg&quot;&gt;
&lt;/div&gt;
&lt;h1 id=&quot;getting-rid-of-the-sys-task&quot;&gt;Getting Rid of the Sys Task&lt;/h1&gt;
&lt;p&gt;In the beginning I thought I was gonna be changing the GPIO pins from normal code, so switching them
on and off at very high speeds.
In hubris there&#39;s a &lt;code&gt;stm32xx-sys&lt;/code&gt; task that normally controls the GPIO pins and also handles
enabling clock to the different components through the Reset and Clock Control (RCC) block.&lt;/p&gt;
&lt;p&gt;So normally if you want to set a GPIO pin you&#39;d send a message to the &lt;code&gt;sys&lt;/code&gt; task and it would do
that for you.
I was worried that the overhead of the context switching was gonna be a problem there.&lt;/p&gt;
&lt;p&gt;So I decided to get rid of the sys task and do it all in my task.&lt;/p&gt;
&lt;h1 id=&quot;the-plan&quot;&gt;The Plan&lt;/h1&gt;
&lt;p&gt;My first plan was to get the screen to just display a single color.
I thought that it would be enough to get the vsync and hsync signals right and then just have the
green pin high all the time to get a green picture.&lt;/p&gt;
&lt;h1 id=&quot;mapping-the-registers&quot;&gt;Mapping the Registers&lt;/h1&gt;
&lt;p&gt;The peripherals of our chip are all controlled with registers.
Those are memory mapped and to certain addresses.
There is a gigantic 3000 page reference manual that describes all those registers.
It&#39;s all very overwhelming.
Luckily there&#39;s a Peripheral Access Crate (PAC) that defines an API for reading and writing those registers.&lt;/p&gt;
&lt;p&gt;Since we&#39;re running under memory protection we need to first make sure we can actually write to those registers.
In Hubris that sort of thing happens in an &lt;code&gt;app.toml&lt;/code&gt; where all the tasks for an app are defined.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;[&lt;/span&gt;&lt;span&gt;tasks.vga&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; = &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt;drv-vga&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;priority&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;uses&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; = [&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt;rcc&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt;gpios&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #B4DCE7;&quot;&gt;tim3&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;&amp;quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;start&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FFE261;&quot;&gt; true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case the &lt;code&gt;tim3&lt;/code&gt; memory region wasn&#39;t a thing the Hubris build system knew about yet.
The regions you can &lt;code&gt;use&lt;/code&gt; there are defined in a &lt;code&gt;chip.toml&lt;/code&gt; for the specific chip you have.
In our case that&#39;s &lt;code&gt;chips/stm32h7/chip.toml&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #FFB85B; background-color: #27212E;&quot; &gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;[&lt;/span&gt;&lt;span&gt;tim3&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;address&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt; 0x40000400&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFFFFF;&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color: #7B6995;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #B381C5;&quot;&gt; 0x400&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You get those values from a fun table called &quot;Register boundary addresses&quot; from the manual.&lt;/p&gt;
&lt;h1 id=&quot;blinking-an-led-with-a-timer-pwm&quot;&gt;Blinking an LED with a Timer / PWM&lt;/h1&gt;
&lt;p&gt;The timers on this chip have a Pulse-Width-Modulation (PWM) feature which we should be able to use to generate the VGA sync signals.
But the first step was to get a light blinking using PWM.
The basic Hubris demo app does have a blinking LED, but that&#39;s not using PWM.
Instead it uses the timer feature of the kernel, which makes a lot of sense for a Hubris demo, but we want to involve the CPU as minimally as possible for generating the signal.&lt;/p&gt;
&lt;p&gt;My initial plan was to measure the PWM with my multimeter to see it working.
I chose PB0 for this from the pinout table in the user manual of the board (which is different from the reference manual of the chip).
PB0 is hooked up to timer 3, channel 3 (TIM3_CH3).
Looking at the &quot;Solder bridges and jumpers&quot; section I found out that that&#39;s also connected to an LED on the board by default, so I chose to just test it that way.&lt;/p&gt;
&lt;p&gt;By default here means that there&#39;s a bunch of predefined places on the bottom of the board where you can make connections by adding a bit of solder or remove connections by cutting traces or removing zero ohm resistors.&lt;/p&gt;
&lt;p&gt;So after a whole bunch of fiddling I got all the registers set up right to get the LED blinking.&lt;/p&gt;
&lt;h1 id=&quot;setting-up-the-h-sync-and-v-sync-timers&quot;&gt;Setting up the H-Sync and V-Sync Timers&lt;/h1&gt;
&lt;p&gt;The first thing I sort of used for some guidance was this site where someone had done a similar project:
&lt;a rel=&quot;external&quot; href=&quot;https://www.programmerall.com/article/26476558/&quot;&gt;https://www.programmerall.com/article/26476558/&lt;/a&gt;
That was pretty useful for the wiring itself and a basic understanding of how the signal works.&lt;/p&gt;
&lt;p&gt;The basic idea is that there&#39;s three pins for red, green and blue and two pins for horizontal and vertical sync.
The horizontal sync signal needs to be on for a bit between each line of pixels and the vertical one between frames.
You can connect any of the color that you don&#39;t need to display to ground.&lt;/p&gt;
&lt;p&gt;To connect the end of the cable to the GPIO headers on the board I ended up using some jumper wires and a breadboard.
(The breadboard is just for all the things connected to ground.)&lt;/p&gt;
&lt;p&gt;I could take off black plastic cover on the end of the jumper wires and clip off the pointy end.
That left a sort of hollow bit that I could wrap some electrical tape around and stick onto the pins of the VGA cable.
The connection is a bit loose, but it makes contact.&lt;/p&gt;
&lt;p&gt;Before that I had tried soldering and that was a horrible idea because I don&#39;t have enough hands to hold the soldering iron, the solder and the jumper.&lt;/p&gt;
&lt;p&gt;Then there&#39;s this site which has timing information for all the different resolutions:
&lt;a rel=&quot;external&quot; href=&quot;http://www.tinyvga.com/vga-timing&quot;&gt;http://www.tinyvga.com/vga-timing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At first I chose 640×480 because I wanted a minimal pixel count.
I got that sort of working to the point where the monitor would recognize a signal, but it would need a bit of time to auto-adjust.&lt;/p&gt;
&lt;p&gt;I then decided I&#39;d switch to 800×600 like they did in the link above, because those numbers add up much nicer:
&lt;a rel=&quot;external&quot; href=&quot;http://www.tinyvga.com/vga-timing/800x600@60Hz&quot;&gt;http://www.tinyvga.com/vga-timing/800x600@60Hz&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Each timer has a prescaler that can be used to divide the base clock, which is 200 Mhz in our case.
The timer will then count up until it reaches the value in the auto-reload register (ARR).
Then there&#39;s also the capture/compare register (CCR), which determines for which part of the cycle the output is on when doing pulse-width modulation.&lt;/p&gt;
&lt;p&gt;For hsync I set the prescaler to zero, meaning the frequency is divided by one, because that register is offset by one.
Then I set the ARR to 5279 (also offset by one) and the CCR to 640 (not offset by one).
That means the timer counts up 200 times per microsecond.
5280 / 200 gives us the 26.4 µs that we need for one line and 640 / 200 gives us the 3.2 µs for the sync pulse.&lt;/p&gt;
&lt;p&gt;For vsync I set the prescaler to 21119.
21120 / 200 gives us 105.6 µs, which is the width our sync pulse should be.
So then we can set the CCR to 1.
The ARR is set to 156 to give us 105.6 µs * 157 = 16.5792 ms, which is exactly the time a whole frame should take.&lt;/p&gt;
&lt;h1 id=&quot;all-green-all-the-time-not-working&quot;&gt;All Green all the Time Not Working&lt;/h1&gt;
&lt;p&gt;My hope was that I could get to a fully green picture pretty easily by just hooking up the green pin to a GPIO pin that was on.
That ended up not working, I suspect because the monitor uses the voltage that&#39;s on the color pins during the h-sync as a baseline or something like that.&lt;/p&gt;
&lt;h1 id=&quot;dma-to-the-dac&quot;&gt;DMA to the DAC&lt;/h1&gt;
&lt;p&gt;The next plan was to continuously repeat a single line.
I decided to try to use the Digital-to-analog converter (DAC) for this.&lt;/p&gt;
&lt;p&gt;The basic way the DAC works is that you first need to set a GPIO pin that&#39;s hooked up to the DAC into an analog mode.
This isn&#39;t one of the altenate functions like you&#39;d use for the timer, but a whole separate mode.
Then there&#39;s a data holding register you can write an 8 or 12 bit value into.
That will determine the output voltage you get on the pin.&lt;/p&gt;
&lt;p&gt;Now, we don&#39;t want to keep the CPU fully occupied with constantly setting that register, so we need a better solution.
Luckily the h7 has dedicated units for copying memory around.
There&#39;s actually at least four different kinds of these, but we&#39;ll start with a &quot;normal&quot; direct memory access controller (DMA).
There&#39;s two of those, but well use DMA1.&lt;/p&gt;
&lt;p&gt;When I wanted to map the DAC control registers into my task I got a build error.
As it turns out, the memory protection unit only supports eight memory regions at a time, meaning per-task in Hubris.
I resolved that by grouping some timers together.
They also need to have a power-of-two size and be aligned to their size, which would lead to problems later when I tried to group more things together, but it worked out for the timers.&lt;/p&gt;
&lt;p&gt;What I ended up doing here is to hooking up the timer to the DAC and configuring the DMA request multiplexer (DMAMUX) to be triggered by the DAC.
Then I set up the DAC in circular mode with a pointer to a buffer.&lt;/p&gt;
&lt;p&gt;Eventually I got it looking like that (with a lot of flickering of course):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lasernoises.com/blog/hubris-vga/./3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now that wasn&#39;t looking very much like the data that I wanted to DMA into DAC.
It was also changing quite a bit based on what exactly the code around it did (like adding something do a debugging ringbuffer).
It appears that the DMA unit doesn&#39;t go through the CPU caches, so likely this was some random data.&lt;/p&gt;
&lt;p&gt;After some digging I found out that there&#39;s different kinds of memory on this chip that are configured differently in Hubris.
You can see that configuration in &lt;a rel=&quot;external&quot; href=&quot;https://github.com/oxidecomputer/hubris/blob/69d379375269dab7c4ac67c3d88605736ec32fbd/chips/stm32h7/memory-large.toml&quot;&gt;chips/stm32h7/memory-large.toml&lt;/a&gt;.
Among others there&#39;s a &lt;code&gt;dma&lt;/code&gt; flag that can be set for a region.
I&#39;m not sure what that does exacly (it looks like one thing is that the kernel will refuse to copy
from or to there), but putting my buffer there using the &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute&quot;&gt;link_section&lt;/a&gt;
attribute seems to make our DMA work.&lt;/p&gt;
&lt;p&gt;After I got that to work all that was left was a lot of confusion because I had gotten the math for the pixel timing wrong.
But after I had figured that out I was able to produce a nice gradient.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lasernoises.com/blog/hubris-vga/./12.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;(If you&#39;re confused about the color: I had switched to blue instead of green at some point.)&lt;/p&gt;
&lt;p&gt;Switching between on and off pixels leads to a pattern like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lasernoises.com/blog/hubris-vga/./11.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The DAC seems unable to produce sharp edges and also the average output seems to get higher after switching on and off a couple of times.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.programmerall.com/article/26476558/&quot;&gt;Here&lt;/a&gt; they used the SPI hardware support to produce an image, so maybe I should try that next as well.&lt;/p&gt;
&lt;h1 id=&quot;return-of-the-sys-task&quot;&gt;Return of the Sys Task&lt;/h1&gt;
&lt;p&gt;The next thing I wanted to do of course was to produce an actual 2 dimensional image.
So far the CPU hadn&#39;t been involved after setting up the registers.
The DMA would keep going even if the CPU was halted.&lt;/p&gt;
&lt;p&gt;This starts to become a problem for a 2D image though.
If we were to keep our circular mode buffer and wanted to store a whole image in it we&#39;d need a bunch of bytes for that.
While we can horizontally repeat the same pixel 8 times (by decreasing the timer frequency), we can&#39;t do that vertically.
So we&#39;d need 132 (1056 / 8) × 628 = 82896 bytes for that buffer.&lt;/p&gt;
&lt;p&gt;That would fit into one of the sram regions, but it&#39;s a bit of an inconvenient format for a framebuffer with vertical pixels being 8 times smaller than horizontal ones.&lt;/p&gt;
&lt;p&gt;Luckily there&#39;s the master direct memory access controller (MDMA), which can be triggered by the completion of other DMA controllers and supports much more complex
configuration.&lt;/p&gt;
&lt;p&gt;But at this point I was definitely out of regions that could be mapped to my task.
Since it was very clear at this point that we weren&#39;t goint to do high speed GPIO toggling on the CPU we could actually re-introduce the &lt;code&gt;sys&lt;/code&gt; task.
This means that we could get rid of two regions from our task (RCC and GPIO) and we&#39;d have space for the MDMA control registers.
It&#39;s kind of funny how this hardware limitation can encourage splitting things into different tasks.&lt;/p&gt;
&lt;p&gt;I was able to get the MDMA copying into the DMA buffer, but I haven&#39;t quite been able to get a framebuffer working yet.
So this is the end of this post.
I hope I&#39;ll find some more time for this project soon and I&#39;ll try to make another post if I get something more interesting going.
I already have some ideas about what to do with a working framebuffer.&lt;/p&gt;
</content>
        
    </entry>
</feed>
