<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<title>Marmablog</title>
	<subtitle>A blog containing the musings of a marmamorph</subtitle>
	<link href="https://marmamorphism.com/posts/feed.xml" rel="self" type="application/atom+xml"/>
    <link href="https://marmamorphism.com/posts/"/>
	<updated>2025-12-23T00:00:00+00:00</updated>
	<id>https://marmamorphism.com/posts/feed.xml</id>
	<entry xml:lang="en">
		<title>&#x27;Audiobooks are not reading&#x27;: a Microcosm of Conservative Outrage</title>
		<published>2025-12-23T00:00:00+00:00</published>
		<updated>2025-12-23T00:00:00+00:00</updated>
		<link href="https://marmamorphism.com/posts/3-audiobooks-not-reading/" type="text/html"/>
		<id>https://marmamorphism.com/posts/3-audiobooks-not-reading/</id>
		<content type="html">&lt;p&gt;You sat down to read a book.
Cracking open a heavy tome feels good.
The weight in your hands, the feel of the pages, reading is an experience.
Then computers got involved.
Now you&#x27;re reading text on screens: laptops, ipads, etc.
These devices don&#x27;t have the same experience and to a certain extent strain your eyes.
The act of reading has been diminished.
Then computers jumped the shark.
Now they read to you instead of you reading yourself.
Like a toddler being comforted with their favorite children&#x27;s story by their parent.
Reading has not been diminished, it has been destroyed.
Yet, somehow a collection of adults find enjoyment in listening to their computers read to them.
Fine, you say, it doesn&#x27;t bother me, just don&#x27;t pretend its reading.
A few years later you hear about people &quot;reading&quot; hundreds of books a year.
Impossible, you think, they&#x27;re &lt;em&gt;listening&lt;&#x2F;em&gt; to those books, and probably at accelerated speeds.
How can anyone call this reading?
How can anyone call this fair?&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-is-reading-anyway&quot;&gt;What is reading anyway?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-is-reading-anyway&quot; aria-label=&quot;Anchor link for: what-is-reading-anyway&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;The verb &lt;em&gt;read&lt;&#x2F;em&gt; appears to originate from a word meaning (simplifying) &quot;to persuade&quot; or &quot;to learn.&quot;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Middle English reden, ireden, &quot;to counsel, advise,&quot; also &quot;to read,&quot; from Old English rædan, gerædan (West Saxon), redan, geredan (Anglian) &quot;to advise, counsel, persuade; discuss, deliberate; rule, guide; arrange, equip; forebode; to read (observe and apprehend the meaning of something written), utter aloud (words, letters, etc.); to explain; to learn through reading; to put in order.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;-- &lt;cite&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.etymonline.com&#x2F;word&#x2F;read&quot;&gt;etymonline&lt;&#x2F;a&gt;&lt;&#x2F;cite&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Handwritten words in ancient manuscripts and texts were particularly taxing to read for a number of reasons. ... Hence a reader had to pick out words (a combination of seeing, identifying, choosing, and selecting) from a wall of text before the piece could be read.&lt;&#x2F;p&gt;
&lt;p&gt;-- &lt;cite&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;english.stackexchange.com&#x2F;questions&#x2F;239630&#x2F;how-did-pick-out-evolve-to-mean-read&quot;&gt;Mari-Lou A&lt;&#x2F;a&gt;&lt;&#x2F;cite&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Let us not pretend that a cursory investigation of non-primary internet sources counts as research.
However, it delivers an important point: the verb &lt;em&gt;read&lt;&#x2F;em&gt; has, like pretty much every word, changed with time.
There is then an obvious counterargument to the above claim that listening to an audiobook is not reading.
That is, that the verb &lt;em&gt;read&lt;&#x2F;em&gt; is undergoing a cultural shift, language is adapting.&lt;&#x2F;p&gt;
&lt;p&gt;The first microcosm of conservatism is in objection to this claim.
A language purist would reject this idea, saying that the verb &lt;em&gt;read&lt;&#x2F;em&gt; should not meet the demands of the culture it is surrounded by.
History makes it clear this is a losing battle.
One need only know the definition of etymology to understand that the meanings of words will change whether you like it or not.
Nevertheless, the &lt;em&gt;resistance&lt;&#x2F;em&gt; to this change is fundamentally a conservative principle.&lt;&#x2F;p&gt;
&lt;p&gt;On the other hand, why should a person who listens to an audiobook call it reading?
This is a matter of personal experience.
If listening to the audiobook gives the perception (the feeling) of having read the book, then from that experience it is reasonable to call it reading.
Likewise, some will listen to an audiobook and feel that is very different from traditional reading, and they would be inclined to not equate the two.
Why then do people insist that listening to an audiobook is not reading?&lt;&#x2F;p&gt;
&lt;h1 id=&quot;ego-injury&quot;&gt;Ego injury&lt;a class=&quot;zola-anchor&quot; href=&quot;#ego-injury&quot; aria-label=&quot;Anchor link for: ego-injury&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;Not to be confused with narcissistic injury which is albeit a bit harsh for the present question.
Regardless, there is an emotional investment in reading being traditional.
Using the visual senses to ingest and consume the written word is considered a harder task than listening.
It feels as though the person who generated the audio, the reader, has done the hard phonetic work.
In what sense is the listener doing any of this hard work?
How dare they perceive their experience as reading when they have taken a shortcut.&lt;&#x2F;p&gt;
&lt;p&gt;This argument from toil is probably also why most people consider braille reading without a second thought.
Well of course it!
Deciphering and processing braille is a hard task, the brain is really grooving.
Hence, those who read traditionally want their efforts to be rewarded and not devalued by the audiobook listeners.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;elitism&quot;&gt;Elitism&lt;a class=&quot;zola-anchor&quot; href=&quot;#elitism&quot; aria-label=&quot;Anchor link for: elitism&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;Since audiobooks are here to stay some degree of elitism creeps in.
Whether it be from the conservative desire to maintain the proper definition of &lt;em&gt;read&lt;&#x2F;em&gt; or the ego injury involved in audiobooks being too easy the consequence is the same.
The traditional reader is &lt;em&gt;better&lt;&#x2F;em&gt; because they read Robert Jordan&#x27;s &quot;Wheel of Time&quot; series the old-fashioned way.
They suffered through book 10 like everyone else and didn&#x27;t cheat it with 2.0x speed through the boring slow parts.
A conservative ingroup forms around those who agree that traditional reading is what reading really is.
Why people join this ingroup is multifaceted, and it is a mistake to assume that the two above reasons are the &lt;em&gt;only&lt;&#x2F;em&gt; possible reasons.
Regardless, the ingroup is inherently conservative.
It resists the change of audiobooks and tries to impose either restrictions or malice on the outgroup.&lt;&#x2F;p&gt;
&lt;p&gt;This is a particularly interesting microcosm of this effect, because strictly speaking there is nothing stopping an otherwise perfectly progressive person from having an ego injury involving reading.
They can fall in line with an entirely conservative perspective on the world.
Moreover, there is an argument to be made that diminishing the efforts of listening to an audiobook is ableist.
Why must the person who struggles with visually consuming a book be forced to use braille when they much prefer listening?
Here is where the ingroup typically makes the fuzzy exceptions: &quot;Well not them of course, the disabled don&#x27;t count.&quot;
Not unlike a leftist space that forgets transmen actually exist.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;is-this-a-rant-or-an-analysis&quot;&gt;Is this a rant or an analysis?&lt;a class=&quot;zola-anchor&quot; href=&quot;#is-this-a-rant-or-an-analysis&quot; aria-label=&quot;Anchor link for: is-this-a-rant-or-an-analysis&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;Until this point I&#x27;ve attempted to hold off on moral judgment, but I think you can read between the lines.
Yes, it&#x27;s true, I think listening to audiobooks is reading.
I am morally against the ingroup formed in rejection of this claim and do view it as an immoral conservative ideology.
However, it is a fascinating microcosm of many different arguments and confusions faced in the public sphere.&lt;&#x2F;p&gt;
&lt;p&gt;For example, modern conservatives love to object that progressives can&#x27;t define &lt;em&gt;woman&lt;&#x2F;em&gt;.
If listening is reading, what&#x27;s next, your Gen AI is reading by downloading text?
Defining woman is a difficult task for a progressive because it requires a great deal of critical thought about both the complexities of sex (in particular intersex individuals) and the complexities of gender (in particular the performance of gender).
Yet, understanding all the minutiae is difficult and boring, and why bother when traditional womanhood is something you are emotionally invested in.&lt;&#x2F;p&gt;
&lt;p&gt;Another example is post hoc rationalization.
The modern conservative will claim that transwomen do harm to traditional women, particularly in high school or college sports.
Likewise, listening to audiobooks is bad for the youth, because of the current literary crisis.
Both of these arguments are interesting because there is a problem here we do deeply care about.
Yes, we want women to have equal opportunities especially in their developmental years, but where exactly is the connection that transwomen are a hindrance?
Yes, we want kids to be literate, but where exactly is the connection that audiobooks are a hindrance?
I conjecture that the immoral conservative ideology finds a rejection of traditional values it dislikes then post hoc rationalizes this position by reaching for the nearest plausible explanation.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;an-ode-to-conservatism&quot;&gt;An ode to conservatism&lt;a class=&quot;zola-anchor&quot; href=&quot;#an-ode-to-conservatism&quot; aria-label=&quot;Anchor link for: an-ode-to-conservatism&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;Let it be known that a conservative ideology is not by its nature immoral.
Indeed, one could argue that vaccines were a conservative ideology for a while.
It is only a recent populist change against a perceived elitist class (scientists) and argued from a place of fear (conspiracy really) that vaccines should not be mandated.
Having stability in a morally good cultural value is itself a moral good.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Program Synthesis in Idris 2</title>
		<published>2023-08-02T00:00:00+00:00</published>
		<updated>2023-08-02T00:00:00+00:00</updated>
        <summary>&lt;p&gt;Program synthesis enables a tool to automatically generate a program matching some specification.
In Idris 2 specifically this capability is espoused as a better method of interacting with the tool.
Indeed, the conjecture is that in dependent type theory we sometimes fully specify the function in the type anyway, so why bother writing it again?&lt;&#x2F;p&gt;</summary>
		<link href="https://marmamorphism.com/posts/2-program-synthesis-in-idris/" type="text/html"/>
		<id>https://marmamorphism.com/posts/2-program-synthesis-in-idris/</id>
		<content type="html">&lt;p&gt;Program synthesis enables a tool to automatically generate a program matching some specification.
In Idris 2 specifically this capability is espoused as a better method of interacting with the tool.
Indeed, the conjecture is that in dependent type theory we sometimes fully specify the function in the type anyway, so why bother writing it again?&lt;&#x2F;p&gt;
&lt;span id=&quot;continue-reading&quot;&gt;&lt;&#x2F;span&gt;
&lt;h1 id=&quot;abstract-view-of-program-synthesis&quot;&gt;Abstract View of Program Synthesis&lt;a class=&quot;zola-anchor&quot; href=&quot;#abstract-view-of-program-synthesis&quot; aria-label=&quot;Anchor link for: abstract-view-of-program-synthesis&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;What is program synthesis?
Consider a functional program with the following type:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Program synthesis is the problem of finding &lt;em&gt;any&lt;&#x2F;em&gt; program that satisfies some constraints (in this case the type).
For example, the following synthesized program is a valid answer:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, this isn&#x27;t the kind of answer we expect, but it is an answer!
The problem:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;the type of &lt;code&gt;add&lt;&#x2F;code&gt; is not specific enough to arrive at the function we expect&lt;&#x2F;li&gt;
&lt;li&gt;and the heuristics we use to determine which program to pick are badly tuned&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Abstractly, program synthesis works over some syntax of programs and some set of edit actions and generates a graph of possible programs.
This graph can be &lt;em&gt;infinitely&lt;&#x2F;em&gt; large if not at least exponentially large, depending entirely on the syntax and edit actions the synthesis is working over.
For this reason it is important to not only pick a small set of desirable edit actions but to prune&#x2F;order the search space with heuristics.
Indeed, program synthesis is ultimately a traversal of the generated graph.&lt;&#x2F;p&gt;
&lt;p&gt;To sum it up precisely, program synthesis consists of the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A set of syntactic forms &lt;em&gt;with holes&lt;&#x2F;em&gt; (usually represented as an inductive type), $\mathcal{S}$&lt;&#x2F;li&gt;
&lt;li&gt;A type representing available information at a given hole, $\mathcal{Ctx}$&lt;&#x2F;li&gt;
&lt;li&gt;A set of edit actions $e \in \mathcal{E}$ with type $e : \mathcal{Ctx} \to \mathcal{S}$&lt;&#x2F;li&gt;
&lt;li&gt;A (usually coinductive) traversal algorithm $\mathcal{T}$ with type $\mathcal{T} : \mathcal{S} \to \text{Stream}\ \mathcal{S}$&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For example, suppose our syntax consists of all Haskell programs, and we have four edit actions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Case split on a variable&lt;&#x2F;li&gt;
&lt;li&gt;Try a variable in context if the types match&lt;&#x2F;li&gt;
&lt;li&gt;Try a constructor if the types match&lt;&#x2F;li&gt;
&lt;li&gt;Try a recursive call if the types match&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;One path through the graph is: case split on the first input (generates two holes); try constructor 0 on first hole; recursive call on input (generates two holes); constant 1 on first hole; second variable on second hole.
This sequence is visualized below:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- starting node
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- 1st edit action
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;add (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- 2nd edit action
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;add (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- 3rd edit action
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;add (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- 4th edit action
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;add (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- 5th edit action
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;add (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt; m
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, with this definition program synthesis could produce a goal with a hole.
This may or may not be desirable, but it is easy to throw away leaf nodes that have holes (i.e. programs with holes that somehow have no valid edit actions).&lt;&#x2F;p&gt;
&lt;p&gt;Note that the traversal algorithm produces a stream of possibilities because we want the user to be able to cycle through different synthesized programs, in case the first attempt is not desirable.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;program-synthesis-in-idris-2&quot;&gt;Program Synthesis in Idris 2&lt;a class=&quot;zola-anchor&quot; href=&quot;#program-synthesis-in-idris-2&quot; aria-label=&quot;Anchor link for: program-synthesis-in-idris-2&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;The following description is synthesized from these resources:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=E7uSsL8r_mU&quot;&gt;Secrets of type driven program synthesis - Edwin Brady | Lambda Days 2021&lt;&#x2F;a&gt; (the slides are available &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.lambdadays.org&#x2F;static&#x2F;upload&#x2F;media&#x2F;1613990474814809idrissynthesisedwinbrady.pdf&quot;&gt;here&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=s9PAb9c6J44&quot;&gt;Dependent Type Driven Program Synthesis&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;idris-lang&#x2F;Idris2&#x2F;blob&#x2F;main&#x2F;src&#x2F;TTImp&#x2F;Interactive&#x2F;ExprSearch.idr&quot;&gt;Idris 2 source code for expression search&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The syntax of Idris 2 is a dependent type theory with a Haskell-style, not unlike the syntax of Agda.
The main difference is that Idris 2 has &lt;em&gt;quantities&lt;&#x2F;em&gt; in its function types.&lt;&#x2F;p&gt;
&lt;p&gt;For Idris&#x27; program synthesis it consists of three &quot;major&quot; edit actions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Initialize&lt;&#x2F;li&gt;
&lt;li&gt;Case split on an input variable (heuristic: limited to depth of 1, no nested case splitting)&lt;&#x2F;li&gt;
&lt;li&gt;Expression search&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Expression search consist of a list of &quot;minor&quot; edit actions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Try a variable in context when the type of the hole can be unified (heuristic: also try pair projections &lt;code&gt;fst&lt;&#x2F;code&gt; and &lt;code&gt;snd&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Try a lambda if the type of the hole is a function type&lt;&#x2F;li&gt;
&lt;li&gt;Try a constructor for the type of the hole when the resulting types can be unified, then expression search on the holes for the constructor arguments&lt;&#x2F;li&gt;
&lt;li&gt;Try a recursive call with a descending argument to the function being defined (heuristic: also try let-abstracting this recursive call)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The traversal algorithm will initialize a function, and then try expression search followed by case splitting (left-to-right).
Expression search will try all its minor edit actions in order.
Moreover, the traversal algorithm will generate a batch of candidates (of a small size, ~16) and orders that batch by number of inputs used.
The idea is that a program &lt;em&gt;probably&lt;&#x2F;em&gt; wanted to use all inputs, so those synthesized programs should be presented first.&lt;&#x2F;p&gt;
&lt;p&gt;The &quot;Initialize&quot; action simply sets up the function with input variables and a hole for the body:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- initialize edit
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &quot;Case Split&quot; action will case split only to depth of 1 and left-to-right, below is an example of it being applied three times:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- initialize edit
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- 1st case split
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;add (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- 2nd case split
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0 0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; (m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;span&gt;add (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;add (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) (m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- 3rd case split
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- fails
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For expression search, many edits only work if the synthesized expressions type unifies with the holes type.
Unification is needed in the case of Idris because types may be dependent and may have implicit arguments.
For example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span&gt;f &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Vec A&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Vec A&lt;&#x2F;span&gt;&lt;span&gt; (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;f v &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- edit try v
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- fails, Vec A n != Vec A (n + 1)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The implementation has a method of unifying types already as that is required for type checking.
In the above case, there is no way to unify the type of the variable &lt;code&gt;v&lt;&#x2F;code&gt; and the type of the hole &lt;code&gt;?0&lt;&#x2F;code&gt; so the try-variable edit action fails.
Unification is not strictly needed to accomplish this kind of goal, it depends on the language.
Indeed, convertibility of types will also work, but it might miss programs that unification would be able to unify.&lt;&#x2F;p&gt;
&lt;p&gt;This unification check is also important when trying constructors because the type might refute a particular constructor as possible.
For example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span&gt;f &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Vec A&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Vec A&lt;&#x2F;span&gt;&lt;span&gt; (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;f a v &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- edit try constructor vnil
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- fails Vec A (n + 1) != Vec A 0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When synthesis tries the &lt;code&gt;vnil&lt;&#x2F;code&gt; constructor for a vector that we know &lt;em&gt;must&lt;&#x2F;em&gt; have at least one element, unification is unable to unify the type of &lt;code&gt;vnil&lt;&#x2F;code&gt; with the type of the hole &lt;code&gt;?0&lt;&#x2F;code&gt;.
Thus, the &lt;code&gt;vnil&lt;&#x2F;code&gt; constructor is rejected and the &lt;code&gt;vcons&lt;&#x2F;code&gt; constructor is tried instead:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span&gt;f &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;A &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Vec A&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Vec A&lt;&#x2F;span&gt;&lt;span&gt; (n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;f a v &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- edit try constructor vcons
&lt;&#x2F;span&gt;&lt;span&gt;f a v &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vcons &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- edit try variable
&lt;&#x2F;span&gt;&lt;span&gt;f a v &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vcons a &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- edit try variable
&lt;&#x2F;span&gt;&lt;span&gt;f a v &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vcons a v
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, synthesis could have tried the variable &lt;code&gt;v&lt;&#x2F;code&gt; in hole &lt;code&gt;?1&lt;&#x2F;code&gt; but again the types would not unify, as the type of &lt;code&gt;?1&lt;&#x2F;code&gt; is &lt;code&gt;A&lt;&#x2F;code&gt;.
Unification in this way is &lt;em&gt;pruning&lt;&#x2F;em&gt; search paths in the graph.
When unification succeeds it also tends to prune the search space by forcing the definition of holes that show up in implicit arguments of types.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;manually-worked-examples&quot;&gt;Manually Worked Examples&lt;a class=&quot;zola-anchor&quot; href=&quot;#manually-worked-examples&quot; aria-label=&quot;Anchor link for: manually-worked-examples&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;Below we work some examples following the Idris 2 traversal algorithm.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;addition-of-naturals-with-no-specification&quot;&gt;Addition of Naturals with No Specification&lt;a class=&quot;zola-anchor&quot; href=&quot;#addition-of-naturals-with-no-specification&quot; aria-label=&quot;Anchor link for: addition-of-naturals-with-no-specification&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- initialize
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- expression search on ?0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable n in context, Nat = Nat
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- done (1)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable m in context, Nat = Nat
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- done (2)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor 0
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- done (3), Nat = Nat
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor S
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable n in context, Nat = Nat
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- done (4)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The order of the batch would list (1), (2), and (4) arbitrarily followed by (3)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;addition-of-naturals-with-specification&quot;&gt;Addition of Naturals with Specification&lt;a class=&quot;zola-anchor&quot; href=&quot;#addition-of-naturals-with-specification&quot; aria-label=&quot;Anchor link for: addition-of-naturals-with-specification&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;AddSpec &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;where
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Zero &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat&lt;&#x2F;span&gt;&lt;span&gt;} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;AddSpec 0&lt;&#x2F;span&gt;&lt;span&gt; m
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat&lt;&#x2F;span&gt;&lt;span&gt;} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;AddSpec&lt;&#x2F;span&gt;&lt;span&gt; n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;AddSpec&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) m
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;AddSpec&lt;&#x2F;span&gt;&lt;span&gt; n m
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- initialize
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- expression search on ?0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable n in context, Nat != AddSpec n m
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable m in context, Nat != AddSpec n m
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Zero,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- AddSpec 0 ?1 != AddSpec n m
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- (because 0 != n, but we can unify ?1 = m)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Succ,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- AddSpec (S ?1) ?2 = AddSpec n m
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- cannot unify S ?1 and n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try a recursive call, but no input is descending
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- case split on n
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- ?0: try variable m in context, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- ?0: try constructor Zero,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- AddSpec 0 ?2 = AddSpec 0 m
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- unification forces ?2 = m
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Zero
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable n in context, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable m in context, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Zero, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Succ,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- AddSpec (S ?3) ?4 = AddSpec (S n) m
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- unification forces ?3 = n and ?4 = m
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- now ?5 : AddSpec n m
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable n in context, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable m in context, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Zero, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Succ, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try recursive call on descending argument (n and m)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- add n m : AddSpec n m which unifies
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- note the traversal could have tried (n and n)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- but this would not unify AddSpec n n != AddSpec n m
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- so the only valid recursive call is `add n m`
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ&lt;&#x2F;span&gt;&lt;span&gt; (add n m) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- done
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- by design there is only one valid program to generate
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that as of July 2023 Idris 2 will find this definition.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;addition-of-naturals-with-partial-specification&quot;&gt;Addition of Naturals with Partial Specification&lt;a class=&quot;zola-anchor&quot; href=&quot;#addition-of-naturals-with-partial-specification&quot; aria-label=&quot;Anchor link for: addition-of-naturals-with-partial-specification&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;data &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;AddSpec &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;where
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Zero &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;AddSpec 0
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat&lt;&#x2F;span&gt;&lt;span&gt;} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;AddSpec&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;AddSpec&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Nat&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;AddSpec&lt;&#x2F;span&gt;&lt;span&gt; n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- initialize
&lt;&#x2F;span&gt;&lt;span&gt;add n m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- expression search on ?0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable n in context, Nat != AddSpec n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable m in context, Nat != AddSpec n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Zero,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- AddSpec 0 != AddSpec n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Succ,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- AddSpec (S ?1) = AddSpec n
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- cannot unify (S ?1) and n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try a recursive call, but no input is descending
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- case split on n
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- ?0: try variable m in context, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- ?0: try constructor Zero,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- AddSpec 0 = AddSpec 0
&lt;&#x2F;span&gt;&lt;span&gt;add &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Zero
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable n in context, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable m in context, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Zero, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Succ,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- AddSpec (S ?2) = AddSpec (S n)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- unification forces ?2 = n
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- now ?3 : AddSpec n
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable n in context, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable m in context, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Zero, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Succ, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try recursive call on descending argument (n and m)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- add n m : AddSpec n m which unifies
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ&lt;&#x2F;span&gt;&lt;span&gt; (add n m) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- done (1)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- but now there are more options!
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- case split on m
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; m) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;4
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- ?3: try variable n, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- ?3: try constructor Zero, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- ?3: try constructor Succ, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- ?3: try recursive call on descending arguments (n and n)
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ&lt;&#x2F;span&gt;&lt;span&gt; (add n n)
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; m) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;4
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable n, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try variable m, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Zero, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try constructor Succ, fails
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try recursive call on descending arguments (n and m)
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ&lt;&#x2F;span&gt;&lt;span&gt; (add n n)
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; m) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ&lt;&#x2F;span&gt;&lt;span&gt; (add n m) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- done (2)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- try recursive call on descending arguments (n and n)
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ&lt;&#x2F;span&gt;&lt;span&gt; (add n n)
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; m) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ&lt;&#x2F;span&gt;&lt;span&gt; (add n n) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;-- done (3)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that as of July 2023 Idris will return the 2nd definition as its first synthesis:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haskell&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-haskell &quot;&gt;&lt;code class=&quot;language-haskell&quot; data-lang=&quot;haskell&quot;&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ&lt;&#x2F;span&gt;&lt;span&gt; (add n n)
&lt;&#x2F;span&gt;&lt;span&gt;add (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; n) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span&gt; m) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bd93f9;&quot;&gt;Succ&lt;&#x2F;span&gt;&lt;span&gt; (add n m)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Thus, the manually worked example is missing some details of the complete algorithm, most likely to do with how Idris 2 picks descending arguments or how the batch ordering interacts with case splitting.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>A Programming Language Wishlist</title>
		<published>2022-06-19T00:00:00+00:00</published>
		<updated>2022-06-19T00:00:00+00:00</updated>
        <summary>&lt;p&gt;I&#x27;ve been thinking about a programming language for a while that makes the trade-offs that I prefer.
The high-level overview is something like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;no bound variables;&lt;&#x2F;li&gt;
&lt;li&gt;a type system with at least dependent function types and refinement types;&lt;&#x2F;li&gt;
&lt;li&gt;a DSL (Domain Specific Language) system that is conducive to inspection and easy extension;&lt;&#x2F;li&gt;
&lt;li&gt;and efficient execution.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;</summary>
		<link href="https://marmamorphism.com/posts/1-gobble-wish-list/" type="text/html"/>
		<id>https://marmamorphism.com/posts/1-gobble-wish-list/</id>
		<content type="html">&lt;p&gt;I&#x27;ve been thinking about a programming language for a while that makes the trade-offs that I prefer.
The high-level overview is something like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;no bound variables;&lt;&#x2F;li&gt;
&lt;li&gt;a type system with at least dependent function types and refinement types;&lt;&#x2F;li&gt;
&lt;li&gt;a DSL (Domain Specific Language) system that is conducive to inspection and easy extension;&lt;&#x2F;li&gt;
&lt;li&gt;and efficient execution.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;span id=&quot;continue-reading&quot;&gt;&lt;&#x2F;span&gt;
&lt;p&gt;Let&#x27;s talk about each of these.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;no-bound-variables&quot;&gt;No Bound Variables&lt;a class=&quot;zola-anchor&quot; href=&quot;#no-bound-variables&quot; aria-label=&quot;Anchor link for: no-bound-variables&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;Bound variables are the heart and soul of the $\lambda$-calculus.
Variables give you the ability to mark internal sharing and are pretty natural based on mathematical practice.
So why get rid of them?
The reason is three-fold.&lt;&#x2F;p&gt;
&lt;p&gt;First, when you are dealing with first-class higher-order functions the variables get in the way of efficient execution by demanding some garbage collection discipline.
One choice to recover efficiency is enforced linearity (i.e. a variable can only occur once in the body), but now you&#x27;re placing a seemingly arbitrary restriction on what was standard practice.&lt;&#x2F;p&gt;
&lt;p&gt;Second, if you want easy quotable syntax the variables complicate things.
Now the users creating macros have to handle bound variables too, usually by hygienic patterns.
This is the path taken by many modern macro systems.&lt;&#x2F;p&gt;
&lt;p&gt;Third, if you do have a robust DSL system then you can add in bound variables without much issue.
To that point, why complicate the &lt;em&gt;core&lt;&#x2F;em&gt; system with bound variables if it can be implemented as a library feature?&lt;&#x2F;p&gt;
&lt;h1 id=&quot;rich-type-system&quot;&gt;Rich Type System&lt;a class=&quot;zola-anchor&quot; href=&quot;#rich-type-system&quot; aria-label=&quot;Anchor link for: rich-type-system&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;The lack of dependent types in most modern languages is caused by a few things.
Dependent types do not play nice with effects (e.g. non-termination, exceptions, I&#x2F;O), they can complicate type checking, and your average programmer is scared of them.
For a crash course in dependent function types, consider the following type: &lt;code&gt;Vec Nat n&lt;&#x2F;code&gt; which represents a list with &lt;em&gt;exactly&lt;&#x2F;em&gt; $n$ elements.
This is impossible to represent in a lot of languages but pretty trivial in a language with dependent types.
Together with the finite type: &lt;code&gt;Fin n&lt;&#x2F;code&gt; which represents a number in the range $[0, n)$ you have a safe, optimization friendly way to access arrays:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#8be9fd;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; array : &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#66d9ef;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt; Nat n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ...
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#8be9fd;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; index : Fin n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;= ...
&lt;&#x2F;span&gt;&lt;span&gt;    array[index] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;&#x2F;&#x2F; no bounds checks necessary
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Refinement types also seem like a pretty necessary feature, but they are more exotic.
Languages like &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;agda&#x2F;agda&quot;&gt;Agda&lt;&#x2F;a&gt; and &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;coq.inria.fr&#x2F;&quot;&gt;Coq&lt;&#x2F;a&gt; don&#x27;t have refinement types in the sense I mean, but &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.fstar-lang.org&#x2F;&quot;&gt;F*&lt;&#x2F;a&gt; does.
A simple refinement type is the type of even numbers:&lt;&#x2F;p&gt;
&lt;p&gt;$$\texttt{Even} = \{ n: \mathbb{N}\ |\ n = 0 \mod 2 \}$$&lt;&#x2F;p&gt;
&lt;p&gt;Critically, there should be a trivial cast (i.e. an identity function) that forgets the refinements and produces a natural number.
This is not the same as wrapping up a natural number in a dependent pair where the second component is a proof the first is even.
You also likely want some definitional equalities, such as $2 : \texttt{Even} \equiv 2 : \mathbb{N}$.
These choices cause you to have an extrinsic type theory (i.e. a given term can have more than one type).&lt;&#x2F;p&gt;
&lt;p&gt;Another critical requirement is that the type system supports axioms.
In particular, recursive types with the added &lt;em&gt;axiom&lt;&#x2F;em&gt; that they are well-founded.
This is in contrast to most systems which include syntactic requirements like strict positivity.
Although, in plenty of other systems, like &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.idris-lang.org&#x2F;&quot;&gt;Idris&lt;&#x2F;a&gt;, a type-in-type discipline is used which allows general recursive types (and thus inconsistency).&lt;&#x2F;p&gt;
&lt;p&gt;The point here is that recursive types should be an &lt;em&gt;unsafe&lt;&#x2F;em&gt; feature that demands some meta-obligations of the programmer, not unlike unsafe code in &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt;, or &quot;trust me&quot; annotations on recursive functions in Agda or Idris.
However, these &quot;trust me&quot; annotations are not spelled out in the formal core theory.
They are tacked on, and the burden is shifted to the user to make sure they do things right.&lt;&#x2F;p&gt;
&lt;p&gt;Coq and Rust do the best job, in my opinion, of giving the user guidelines of when axioms or meta-obligations are allowed.
Coq has an entire &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;coq&#x2F;coq&#x2F;wiki&#x2F;CoqAndAxioms&quot;&gt;wiki-page&lt;&#x2F;a&gt; about axioms that you can expect to not break your development.
Rust has some &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;ch19-01-unsafe-rust.html&quot;&gt;explicit rules&lt;&#x2F;a&gt; about what expectations are in place for unsafe code.
However, it should also be noted how difficult it is to do &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;gankra.github.io&#x2F;blah&#x2F;fix-rust-pointers&#x2F;&quot;&gt;pointer cast in unsafe Rust correctly&lt;&#x2F;a&gt;!
In this scenario, the meta-obligations are too strong.&lt;&#x2F;p&gt;
&lt;p&gt;Regardless, the trade-off is a powerful and necessary one.
Give the user an escape hatch with a well documented set of meta-obligations so that they can express themselves in code to the fullest extent possible.
Moreover, deciding that a recursive function is well-founded is a daily occurrence for programmers and it is often trivially terminating from the perspective of the programmer (but often not trivially terminating from the perspective of syntactic criterion used in Coq or Agda!)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;powerful-dsl-system&quot;&gt;Powerful DSL System&lt;a class=&quot;zola-anchor&quot; href=&quot;#powerful-dsl-system&quot; aria-label=&quot;Anchor link for: powerful-dsl-system&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;Let&#x27;s be honest, there is only one game in town when it comes to reasonable DSLs and that is &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;racket-lang.org&#x2F;&quot;&gt;Racket&lt;&#x2F;a&gt;.
I don&#x27;t have much experience with Racket and think there is a lot to learn there.
Also, I fundamentally agree that allowing the user to construct DSLs is important if you want a language to help a user express domain knowledge.
Yet, macro systems are a complete disaster.
The greatest failure of Lisp is perhaps its macro system.
Macros in Lisp are so powerful that they make code written by a programmer completely incomprehensible.
Somehow, they are also too weak to express the kinds of syntactic constructs that are more natural on pen-and-paper.
This is likely why Racket is a thing at all, if Lisp solved DSLs at the onset there would be no Racket.&lt;&#x2F;p&gt;
&lt;p&gt;What is needed of a good DSL system?
I think the following things:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;easy inspection via the core syntax both with a debug representation and the actual representation;&lt;&#x2F;li&gt;
&lt;li&gt;easy construction by well-known grammar definitions;&lt;&#x2F;li&gt;
&lt;li&gt;and easy combination and interoperability between DSLs.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To inspect a DSL I propose the requirement that any span of a DSL can be independently transformed into core syntax.
For example, consider the following DSL code:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#8be9fd;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#50fa7b;&quot;&gt;quadratic&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#ffb86c;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#8be9fd;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#ffb86c;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#8be9fd;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#ffb86c;&quot;&gt;c&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#8be9fd;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#8be9fd;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        a&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;a &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;b &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; c
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In case you missed the implication, a language without bound variables basically ends up looking like a variation on &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.forth.com&#x2F;forth&#x2F;&quot;&gt;Forth&lt;&#x2F;a&gt;.
Here is how I imagine the above representation being encoded:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#282a36;color:#f8f8f2;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    [
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;&#x2F;&#x2F; stack starts as [c, b, a]
&lt;&#x2F;span&gt;&lt;span&gt;        dup &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;*       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;&#x2F;&#x2F; compute a^2
&lt;&#x2F;span&gt;&lt;span&gt;        swap dup &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;*  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;&#x2F;&#x2F; compute b^2
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff79c6;&quot;&gt;+ +         &lt;&#x2F;span&gt;&lt;span style=&quot;color:#6272a4;&quot;&gt;&#x2F;&#x2F; compute a^2 + b^2 + c
&lt;&#x2F;span&gt;&lt;span&gt;    ]
&lt;&#x2F;span&gt;&lt;span&gt;    [quadratic]
&lt;&#x2F;span&gt;&lt;span&gt;    define
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where the syntax &lt;code&gt;[...]&lt;&#x2F;code&gt; is a &lt;em&gt;quote&lt;&#x2F;em&gt; inspired by &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Joy_(programming_language)&quot;&gt;Joy&lt;&#x2F;a&gt;.
Now, if a user selects the &lt;code&gt;b*b&lt;&#x2F;code&gt; span in the DSL, they should be able to see that it maps to &lt;code&gt;swap dup *&lt;&#x2F;code&gt; code in the core syntax.
It might not be the easiest to comprehend Forth-style (or really Joy-style) syntax for most programmers.
Indeed, it is likely better to describe it as a high-level assembler, but the benefits are that it does always make sense, even if it takes some effort to figure out what.
In contrast, someone&#x27;s invented notation with no documentation may &lt;em&gt;never&lt;&#x2F;em&gt; make sense.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;efficient-execution&quot;&gt;Efficient Execution&lt;a class=&quot;zola-anchor&quot; href=&quot;#efficient-execution&quot; aria-label=&quot;Anchor link for: efficient-execution&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;A concatenative programming language, which is ultimately what I am describing, yields to fairly obvious efficient execution by way of a linear type system.
The real issue only arises with quotes which are the replacement for higher-order functions.
For this, the proposed fix is to require that quotes are not data unless boxed or otherwise hidden behind a pointer.
Ultimately, this pushes the garbage collection duties to the user, they have to construct smart pointers like reference counting.&lt;&#x2F;p&gt;
&lt;p&gt;However, that is the main design principle behind all of this.
Keep the core language as simple as possible without sacrificing expressibility or power.
Push as much as possible into libraries.
As the design grows this core principle will remain.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Initial commit</title>
		<published>2022-06-16T00:00:00+00:00</published>
		<updated>2022-06-16T00:00:00+00:00</updated>
        <summary>&lt;p&gt;I haven&#x27;t written anything on my blog since 2017.
That is a very long time.
Personally, I think that is because I was under the illusion that the content of my blog has to be good, because people could read it.
The reality, is that even if some random person &lt;em&gt;does&lt;&#x2F;em&gt; read it the likelihood I interact with this person about a blog post that they &lt;em&gt;didn&#x27;t&lt;&#x2F;em&gt; like is basically zero.&lt;&#x2F;p&gt;</summary>
		<link href="https://marmamorphism.com/posts/0-initial-commit/" type="text/html"/>
		<id>https://marmamorphism.com/posts/0-initial-commit/</id>
		<content type="html">&lt;p&gt;I haven&#x27;t written anything on my blog since 2017.
That is a very long time.
Personally, I think that is because I was under the illusion that the content of my blog has to be good, because people could read it.
The reality, is that even if some random person &lt;em&gt;does&lt;&#x2F;em&gt; read it the likelihood I interact with this person about a blog post that they &lt;em&gt;didn&#x27;t&lt;&#x2F;em&gt; like is basically zero.&lt;&#x2F;p&gt;
&lt;span id=&quot;continue-reading&quot;&gt;&lt;&#x2F;span&gt;
&lt;p&gt;Anyway here is some $\KaTeX$ because I want to test it out with this new blog setup.&lt;&#x2F;p&gt;
&lt;p&gt;$$\int_0^x e^x dx$$&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m using Zola and the theme Serene, which you can see there at the bottom right.
It is pretty spiffy and I like the theme overall, zola is also really nice a step up from Jekyll in my opinion.
Anyway, if you are reading this, including you future Andrew, don&#x27;t take the blog too seriously, it&#x27;s just a romping good time.&lt;&#x2F;p&gt;
</content>
	</entry>
</feed>