<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>NotEuclid</title>
    <link>https://blog.noteuclid.ru/</link>
    <description></description>
    <pubDate>Fri, 17 Apr 2026 20:58:41 +0300</pubDate>
    <item>
      <title>JSON vs XML</title>
      <link>https://blog.noteuclid.ru/json-vs-xml</link>
      <description>&lt;![CDATA[Data serialization is a very common task, and JSON and XML are probably the most popular formats for that. They both can be used to store essentially arbitrary data. However that doesn’t mean they are interchangeable.&#xA;&#xA;For example, consider this XML document:&#xA;&#xA;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&#xA;bookstore&#xA;&#x9;book category=&#34;fiction&#34;&#xA;&#x9;&#x9;titleDragon Flames/title&#xA;&#x9;&#x9;authorJohn Doe/author&#xA;&#x9;&#x9;year2012/year&#xA;&#x9;&#x9;price35/price&#xA;&#x9;/book&#xA;&#x9;book category=&#34;non-fiction&#34;&#xA;&#x9;&#x9;titleLocalisation &amp;amp; Globalisation/title&#xA;&#x9;&#x9;authorSmith White/author&#xA;&#x9;&#x9;year2020/year&#xA;&#x9;&#x9;price120/price&#xA;&#x9;/book&#xA;/bookstore&#xA;&#xA;The same data can be encoded in JSON much more succinctly:&#xA;&#xA;{&#xA;&#x9;&#34;books&#34;: [&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;&#34;category&#34;: &#34;fiction&#34;,&#xA;&#x9;&#x9;&#x9;&#34;title&#34;: &#34;Dragon Flames&#34;,&#xA;&#x9;&#x9;&#x9;&#34;author&#34;: &#34;John Doe&#34;,&#xA;&#x9;&#x9;&#x9;&#34;year&#34;: 2012,&#xA;&#x9;&#x9;&#x9;&#34;price&#34;: 35&#xA;&#x9;&#x9;}, {&#xA;&#x9;&#x9;&#x9;&#34;category&#34;: &#34;non-fiction&#34;,&#xA;&#x9;&#x9;&#x9;&#34;title&#34;: &#34;Localisation &amp; Globalisation&#34;,&#xA;&#x9;&#x9;&#x9;&#34;author&#34;: &#34;Smith White&#34;,&#xA;&#x9;&#x9;&#x9;&#34;year&#34;: 2020,&#xA;&#x9;&#x9;&#x9;&#34;price&#34;: 120&#xA;&#x9;&#x9;}&#xA;&#x9;]&#xA;}&#xA;&#xA;This looks much better. However it’s not actually the same data. It may be the same for the application but, note the differences:&#xA;&#xA;year and price are numbers in JSON. XML doesn’t know numbers, they’re all strings.&#xA;category is an attribute in XML. In JSON it’s a field like everything else.&#xA;In XML each entry is labelled as a book separately. In JSON only the array is labelled (with a field name).&#xA;&#xA;For a specific application that probably doesn’t matter (though would be a big pain for a generic converter). But, consider a slightly modified example:&#xA;&#xA;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&#xA;bookstore&#xA;&#x9;book category=&#34;fiction&#34;&#xA;&#x9;&#x9;titleDragon Flames/title&#xA;&#x9;&#x9;authorJohn Doe/author&#xA;&#x9;&#x9;year2012/year&#xA;&#x9;&#x9;price35/price&#xA;&#x9;/book&#xA;&#x9;magazine category=&#34;non-fiction&#34;&#xA;&#x9;&#x9;titleLocalisation &amp;amp; Globalisation/title&#xA;&#x9;&#x9;editorSmith White/editor&#xA;&#x9;&#x9;year2020/year&#xA;&#x9;&#x9;price120/price&#xA;&#x9;/magazine&#xA;/bookstore&#xA;&#xA;The change is minuscule but, how to reflect it in JSON? One way is to use separate arrays for books and magazines but, if the relative order matters, the only way is to add a special key field, like:&#xA;&#xA;{&#xA;&#x9;&#34;items&#34;: [&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;&#34;$type&#34;: &#34;book&#34;,&#xA;&#x9;&#x9;&#x9;&#34;category&#34;: &#34;fiction&#34;,&#xA;&#x9;&#x9;&#x9;&#34;title&#34;: &#34;Dragon Flames&#34;,&#xA;&#x9;&#x9;&#x9;&#34;author&#34;: &#34;John Doe&#34;,&#xA;&#x9;&#x9;&#x9;&#34;year&#34;: 2012,&#xA;&#x9;&#x9;&#x9;&#34;price&#34;: 35&#xA;&#x9;&#x9;}, {&#xA;&#x9;&#x9;&#x9;&#34;$type&#34;: &#34;magazine&#34;,&#xA;&#x9;&#x9;&#x9;&#34;category&#34;: &#34;non-fiction&#34;,&#xA;&#x9;&#x9;&#x9;&#34;title&#34;: &#34;Localisation &amp; Globalisation&#34;,&#xA;&#x9;&#x9;&#x9;&#34;editor&#34;: &#34;Smith White&#34;,&#xA;&#x9;&#x9;&#x9;&#34;year&#34;: 2020,&#xA;&#x9;&#x9;&#x9;&#34;price&#34;: 120&#xA;&#x9;&#x9;}&#xA;&#x9;]&#xA;}&#xA;&#xA;This works but, it’s not all that clean anymore. Especially given that the field order can be arbitrary so, $type may end up somewhere in the middle.&#xA;&#xA;There is more however. XML isn’t just for data serialization, it can also handle text markup. In fact, that’s its original purpose. Consider:&#xA;&#xA;review user=&#34;Willy Smith&#34; rating=&#34;5&#34;&#xA;&#x9;pI’m emso/em glad I’ve read it! It’s great!/p&#xA;&#x9;pTotally recommend!/p&#xA;/review&#xA;&#xA;It is sure possible to store anything in JSON but...&#xA;&#xA;{&#xA;&#x9;&#34;user&#34;: &#34;Willy Smith&#34;,&#xA;&#x9;&#34;rating&#34;: 5,&#xA;&#x9;&#34;text&#34;: [&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;&#34;type&#34;: &#34;paragraph&#34;,&#xA;&#x9;&#x9;&#x9;&#34;content&#34;: [&#xA;&#x9;&#x9;&#x9;&#x9;&#34;I’m &#34;,&#xA;&#x9;&#x9;&#x9;&#x9;{ &#34;type&#34;: &#34;emphasis&#34;, &#34;content&#34;: &#34;so&#34; },&#xA;&#x9;&#x9;&#x9;&#x9;&#34; glad I’ve read it! It’s great!&#34;&#xA;&#x9;&#x9;&#x9;]&#xA;&#x9;&#x9;},&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;&#34;type&#34;: &#34;paragraph&#34;,&#xA;&#x9;&#x9;&#x9;&#34;content&#34;: &#34;Totally recommend!&#34;&#xA;&#x9;&#x9;}&#xA;&#x9;]&#xA;}&#xA;&#xA;...is it really desirable?&#xA;&#xA;And if you think the example is exaggerated, maybe a bit but, the real issue is mixing text and markup. JSON just isn’t designed to handle this.&#xA;&#xA;There is a reason however, why XML is often considered “legacy”. While it is actually much more flexible than JSON real-world data doesn’t need that flexibility, which gets in the way instead. Just look at the first example again: if all you need is a bunch of items with specific fields, JSON is perfectly good for it! Only if your data has to be a mixed bag of everything like an AST or “just” marked up text XML starts to gain advantage — and may end up being a better choice.&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>Data serialization is a very common task, and JSON and XML are probably the most popular formats for that. They both can be used to store essentially arbitrary data. However that doesn’t mean they are interchangeable.</p>

<p>For example, consider this XML document:</p>

<pre><code class="language-xml">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;
&lt;bookstore&gt;
	&lt;book category=&#34;fiction&#34;&gt;
		&lt;title&gt;Dragon Flames&lt;/title&gt;
		&lt;author&gt;John Doe&lt;/author&gt;
		&lt;year&gt;2012&lt;/year&gt;
		&lt;price&gt;35&lt;/price&gt;
	&lt;/book&gt;
	&lt;book category=&#34;non-fiction&#34;&gt;
		&lt;title&gt;Localisation &amp;amp; Globalisation&lt;/title&gt;
		&lt;author&gt;Smith White&lt;/author&gt;
		&lt;year&gt;2020&lt;/year&gt;
		&lt;price&gt;120&lt;/price&gt;
	&lt;/book&gt;
&lt;/bookstore&gt;
</code></pre>

<p>The same data can be encoded in JSON much more succinctly:</p>

<pre><code class="language-json">{
	&#34;books&#34;: [
		{
			&#34;category&#34;: &#34;fiction&#34;,
			&#34;title&#34;: &#34;Dragon Flames&#34;,
			&#34;author&#34;: &#34;John Doe&#34;,
			&#34;year&#34;: 2012,
			&#34;price&#34;: 35
		}, {
			&#34;category&#34;: &#34;non-fiction&#34;,
			&#34;title&#34;: &#34;Localisation &amp; Globalisation&#34;,
			&#34;author&#34;: &#34;Smith White&#34;,
			&#34;year&#34;: 2020,
			&#34;price&#34;: 120
		}
	]
}
</code></pre>

<p>This looks much better. However it’s not actually <em>the same</em> data. It may be the same for the application but, note the differences:</p>
<ul><li><code>year</code> and <code>price</code> are numbers in JSON. XML doesn’t know numbers, they’re all strings.</li>
<li><code>category</code> is an attribute in XML. In JSON it’s a field like everything else.</li>
<li>In XML each entry is labelled as a <code>book</code> separately. In JSON only the array is labelled (with a field name).</li></ul>

<p>For a specific application that probably doesn’t matter (though would be a <em>big</em> pain for a generic converter). But, consider a slightly modified example:</p>

<pre><code class="language-xml">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;
&lt;bookstore&gt;
	&lt;book category=&#34;fiction&#34;&gt;
		&lt;title&gt;Dragon Flames&lt;/title&gt;
		&lt;author&gt;John Doe&lt;/author&gt;
		&lt;year&gt;2012&lt;/year&gt;
		&lt;price&gt;35&lt;/price&gt;
	&lt;/book&gt;
	&lt;magazine category=&#34;non-fiction&#34;&gt;
		&lt;title&gt;Localisation &amp;amp; Globalisation&lt;/title&gt;
		&lt;editor&gt;Smith White&lt;/editor&gt;
		&lt;year&gt;2020&lt;/year&gt;
		&lt;price&gt;120&lt;/price&gt;
	&lt;/magazine&gt;
&lt;/bookstore&gt;
</code></pre>

<p>The change is minuscule but, how to reflect it in JSON? One way is to use separate arrays for books and magazines but, if the relative order matters, the only way is to add a special key field, like:</p>

<pre><code class="language-json">{
	&#34;items&#34;: [
		{
			&#34;$type&#34;: &#34;book&#34;,
			&#34;category&#34;: &#34;fiction&#34;,
			&#34;title&#34;: &#34;Dragon Flames&#34;,
			&#34;author&#34;: &#34;John Doe&#34;,
			&#34;year&#34;: 2012,
			&#34;price&#34;: 35
		}, {
			&#34;$type&#34;: &#34;magazine&#34;,
			&#34;category&#34;: &#34;non-fiction&#34;,
			&#34;title&#34;: &#34;Localisation &amp; Globalisation&#34;,
			&#34;editor&#34;: &#34;Smith White&#34;,
			&#34;year&#34;: 2020,
			&#34;price&#34;: 120
		}
	]
}
</code></pre>

<p>This <em>works</em> but, it’s not all that clean anymore. Especially given that the field order can be arbitrary so, <code>$type</code> may end up somewhere in the middle.</p>

<p>There is more however. XML isn’t just for data serialization, it can also handle text markup. In fact, that’s its <em>original</em> purpose. Consider:</p>

<pre><code class="language-xml">&lt;review user=&#34;Willy Smith&#34; rating=&#34;5&#34;&gt;
	&lt;p&gt;I’m &lt;em&gt;so&lt;/em&gt; glad I’ve read it! It’s great!&lt;/p&gt;
	&lt;p&gt;Totally recommend!&lt;/p&gt;
&lt;/review&gt;
</code></pre>

<p>It is sure possible to store <em>anything</em> in JSON but...</p>

<pre><code class="language-json">{
	&#34;user&#34;: &#34;Willy Smith&#34;,
	&#34;rating&#34;: 5,
	&#34;text&#34;: [
		{
			&#34;type&#34;: &#34;paragraph&#34;,
			&#34;content&#34;: [
				&#34;I’m &#34;,
				{ &#34;type&#34;: &#34;emphasis&#34;, &#34;content&#34;: &#34;so&#34; },
				&#34; glad I’ve read it! It’s great!&#34;
			]
		},
		{
			&#34;type&#34;: &#34;paragraph&#34;,
			&#34;content&#34;: &#34;Totally recommend!&#34;
		}
	]
}
</code></pre>

<p>...is it really desirable?</p>

<p>And if you think the example is exaggerated, maybe a bit but, the real issue is mixing text and markup. JSON just isn’t designed to handle this.</p>

<p>There is a reason however, why XML is often considered “legacy”. While it is actually much more flexible than JSON real-world data doesn’t <em>need</em> that flexibility, which gets in the way instead. Just look at the first example again: if all you need is a bunch of items with specific fields, JSON is perfectly good for it! Only if your data <em>has</em> to be a mixed bag of everything like an AST or “just” marked up text XML starts to gain advantage — and may end up being a better choice.</p>
]]></content:encoded>
      <guid>https://blog.noteuclid.ru/json-vs-xml</guid>
      <pubDate>Wed, 18 Dec 2024 19:21:47 +0000</pubDate>
    </item>
    <item>
      <title>Is something wrong with binary formats?</title>
      <link>https://blog.noteuclid.ru/is-something-wrong-with-binary-formats</link>
      <description>&lt;![CDATA[For quite some time I was wondering why are text formats so popular while binary formats often struggle. Even for graphics there is PPM, and JSON and HTTP¹ are now ubiquitous. While there are very popular binary formats like ELF and JPEG they are also very specialized, while less specialized formats like MsgPack and ProtoBuf are far less common.&#xA;&#xA;It was stated this is rooted in human capabilities: our mental recognition works well with text including text-based formats yet is totally unsuitable for binary data. While I do agree with that the core problem is subtler in my opinion.&#xA;&#xA;One part is human-machine interface (i.e. tooling). Image having half of your text files encoded in EBCDIC and some others in word-swapped UTF-32. Now suddenly, your mental recognition is of no use as your text editor just can’t open that and leaves you looking at 41 e2 c3 c9 c9 in the hex editor...&#xA;&#xA;That’s not enough for a problem though; after all if we have good tooling for text why can’t we have the same for binary? But the problem here is one detail that is so obvious it is often omitted:&#xA;&#xA;emText is binary./em&#xA;&#xA;Text is not an alternative to binary, it’s a binary format of its own. Or rather, a text encoding is; there are many but, what they encode is the very same notion of text, just like there are many image formats but what they encode is the same notion of pixels².&#xA;&#xA;Now, that may or may not be obvious but it doesn’t look like a problem. But the more interesting part is a corollary:&#xA;&#xA;Binary formats (like MsgPack) aren’t siblings of text formats (like JSON); they are siblings of the text format itself, of the venerable ASCII!&#xA;&#xA;This cuts it clear. Competing with XML and JSON is one thing but competing with ASCII is just another level entirely. No wonder there is no accepted universal binary format: there actually is one, and it’s called “text”.&#xA;&#xA;I think this is why EBCDIC has died. It is also probably a major reason Unicode succeeded despite all the pain: while for human-targeted data it may be beneficial to have tailored formats for different needs (scripts), for machine communication benefits of a single universal format are so enormous UTF-8 was accepted nevertheless.&#xA;&#xA;¹ Okay, HTTP 2 is not text-based anymore. Except it is, in a sense: it still uses textual key-value pairs, only wire-level encoding is a bit more complicated.&#xA;&#xA;² For raster image formats only, obviously.&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>For quite some time I was wondering why are text formats so popular while binary formats often struggle. Even for graphics there is <a href="https://ru.wikipedia.org/wiki/Portable_anymap">PPM</a>, and JSON and HTTP¹ are now ubiquitous. While there are <em>very</em> popular binary formats like ELF and JPEG they are also very specialized, while less specialized formats like MsgPack and ProtoBuf are far less common.</p>

<p>It was stated this is rooted in human capabilities: our mental recognition works well with text including text-based formats yet is totally unsuitable for binary data. While I do agree with that the core problem is subtler in my opinion.</p>

<p>One part is human-machine interface (i.e. tooling). Image having half of your text files encoded in EBCDIC and some others in word-swapped UTF-32. Now suddenly, your mental recognition is of no use as your text editor just can’t open that and leaves you looking at 41 e2 c3 c9 c9 in the hex editor...</p>

<p>That’s not enough for a problem though; after all if we have good tooling for text why can’t we have the same for binary? But the problem here is one detail that is so obvious it is often omitted:</p>

<p><em>Text <strong>is</strong> binary.</em></p>

<p>Text is not an alternative to binary, it’s a binary format of its own. Or rather, a text <em>encoding</em> is; there are many but, what they encode is the very same notion of text, just like there are many image formats but what they encode is the same notion of pixels².</p>

<p>Now, that may or may not be obvious but it doesn’t look like a problem. But the more interesting part is a corollary:</p>

<p><em>Binary formats (like MsgPack) aren’t siblings of text formats (like JSON); they are siblings of the text format itself, of the venerable ASCII!</em></p>

<p>This cuts it clear. Competing with XML and JSON is one thing but competing with ASCII is just another level entirely. No wonder there is no accepted universal binary format: there actually is one, and it’s called “text”.</p>

<p>I think this is why EBCDIC has died. It is also probably a major reason Unicode succeeded despite <a href="https://en.wikipedia.org/wiki/Han_unification">all the pain</a>: while for human-targeted data it may be beneficial to have tailored formats for different needs (scripts), for machine communication benefits of a single universal format are so enormous UTF-8 was accepted nevertheless.</p>

<p>¹ Okay, HTTP 2 is not text-based anymore. Except it is, in a sense: it still uses textual key-value pairs, only wire-level encoding is a bit more complicated.</p>

<p>² For raster image formats only, obviously.</p>
]]></content:encoded>
      <guid>https://blog.noteuclid.ru/is-something-wrong-with-binary-formats</guid>
      <pubDate>Sun, 20 Oct 2024 18:41:44 +0000</pubDate>
    </item>
    <item>
      <title>Another view on a monad</title>
      <link>https://blog.noteuclid.ru/another-view-on-a-monad</link>
      <description>&lt;![CDATA[Wikipedia describes a monad in some Haskell syntax. Oh well. But actually, one doesn’t need to know Haskell to understand what a monad is and how it can be used.&#xA;&#xA;Basics&#xA;&#xA;Suppose you have a FutureString but that string is actually a decimal integer so, you want to parse it. There are two ways:&#xA;&#xA;Imperative: wait for the Future to resolve, then parse into an i32.&#xA;Monadic: apply the parser “right now” getting a Futurei32 as a result.&#xA;&#xA;Both ways can also be used when instead of parsing you need something that is itself asynchronous, i.e. returns Futurei32 and not i32; in either case you’ll get a Futurei32 as the result.&#xA;&#xA;While imperative code is generally easier to follow monadic version is often leaner on resources. That’s why the modern async/await syntax blurs the distinction a bit: it looks like 1 but works more like 2, evidenced by the fact the result (of an async block or function) is a Future and not the computed value itself.&#xA;&#xA;Generalization&#xA;&#xA;So far I was only talking about Future specifically. But the approach can be generalized and, that generalization is what a monad is.&#xA;&#xA;In more concrete terms a monad M is a generic type MT which allows applying functions T -  U and T -  MU to itself. As there may not be a T inside at the time the result can’t be plain U so, it is MU in either case.&#xA;&#xA;There are many examples of monads. The textbook one is Option (aka Maybe). But while tremendously useful on its own its monadic nature is shadowed somewhat: sure one can do map or andthen on it but, one can do if let Some(x) { y += x; } just as well and, that’s not at all monadic. Except in Haskell where the very notion of monad originated, one can’t: while one can pattern-match one has to return something regardless of the match and, there is no imperative stuff like += in Haskell whatsoever so, just going the monadic way may very well be easier.&#xA;&#xA;Composition&#xA;&#xA;Another way to look at monads is in the parlance of monadic composition.&#xA;&#xA;Suppose you have two functions, f(A) -  B and g(B) -  C. You can compose them into a new function ftheng(A) -  C. However, if what you have is f(A) -  MB and g(B) -  MC regular composition doesn’t work as types don’t match. But monadic composition does!¹ The result is a function ftheng(A) -  MC which applies g to f’s result effectively even though it can’t do that directly.&#xA;&#xA;Outside of Haskell though composition often isn’t spelled out. But it is still there. Consider:&#xA;&#xA;fn download(url: &amp;str) -  Vecu8 {&#xA;&#x9;let data = fetch(url);&#xA;&#x9;let data = decrypt(data);&#xA;&#x9;let data = decompress(data);&#xA;&#x9;data&#xA;}&#xA;&#xA;It’s actually just a composition of 3 functions: fetch, decrypt, and decompress. But in many cases that’s not possible as-is. E.g. fetch is likely asynchronous. So the code would be more like this:&#xA;&#xA;async fn download(url: &amp;str) -  Vecu8 {&#xA;&#x9;let data = fetch(url).await;&#xA;&#x9;let data = decrypt(data).await; // maybe it’s hardware accelerated?&#xA;&#x9;let data = decompress(data).await;&#xA;&#x9;data&#xA;}&#xA;&#xA;And this is actually a monadic composition of the 3 functions. Indeed fetch being async doesn’t return a Vecu8 anymore but a FutureVec&lt;u8   instead while decrypt still takes a Vecu8 as an argument, yet they are essentially composed together.&#xA;&#xA;In the last example await is the key: it’s what facilitates the composition, and it is also specific to Future. But Future isn’t the only monad out there. The first example was overly simplistic: actual functions would return a Result and one’d need to handle that as well, like:&#xA;&#xA;fn download(url: &amp;str) -  io::ResultVec&lt;u8  {&#xA;&#x9;let data = fetch(url)?;&#xA;&#x9;let data = decrypt(data)?;&#xA;&#x9;let data = decompress(data)?;&#xA;&#x9;Ok(data)&#xA;}&#xA;&#xA;And this is again, a monadic composition of the 3 functions. The monad is io::Result this time. It has its own special syntax (shared for Result and Option), so short because it tends to be everywhere in Rust.&#xA;&#xA;¹ Provided that M is a monad of course.&#xA;&#xA;How this works&#xA;&#xA;There is no direct support of composition in the definition of monad. But it is actually pretty easy: if you have f(A) -  MB and g(B) -  MC you can just call f and apply g to the result.&#xA;&#xA;It actually works the other way as well: if you have an x: MA and need to apply f(A) -  MB to it using composition, you can wrap x as h(()) -  MA (returning x unconditionally), monadically compose h with f, and call the resulting (()) -  MB function to obtain the MB.&#xA;&#xA;Conclusion&#xA;&#xA;While directly working with monads may be a hassle they are really useful as building blocks, allowing to unify such distinct concepts as error handling, asynchronous programming, and more.&#xA;&#xA;[w/monad]: https://en.wikipedia.org/wiki/Monad(functional_programming)#Overview&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>Wikipedia <a href="https://en.wikipedia.org/wiki/Monad_(functional_programming)#Overview">describes</a> a monad in some Haskell syntax. Oh well. But actually, one doesn’t need to know Haskell to understand what a monad <em>is</em> and how it can be used.</p>

<h2 id="basics" id="basics">Basics</h2>

<p>Suppose you have a <code>Future&lt;String&gt;</code> but that string is actually a decimal integer so, you want to parse it. There are two ways:</p>
<ol><li>Imperative: wait for the <code>Future</code> to resolve, then parse into an <code>i32</code>.</li>
<li>Monadic: apply the parser “right now” getting a <code>Future&lt;i32&gt;</code> as a result.</li></ol>

<p>Both ways can also be used when instead of parsing you need something that is itself asynchronous, i.e. returns <code>Future&lt;i32&gt;</code> and not <code>i32</code>; in either case you’ll get a <code>Future&lt;i32&gt;</code> as the result.</p>

<p>While imperative code is generally easier to follow monadic version is often leaner on resources. That’s why the modern <code>async</code>/<code>await</code> syntax blurs the distinction a bit: it looks like 1 but works more like 2, evidenced by the fact the result (of an <code>async</code> block or function) is a <code>Future</code> and not the computed value itself.</p>

<h2 id="generalization" id="generalization">Generalization</h2>

<p>So far I was only talking about <code>Future</code> specifically. But the approach can be generalized and, that generalization is what a monad is.</p>

<p>In more concrete terms a monad <code>M</code> is a generic type <code>M&lt;T&gt;</code> which allows applying functions <code>T -&gt; U</code> and <code>T -&gt; M&lt;U&gt;</code> to itself. As there may not be a <code>T</code> inside at the time the result can’t be plain <code>U</code> so, it is <code>M&lt;U&gt;</code> in either case.</p>

<p>There are many examples of monads. The textbook one is <code>Option</code> (aka <code>Maybe</code>). But while tremendously useful on its own its monadic nature is shadowed somewhat: sure one can do <code>map</code> or <code>and_then</code> on it but, one can do <code>if let Some(x) { y += x; }</code> just as well and, that’s not at all monadic. Except in Haskell where the very notion of monad originated, one can’t: while one can pattern-match one has to return <em>something</em> regardless of the match and, there is no imperative stuff like <code>+=</code> in Haskell whatsoever so, just going the monadic way may very well be easier.</p>

<h2 id="composition" id="composition">Composition</h2>

<p>Another way to look at monads is in the parlance of <em>monadic composition</em>.</p>

<p>Suppose you have two functions, <code>f(A) -&gt; B</code> and <code>g(B) -&gt; C</code>. You can compose them into a new function <code>f_then_g(A) -&gt; C</code>. However, if what you have is <code>f(A) -&gt; M&lt;B&gt;</code> and <code>g(B) -&gt; M&lt;C&gt;</code> regular composition doesn’t work as types don’t match. But monadic composition does!¹ The result is a function <code>f_then_g(A) -&gt; M&lt;C&gt;</code> which applies <code>g</code> to <code>f</code>’s result effectively even though it can’t do that directly.</p>

<p>Outside of Haskell though composition often isn’t spelled out. But it is still there. Consider:</p>

<pre><code class="language-rust">fn download(url: &amp;str) -&gt; Vec&lt;u8&gt; {
	let data = fetch(url);
	let data = decrypt(data);
	let data = decompress(data);
	data
}
</code></pre>

<p>It’s actually just a composition of 3 functions: <code>fetch</code>, <code>decrypt</code>, and <code>decompress</code>. But in many cases that’s not possible as-is. E.g. <code>fetch</code> is likely asynchronous. So the code would be more like this:</p>

<pre><code class="language-rust">async fn download(url: &amp;str) -&gt; Vec&lt;u8&gt; {
	let data = fetch(url).await;
	let data = decrypt(data).await; // maybe it’s hardware accelerated?
	let data = decompress(data).await;
	data
}
</code></pre>

<p>And this is actually a monadic composition of the 3 functions. Indeed <code>fetch</code> being async doesn’t return a <code>Vec&lt;u8&gt;</code> anymore but a <code>Future&lt;Vec&lt;u8&gt;&gt;</code> instead while <code>decrypt</code> still takes a <code>Vec&lt;u8&gt;</code> as an argument, yet they are essentially composed together.</p>

<p>In the last example <code>await</code> is the key: it’s what facilitates the composition, and it is also specific to <code>Future</code>. But <code>Future</code> isn’t the only monad out there. The first example was overly simplistic: actual functions would return a <code>Result</code> and one’d need to handle that as well, like:</p>

<pre><code class="language-rust">fn download(url: &amp;str) -&gt; io::Result&lt;Vec&lt;u8&gt;&gt; {
	let data = fetch(url)?;
	let data = decrypt(data)?;
	let data = decompress(data)?;
	Ok(data)
}
</code></pre>

<p>And this is again, a monadic composition of the 3 functions. The monad is <code>io::Result</code> this time. It has its own special syntax (shared for <code>Result</code> and <code>Option</code>), so short because it tends to be <em>everywhere</em> in Rust.</p>

<p>¹ Provided that <code>M</code> is a monad of course.</p>

<h3 id="how-this-works" id="how-this-works">How this works</h3>

<p>There is no direct support of composition in the definition of monad. But it is actually pretty easy: if you have <code>f(A) -&gt; M&lt;B&gt;</code> and <code>g(B) -&gt; M&lt;C&gt;</code> you can just <em>call</em> <code>f</code> and apply <code>g</code> to the result.</p>

<p>It actually works the other way as well: if you have an <code>x: M&lt;A&gt;</code> and need to apply <code>f(A) -&gt; M&lt;B&gt;</code> to it using composition, you can wrap <code>x</code> as <code>h(()) -&gt; M&lt;A&gt;</code> (returning <code>x</code> unconditionally), monadically compose <code>h</code> with <code>f</code>, and call the resulting <code>(()) -&gt; M&lt;B&gt;</code> function to obtain the <code>M&lt;B&gt;</code>.</p>

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

<p>While directly working with monads may be a hassle they are really useful as building blocks, allowing to unify such distinct concepts as error handling, asynchronous programming, and more.</p>
]]></content:encoded>
      <guid>https://blog.noteuclid.ru/another-view-on-a-monad</guid>
      <pubDate>Sun, 13 Oct 2024 13:43:43 +0000</pubDate>
    </item>
    <item>
      <title>I’m fascinated by Rust metaprogramming!</title>
      <link>https://blog.noteuclid.ru/im-fascinated-by-rust-metaprogramming</link>
      <description>&lt;![CDATA[It has trait-based generics, which are safer and much more convenient than nobrC++/nobr templates. It also has rule-based macros which are safer and much more powerful than those of nobrC/C++/nobr. And as if that wasn’t enough it also has procedural macros! Those are comparable to nobrC++/nobr templates in power (quite literally: both are Turing-complete) but this time, it’s not some pattern matching but a full-fledged program that can directly do arbitrary transformations — except not exactly arbitrary, safety checks are still there so it won’t end up with a missing closing bracket or such. And for those with special needs, pretty much all of that machinery is also available “offline”, essentially as a code generation framework.&#xA;&#xA;Now, of course there are rough edges. Traits, while incredibly flexible have their limits. And macros only operate syntactically, not semantically. There appears to be no good way to do complex transformations at semantic level. While trait specialization can help, not only it’s not a solution for everyone it’s also a huge can of worms on its very own. It’s actually one of reasons C++ templates are so hard to work with: anything can be specialized, anywhere. Now, Rust does put a stop on the latter part: as I understand it specializations are still governed by the orphan rule so, there are only so many places for each. The former part is also tamed, specialization is strictly opt-in as proposed. But I’m still somewhat uneasy.&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>It has trait-based generics, which are safer and much more convenient than C++ templates. It also has rule-based macros which are safer and much more powerful than those of C/C++. And as if that wasn’t enough it also has procedural macros! Those are comparable to C++ templates in power (quite literally: both are Turing-complete) but this time, it’s not some pattern matching but a full-fledged program that can directly do arbitrary transformations — except not exactly arbitrary, safety checks are still there so it won’t end up with a missing closing bracket or such. And for those with special needs, pretty much all of that machinery is <em>also</em> available “offline”, essentially as a code generation framework.</p>

<p>Now, of course there are rough edges. Traits, while incredibly flexible have their limits. And macros only operate syntactically, not semantically. There appears to be no good way to do complex transformations at semantic level. While <a href="https://rust-lang.github.io/rfcs/1210-impl-specialization.html">trait specialization</a> can help, not only it’s not a solution for everyone it’s also a huge can of worms on its very own. It’s actually one of reasons C++ templates are so hard to work with: <em>anything</em> can be specialized, anywhere. Now, Rust does put a stop on the latter part: as I understand it specializations are still governed by the orphan rule so, there are only so many places for each. The former part is also tamed, specialization is strictly opt-in as proposed. But I’m still somewhat uneasy.</p>
]]></content:encoded>
      <guid>https://blog.noteuclid.ru/im-fascinated-by-rust-metaprogramming</guid>
      <pubDate>Sun, 06 Oct 2024 19:14:16 +0000</pubDate>
    </item>
  </channel>
</rss>