<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title></title>
    <link rel="self" type="application/atom+xml" href="/atom.xml"/>
    <link rel="alternate" type="text/html" href="/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-08-21T00:00:00+00:00</updated>
    <id>/atom.xml</id>
    <entry xml:lang="en">
        <title>Morcilla de Verano Recipe (Eggplant Dip)</title>
        <published>2025-08-21T00:00:00+00:00</published>
        <updated>2025-08-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/w/4-morcilla-de-verano/"/>
        <id>/w/4-morcilla-de-verano/</id>
        
        <content type="html" xml:base="/w/4-morcilla-de-verano/">&lt;h1 id=&quot;morcilla-de-verano&quot;&gt;Morcilla de Verano&lt;&#x2F;h1&gt;
&lt;p&gt;The name of this dish from the Murcia region of Spain translates to &quot;summer
morcilla&quot;, named after its resemblance to the filling of a type of blood sausage called
morcilla. In spite of its name, this is a meat-free recipe, made by stewing down eggplant
into a deliciously savory dip with a soft spreadable texture.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;asset&#x2F;morcilladeverano.jpg&quot; alt=&quot;morcilla de verano&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;ingredients&quot;&gt;Ingredients&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;olive oil&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;1 onion&lt;&#x2F;strong&gt; (chopped small)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;2 medium eggplants&lt;&#x2F;strong&gt; (cubed)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;2 tbsp pine nuts&lt;&#x2F;strong&gt; (since they&#x27;re expensive, can sub for chopped walnuts or other nuts)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;~100ml white wine&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;salt, black pepper, oregano&lt;&#x2F;strong&gt; (optionally, to taste: cinnamon, paprika, maybe cumin)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;recipe&quot;&gt;Recipe&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;In a pan, &lt;strong&gt;toast the pine nuts&lt;&#x2F;strong&gt; until fragrant. Reserve.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Heat up olive oil&lt;&#x2F;strong&gt; in a pan and add the &lt;strong&gt;onion&lt;&#x2F;strong&gt;, &lt;strong&gt;sautée&lt;&#x2F;strong&gt; over medium-low (10~15m).&lt;&#x2F;li&gt;
&lt;li&gt;Meanwhile, &lt;strong&gt;precook&lt;&#x2F;strong&gt; the cubed &lt;strong&gt;eggplant&lt;&#x2F;strong&gt; by microwaving it for a few minutes until soft.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Add the eggplant and pine nuts to the pan&lt;&#x2F;strong&gt;, &lt;strong&gt;season&lt;&#x2F;strong&gt; with salt, oregano, black pepper and &lt;strong&gt;deglaze&lt;&#x2F;strong&gt; with white wine.&lt;&#x2F;li&gt;
&lt;li&gt;Once alcohol has evaporated, cover and &lt;strong&gt;cook on low&lt;&#x2F;strong&gt; for ~15-30m, until you like the texture, the longer you cook it, the more it will break down and become jammy.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Taste and adjust seasoning&lt;&#x2F;strong&gt; to taste (can add more oregano or spices at this point).&lt;&#x2F;li&gt;
&lt;li&gt;Optionally drizzle with more olive oil and garnish with more nuts. &lt;strong&gt;Serve with bread.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A little XOR trick to micro-optimize some integer data structures</title>
        <published>2025-08-13T00:00:00+00:00</published>
        <updated>2025-08-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/w/3-integer-null-value-trick/"/>
        <id>/w/3-integer-null-value-trick/</id>
        
        <content type="html" xml:base="/w/3-integer-null-value-trick/">&lt;h1 id=&quot;motivating-example&quot;&gt;Motivating example&lt;&#x2F;h1&gt;
&lt;p&gt;Say you want to write an integer hash-set implementation in C. You might start like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;* a hash-set implemented with a flat open-addressed array with linear probing *&#x2F;
struct set {
    int *entries;
    size_t N;
};

void set_init(struct set *set, size_t initial) {
    &#x2F;* make sure N is a power of 2, with enough capacity to minimize collisions *&#x2F;
    for (set-&amp;gt;N = 8; set-&amp;gt;N &amp;lt; initial * 2; set-&amp;gt;N *= 2) ;
    set-&amp;gt;entries = calloc(set-&amp;gt;N, sizeof *set-&amp;gt;entries);
}

unsigned inthash(unsigned x) { ... }

bool set_contains(struct set *set, int x) {
    int h = inthash(x) &amp;amp; (set-&amp;gt;N - 1), i = h;
    do {
 ----&amp;gt;  if (entry i is empty)  &amp;lt;----
            return 0;
        else if (set-&amp;gt;entries[i] == x)
            return 1; 
        i = (i + 1) &amp;amp; (set-&amp;gt;N - 1);
    } while (i != h);
    &#x2F;* set is full, looped around *&#x2F;
    return 0;
}

void _set_grow(struct set *set) { ... } &#x2F;&#x2F; omitted for brevity

void set_put(struct set *set, int x) {
    int h = inthash(x) &amp;amp; (set-&amp;gt;N - 1), i = h;
    do {
 ----&amp;gt;  if (entry i is empty)  &amp;lt;----
            set-&amp;gt;entries[i] = x;
        else if (set-&amp;gt;entries[i] == x)
            return; &#x2F;* nothing to do *&#x2F;
        i = (i + 1) &amp;amp; (set-&amp;gt;N - 1);
    } while (i != h);
    &#x2F;* full set, looped around *&#x2F;
    _set_grow(set);
    set_put(set, x);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The problem is, if every array item can hold a key, how do you mark an entry as
empty?  There&#x27;s two ways you can go about this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Out-of-band signaling, so you keep a separate array &lt;code&gt;bool *hasentry&lt;&#x2F;code&gt; also of size N,
which for every index stores whether the corresponding entry is used or
empty. Initialized to zeroes and updated when new entries are added in
&lt;code&gt;set_put&lt;&#x2F;code&gt;.  Instead of 1 byte per entry with a bool array, you can be more
efficient using a bit array.  This is the generalized approach that is useful
if the values the set is storing are truly arbitrary.&lt;&#x2F;li&gt;
&lt;li&gt;In-band signaling, meaning you reserve a special sentinel value to
represent an empty entry. This places a restriction in the values your set can hold,
but very often this is fine. This technique is for this use case.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So the easy case is if your sentinel value is zero, then it&#x27;s a matter of changing&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;       if (entry i is empty)       
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;into&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;       if (!set-&amp;gt;entries[i])
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and adding a check like&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void set_put(struct set *set, int x) {
    assert(x != 0 &amp;amp;&amp;amp; &amp;quot;illegal value&amp;quot;);
    ...
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that in &lt;code&gt;set_init&lt;&#x2F;code&gt; (and &lt;code&gt;_set_grow&lt;&#x2F;code&gt;), the use of &lt;code&gt;calloc&lt;&#x2F;code&gt; already zeroes
the whole array, marking it initially as all empty, exactly as we want.&lt;&#x2F;p&gt;
&lt;p&gt;But in practice, very often the integers you might wanna store in the set are
not arbitrary (so you can use the sentinel technique), but zero is a value you
would like to be able to store, thus not a good sentinel. In this case you have
to fallback to a non-zero sentinel, for example&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#define _SET_EMPTY INT_MIN

void set_init(struct set *set, size_t initial) {
    ...
    set-&amp;gt;entries = malloc(set-&amp;gt;N);
    for (int i = 0; i &amp;lt; set-&amp;gt;N; ++i) set-&amp;gt;entries[i] = _SET_EMPTY;
}

bool set_contains(struct set *set, int x) {
  ...
        if (set-&amp;gt;entries[i] == _SET_EMPTY)
            return 0;
  ...
}

void _set_grow(struct set *set) {
    int *old_entries = set-&amp;gt;entries;
    size_t old_N = set-&amp;gt;N;
    set-&amp;gt;entries = malloc(set-&amp;gt;N *= 2);
    for (int i = 0; i &amp;lt; set-&amp;gt;N; ++i) set-&amp;gt;entries[i] = _SET_EMPTY;
    ...
}

void set_put(struct set *set, int x) {
    assert(x != _SET_EMPTY &amp;amp;&amp;amp; &amp;quot;illegal value&amp;quot;);
  ...
        if (set-&amp;gt;entries[i] == _SET_EMPTY)
            set-&amp;gt;entries[i] = x;
  ...
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This works fine, but we lose the nicety of &lt;code&gt;calloc&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;My trick combines the benefits of the zero-sentinel (initialization for free)
and an arbitrary sentinel by simply storing the value XORed with the sentinel.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We keep the &lt;code&gt;calloc&lt;&#x2F;code&gt;s for zero initialization&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;if (entry i is empty)&lt;&#x2F;code&gt; becomes &lt;code&gt;if (!set-&amp;gt;entries[i])&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;We XOR the value with the sentinel before storing it and when getting it
out of an entry:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Thus:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;bool set_contains(struct set *set, int x) {
    int h = inthash(x) &amp;amp; (set-&amp;gt;N - 1), i = h;
    do {
        if (!set-&amp;gt;entries[i])
            return 0;
        else if ((set-&amp;gt;entries[i] ^ _SET_EMPTY) == x)  &#x2F;&#x2F; &amp;lt;--------
            return 1; 
        i = (i + 1) &amp;amp; (set-&amp;gt;N - 1);
    } while (i != h);
    &#x2F;* set is full, looped around *&#x2F;
    return 0;
}

void set_put(struct set *set, int x) {
    int h = inthash(x) &amp;amp; (set-&amp;gt;N - 1), i = h;
    assert(x != _SET_EMPTY &amp;amp;&amp;amp; &amp;quot;illegal value&amp;quot;);
    do {
        if (!set-&amp;gt;entries[i])
            set-&amp;gt;entries[i] = x ^ _SET_EMPTY;  &#x2F;&#x2F; &amp;lt;--------
        else if ((set-&amp;gt;entries[i] ^ _SET_EMPTY) == x) &#x2F;&#x2F; &amp;lt;-------
            return; &#x2F;* nothing to do *&#x2F;
        i = (i + 1) &amp;amp; (set-&amp;gt;N - 1);
    } while (i != h);
    &#x2F;* full set, looped around *&#x2F;
    _set_grow(set);
    set_put(set, x);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This works because of the mathematical properties of bitwise XOR:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;x^y == 0&lt;&#x2F;code&gt; if and only if &lt;code&gt;x == y&lt;&#x2F;code&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;x^y = z&lt;&#x2F;code&gt; then &lt;code&gt;z^y = x&lt;&#x2F;code&gt; and &lt;code&gt;x^z = y&lt;&#x2F;code&gt; (XOR is reversible)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In situations where &lt;code&gt;calloc&lt;&#x2F;code&gt; is more efficient than &lt;code&gt;malloc&lt;&#x2F;code&gt; + manual
initialization, this is a potentially more efficient solution, especially if
the size of your set is unpredictable and could grow multiple times.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>No-Knead Bread</title>
        <published>2024-12-17T00:00:00+00:00</published>
        <updated>2024-12-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/w/2-bread/"/>
        <id>/w/2-bread/</id>
        
        <content type="html" xml:base="/w/2-bread/">&lt;h1 id=&quot;no-knead-bread&quot;&gt;No-Knead Bread&lt;&#x2F;h1&gt;
&lt;p&gt;I grew up eating good bread fresh from an artisan bakery every day. Over the
years I&#x27;ve experimented with making and baking my own bread with recipes from
the internet but most of it felt flat and it was only this year that I figured
out What Worked to make delicious bread that matched that from the bakery.
&lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.recipetineats.com&#x2F;easy-yeast-bread-recipe-no-knead&#x2F;&quot;&gt;This recipe&lt;&#x2F;a&gt;,
itself an adaptation of a NYTimes recipe, is what I&#x27;ve been using as a
reference. Refrigerating the dough for a day is really key to develop that
great flavour, no need to maintain a sourdough starter. The dough itself comes
together without much fuss, and doesn&#x27;t really require any kneading. I
typically replace some of the flour with whole-wheat or spelt flour, for more
depth of flavor, nutrition and color.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;ingredients&quot;&gt;Ingredients&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;450g flour&lt;&#x2F;strong&gt;
&lt;ul&gt;
&lt;li&gt;use bread flour if you have it. mix with whole grain wheat&#x2F;spelt flour if
you want, for example 300g bread flour + 150g spelt flour&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;2tsp instant dry yeast&lt;&#x2F;strong&gt;, about 5~6g. a bit less than a 7g packet. or just use
the whole packet this is not too fussy&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;1.5tsp table salt&lt;&#x2F;strong&gt;, or between 1.5% - 2% relative to flour in grams. the
exact volume measurement depends on the grain size of your salt and how salty
you like your bread (personal preference). linked recipe suggests 2tsp for
coarser, kosher salt&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;375ml warm water&lt;&#x2F;strong&gt;, around &lt;strong&gt;80% hydration&lt;&#x2F;strong&gt; in bakers&#x27; percentage. add a little
more if using whole grain flour as it absorbs more water, I go by feel. you
want a wet and sloppy dough&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;recipe&quot;&gt;Recipe&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;mix&lt;&#x2F;strong&gt; &lt;code&gt;flour&lt;&#x2F;code&gt;, &lt;code&gt;yeast&lt;&#x2F;code&gt;, and &lt;code&gt;salt&lt;&#x2F;code&gt; in a large mixing bowl&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;add&lt;&#x2F;strong&gt; &lt;code&gt;water&lt;&#x2F;code&gt; and mix until wet dough forms&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;cover and let rise&lt;&#x2F;strong&gt; at room temperature for about &lt;code&gt;2 to 3 hours&lt;&#x2F;code&gt;, it
should double in size&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;refrigerate&lt;&#x2F;strong&gt;, at least overnight, a whole day is better, possibly
longer. optionally, every couple hours take dough out to do a couple folds
over itself and put it back. this helps develop gluten&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;take dough out&lt;&#x2F;strong&gt; of the fridge, flip it onto parchment paper dusted with
flour, let it come to room temperature and proof, about 45min. &lt;strong&gt;preheat
oven&lt;&#x2F;strong&gt; to &lt;code&gt;200C&lt;&#x2F;code&gt; in the meantime&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;transfer&lt;&#x2F;strong&gt; parchment paper with dough onto oven tray, spray with water to
create a steamy environment in the oven and &lt;strong&gt;bake&lt;&#x2F;strong&gt; until golden brown
(~45m)&lt;&#x2F;li&gt;
&lt;li&gt;remove and &lt;strong&gt;let cool&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;asset&#x2F;dough.jpg&quot; alt=&quot;dough post rise&quot; title=&quot;dough post initial rise&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;asset&#x2F;bread1.jpg&quot; alt=&quot;bread in the oven&quot; title=&quot;bread in the oven&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;asset&#x2F;bread2.jpg&quot; alt=&quot;bread after baking&quot; title=&quot;bread after baking&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How I make my Oatmeal</title>
        <published>2024-09-24T00:00:00+00:00</published>
        <updated>2024-09-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/w/1-oatmeal/"/>
        <id>/w/1-oatmeal/</id>
        
        <content type="html" xml:base="/w/1-oatmeal/">&lt;p&gt;Over the past few months, I&#x27;ve really come to enjoy oatmeal. I&#x27;m from a country
where it&#x27;s not a common food at all and I never knew of it growing up, but now
it&#x27;s become my breakfast of choice most days, and I have experimented with many
variations of it which I wanted to share:&lt;&#x2F;p&gt;
&lt;h1 id=&quot;sweet-variations&quot;&gt;Sweet Variations&lt;&#x2F;h1&gt;
&lt;p&gt;This is how I like to have oatmeal most of the time, with some sweetener and
maybe flavorings and topped with fruit, nuts, and often nut butter. My go-to
lately is with vanilla-flavored soy protein powder, a sliced banana, peanut
butter, nuts and dark chocolate. I usually add raisins and a sprinkle of
cinnamon too.&lt;&#x2F;p&gt;
&lt;p&gt;I cook my oats on the stove-top at a low simmer for 10 to 15 minutes so they
soften and absorb a lot of water. As for measurements, I do ½ cup of rolled
oats (though lately I&#x27;ve been doing ¼ cup oats + ~10g oat bran) and ½ tsp chia
seeds, cooked in initially ~1 cup of liquid (water, plant milk, or a
combination) with a pinch of salt. I add more plant milk or yogurt as it
thickens because I like it on the looser end. I mix in the protein powder at
the end of cooking if I&#x27;m adding it, or I&#x27;ll add some sweetener to taste (maple
syrup&#x2F;honey&#x2F;stevia&#x2F;a combination).&lt;&#x2F;p&gt;
&lt;p&gt;I prefer old fashioned rolled oats for
texture, as opposed to the quick cooking kind.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;asset&#x2F;oat1.jpg&quot; alt=&quot;picture of oatmeal&quot; title=&quot;with banana, nuts, pb, dark chocolate&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;savory-variations&quot;&gt;Savory Variations&lt;&#x2F;h1&gt;
&lt;p&gt;Some days I crave something savory in the morning instead, but it&#x27;s also a
quick &amp;amp; comforting option for dinner. Apparently people in the English-speaking
internet find savory oats weird, but I didn&#x27;t grow up eating oatmeal of any
sort, so I don&#x27;t have that specific association with sweet oats that seems
common. To me it&#x27;s just another cereal grain like rice, so it makes sense for
savory dishes too.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, for savory variations I like creamy and soft oats, similar to
congee&#x2F;rice porridge. Seasoned with salt and some combination of boullion
powder, oyster sauce, soy sauce, miso paste... Simple spices like black pepper,
maybe turmeric, cumin, smoked paprika.. I love adding spinach and mushrooms,
and I often start by sautéeing onions and&#x2F;or garlic for an aromatic base before
adding the rest of the ingredients. Using unsweetened plant milk in addition to
water is nice too.  Sesame seeds, runny egg, sriracha, nattō, are some great
toppings in my rotation.&lt;&#x2F;p&gt;
&lt;p&gt;Other interesting variations I&#x27;ve tried:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;risotto-style with butter, red wine,
mushrooms and parmesan&lt;&#x2F;li&gt;
&lt;li&gt;tomatoey oats (cooked with tomato puree or tomato
sauce), which pair especially well with egg.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Unlike sweet oatmeal,
my preference with savory oats is to use the quick cooking kind for the softer
consistency.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;asset&#x2F;oat2.jpg&quot; alt=&quot;picture of oatmeal&quot; title=&quot;with mushroom, greens, natto, egg, furikake&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Starting a food diary&#x2F;blog</title>
        <published>2024-09-24T00:00:00+00:00</published>
        <updated>2024-09-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/w/food-blog/"/>
        <id>/w/food-blog/</id>
        
        <content type="html" xml:base="/w/food-blog/">&lt;p&gt;I&#x27;ve wanted to make use of some of my spare time to do a bit of writing, and
food &amp;amp; cooking is something I find interesting and spend time thinking about,
plus I like to experiment with cooking as a creative outlet. So writing about
it seems like a natural choice, and I get to give this site some more use that
way.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>C99 doesn&#x27;t need function bodies, or &#x27;VLAs are Turing complete&#x27;</title>
        <published>2022-02-19T00:00:00+00:00</published>
        <updated>2022-02-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/w/c99-vla-tricks/"/>
        <id>/w/c99-vla-tricks/</id>
        
        <content type="html" xml:base="/w/c99-vla-tricks/">&lt;h1 id=&quot;preface&quot;&gt;Preface&lt;&#x2F;h1&gt;
&lt;p&gt;The 1999 revision to the C programming language brought several interesting
changes and additions to the standard. Among those are variable length arrays,
or VLAs for short, which allow array types to have lengths that are determined
at runtime. These can show up in different contexts, but for the purposes of
this post we will be looking at VLAs as parameters to functions. For example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void f(int n, float v[n]);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since array parameters decay to their corresponding pointer type, that
declaration is functionally equivalent, and compatible (&lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;port70.net&#x2F;~nsz&#x2F;c&#x2F;c99&#x2F;n1256.html#6.7.5.3p7&quot;&gt;6.7.5.3p7&lt;&#x2F;a&gt;) to the
following:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void f(int n, float *v);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The length of &lt;code&gt;v&lt;&#x2F;code&gt; in the first declaration is given by the value of a previous
parameter of the function, which can only be known at runtime. However, in a
function prototype (i.e. not a function definition) like the above, the length
of a VLA parameter is never computed and essentially ignored (&lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;port70.net&#x2F;~nsz&#x2F;c&#x2F;c99&#x2F;n1256.html#6.7.5.2p5&quot;&gt;6.7.5.2p5&lt;&#x2F;a&gt;).
But in a function definition, the length is evaluated and must be greater than
zero. In practice this is rather useless because the sizeof operator doesn&#x27;t
work as one might expect it to with array parameters (&lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;port70.net&#x2F;~nsz&#x2F;c&#x2F;c99&#x2F;n1256.html#note88&quot;&gt;6.5.3.4-note88&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void f(int n, float param[n]) {
    float local[n];
    int a = sizeof local,
        b = sizeof param;

    printf(&amp;quot;n = %d\n&amp;quot;, n);
    printf(&amp;quot;sizeof local = %d\n&amp;quot;, a); &#x2F;&#x2F; this will be n * sizeof(float)
    printf(&amp;quot;sizeof param = %d\n&amp;quot;, b); &#x2F;&#x2F; but this will be sizeof(float *)
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In other words, using sizeof with a VLA will evaluate the runtime-known length
and calculate the array size based on that, except when that VLA is a function
parameter, then, for whatever reason, it is the size of the corresponding
pointer type (in this example, &lt;code&gt;sizeof local === n * sizeof(float)&lt;&#x2F;code&gt; but &lt;code&gt;sizeof param == sizeof(float *)&lt;&#x2F;code&gt;). The length of a VLA parameter may be used when e.g.
computing indices when accessing multi-dimensional variable length arrays.&lt;&#x2F;p&gt;
&lt;p&gt;Alas, the standard mandates that the variable array length be computed when
the function is called. Of course, the expression in between the square
brackets is not limited to simple expressions like &lt;code&gt;n&lt;&#x2F;code&gt;, so one can write
something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void f(int a, int b, int m[(a + b) &#x2F; 2]) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;or&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void f(int x, int b[abs(x)]) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;or even&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void f(int v[getchar()]) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;disembodiment&quot;&gt;Disembodiment&lt;&#x2F;h1&gt;
&lt;p&gt;The following program should give you an idea of the kind of constructs
that these rules allow for (&lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;godbolt.org&#x2F;z&#x2F;f3chYMvh5&quot;&gt;try it on compiler explorer&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;int main(int argc, char *argv[printf(&amp;quot;Hello&amp;quot;)])
{
    printf(&amp;quot; world!\n&amp;quot;);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The length expression of the VLA is evaluated before any of the statements in
&lt;code&gt;main&lt;&#x2F;code&gt;. I couldn&#x27;t find anywhere in the standard saying whether this evaluation
order is well-defined but it is what clang and gcc do, and luckily, it does not
matter for the sake of this article, as we will see shortly.&lt;&#x2F;p&gt;
&lt;p&gt;Let us refer to the subset of C99 where function bodies must be empty as
&lt;em&gt;disembodied C&lt;&#x2F;em&gt;. You might naturally ask yourself what things can be
accomplished in this subset (though you can probably guess the answer from the
title of this page). In other words, what can you do in C if you are limited to
just evaluating expressions and no statements?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Using the comma operator, we can sequence arbitrarily many expressions for
their side effects, so&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void f() {
    printf(&amp;quot;Press enter to confirm: &amp;quot;);
    getchar();
    printf(&amp;quot;thanks.\n&amp;quot;);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;becomes&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void f(char _[(
    printf(&amp;quot;Press enter to confirm: &amp;quot;),
    getchar(),
    printf(&amp;quot;thanks.\n&amp;quot;),
    1
)]) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In a comma expression, the operands are evaluated left-to-right and the value
of the last operand is the resulting value of the whole expression. The &lt;code&gt;1&lt;&#x2F;code&gt;
at the end ensures that the evaluated array length is &amp;gt;0 (to avoid UB).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Functions in disembodied C are going to need a dummy parameter where the VLA
length expression evaluation can take place. For consistency, we will denote
it as &lt;code&gt;char _[...]&lt;&#x2F;code&gt; and give it the value &lt;code&gt;&quot;&quot;&lt;&#x2F;code&gt; (the empty string) when calling
said functions (note that the value we give it doesn&#x27;t actually matter, though
its size should be at least as big as the computed VLA size to avoid UB).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If-else statements can be replaced with ternary conditional expressions, such that&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void f(int n) {
    if (n &amp;lt; 0)
        printf(&amp;quot;negative!&amp;quot;);
    else if (n &amp;gt; 0)
        printf(&amp;quot;positive!&amp;quot;);
    else
        printf(&amp;quot;zero!&amp;quot;);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;becomes&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void f(int n, char _[(
    (n &amp;lt; 0) ?
        printf(&amp;quot;negative!&amp;quot;)
    : (n &amp;gt; 0) ?
        printf(&amp;quot;positive!&amp;quot;)
    :
        printf(&amp;quot;zero!&amp;quot;)
    , 1
)]) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Remember that the VLA length expression can access previous function arguments,
so parameter passing is essentially unchanged.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We cannot return values, but we can use out parameters by taking advantage of
the fact that assignments are expressions in C, so instead of&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;int imax(int a, int b) {
    return a &amp;gt; b ? a : b;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;we can write&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void imax(int *out, int a, int b, char _[
    (*out = a &amp;gt; b ? a : b),
    1
]) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We cannot define local variables inside of expressions, but we can just add
extra function parameters to use as temporaries, rewriting&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;void fswapf(float *a, float *b) {
    float tmp = *a;
    *a = *b;
    *b = tmp;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;as&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;static void fswapf_aux(float *a, float *b, float tmp, char _[(
    tmp = *a,
    *a = *b,
    *b = tmp,
    1
)]) {}

void fswapf(float *a, float *b, char _[(
    fswapf_aux(a, b, 0, &amp;quot;&amp;quot;), 1
)]) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Alternatively, if re-entrancy and thread-safety are disregarded, we could
just use global (static) variables.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;What about loops? Clearly we cannot use &lt;code&gt;while&lt;&#x2F;code&gt; or &lt;code&gt;for&lt;&#x2F;code&gt; inside expressions.
Thankfully, they are unnecessary thanks to recursion. For example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;float sum(float *v, size_t n) {
    float sum = 0.0f;
    for (size_t i = 0; i &amp;lt; n; ++i)
        sum += v[i];
    return sum;
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;can be expressed as&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&#x2F;* the forward declaration is necessary *&#x2F;
static void sum_aux(float *out, float *v, size_t n, char *);
static void sum_aux(float *out, float *v, size_t n, char _[(
    (n &amp;gt; 0) ? (
        *out += *v,
        sum_aux(out, v + 1, n - 1, &amp;quot;&amp;quot;),
        1
    ) : 1
)]) {}

void sum(float *out, float *v, size_t n, char _[(
    *out = 0.0f,
    sum_aux(out, v, n, &amp;quot;&amp;quot;),
    1
)]) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In fact, any imperative-style loop can be turned into an equivalent recursive
loop (as any functional programmer will be happy to demonstrate), though since
C lacks closures or any form of anonymous functions, it can get quite unwieldy
(I hope you like auxiliary functions).&lt;&#x2F;p&gt;
&lt;p&gt;The astute reader might point out that these two versions of &lt;code&gt;sum&lt;&#x2F;code&gt; are not
equivalent because the recursive definition may cause a stack overflow for
large enough values of &lt;code&gt;n&lt;&#x2F;code&gt;. This is unfortunately true, and the major hurdle
for the practicality of disembodied C, but does not preclude Turing
completeness (an ideal &lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Turing_machine&quot;&gt;Turing machine&lt;&#x2F;a&gt; has infinite memory at its
disposal). Luckily, modern compilers are smart, and if we write our functions
carefully to be &lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tail_call&quot;&gt;tail recursive&lt;&#x2F;a&gt;, they will often be able to perform tail
call elimination, removing the risk of a stack overflow. For the above
example, both gcc and clang are able to optimize the tail call (&lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;godbolt.org&#x2F;z&#x2F;b1aG78os5&quot;&gt;see on
compiler explorer&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Although not relevant to standard C99, in case you had the idea of using &lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gcc.gnu.org&#x2F;onlinedocs&#x2F;gcc&#x2F;Statement-Exprs.html&quot;&gt;gcc
statement expressions&lt;&#x2F;a&gt; to bypass these limitations, the compiler will stop
you right on your tracks since it doesn&#x27;t allow those outside of function
bodies.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;limitations&quot;&gt;Limitations&lt;&#x2F;h1&gt;
&lt;p&gt;After all of that, it seems that basically anything can be done in disembodied
C, so, is there something that &lt;em&gt;can&#x27;t&lt;&#x2F;em&gt; be expressed in this C99 subset?&lt;&#x2F;p&gt;
&lt;p&gt;With the rules that we&#x27;ve laid down so far, yes. In particular:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It is not possible in the general case to use APIs that require callbacks.
For example, look at the standard &lt;code&gt;qsort&lt;&#x2F;code&gt; function:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt; void qsort(void *base, size_t nmemb, size_t size,
            int (*compar)(const void *, const void *));
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;compar&lt;&#x2F;code&gt; parameter is a pointer to a function that should return the
result of comparing two values in the given array. Since its parameters are
void pointers, we can&#x27;t have the VLA argument we need to perform computations
(arrays of &lt;code&gt;void&lt;&#x2F;code&gt; are not valid C), and we also cannot provide an &lt;code&gt;int&lt;&#x2F;code&gt;
return value. Thus there is no way (that I know of) to use this function in
standards-compliant disembodied C.&lt;&#x2F;p&gt;
&lt;p&gt;This is not a dealbreaker since we could just reimplement &lt;code&gt;qsort&lt;&#x2F;code&gt; ;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We cannot access the program arguments. The entry point of a program in
disembodied C looks like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;int main(int argc, char *argv[ &#x2F;* code here ... *&#x2F; ]) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the VLA length expression for &lt;code&gt;argv&lt;&#x2F;code&gt;, &lt;code&gt;argc&lt;&#x2F;code&gt; is in scope, but &lt;code&gt;argv&lt;&#x2F;code&gt; is
not.&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately there is a way to work around this: we can use the common
extension where &lt;code&gt;main&lt;&#x2F;code&gt; can take a third argument which is a pointer to the
environment. According to the standard (&lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;port70.net&#x2F;~nsz&#x2F;c&#x2F;c99&#x2F;n1256.html#J.5.1&quot;&gt;J.5.1&lt;&#x2F;a&gt;), this is implemented in
hosted environments. In practice, POSIX environments and Microsoft both
support it. Then, our entry point looks like this instead:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;int main(int argc, char **argv, char *envp[&#x2F;* ... *&#x2F;]) {}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now &lt;code&gt;argv&lt;&#x2F;code&gt; is in scope within the &lt;code&gt;envp&lt;&#x2F;code&gt; array length expression.&lt;&#x2F;p&gt;
&lt;p&gt;Side note: even though we can&#x27;t &lt;code&gt;return&lt;&#x2F;code&gt;, &lt;code&gt;main&lt;&#x2F;code&gt; is the exception to the rule
that reaching the closing &lt;code&gt;}&lt;&#x2F;code&gt; of a function returning non-void is verboten,
and is equivalent to returning zero (&lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;port70.net&#x2F;~nsz&#x2F;c&#x2F;c99&#x2F;n1256.html#5.1.2.2.3&quot;&gt;5.1.2.2.3&lt;&#x2F;a&gt;). If we need to terminate
with an exit code other than zero, we can use &lt;code&gt;exit()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;final-words&quot;&gt;Final Words&lt;&#x2F;h1&gt;
&lt;p&gt;It seems that with enough effort anything can be done with these peculiar
restrictions. As an example, I wrote implementations of the &lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~lsof&#x2F;x&#x2F;tree&#x2F;main&#x2F;item&#x2F;vla&#x2F;md5sum.c&quot;&gt;MD5&lt;&#x2F;a&gt; and &lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~lsof&#x2F;x&#x2F;tree&#x2F;main&#x2F;item&#x2F;vla&#x2F;sha256sum.c&quot;&gt;SHA256&lt;&#x2F;a&gt;
hash functions as well as &lt;a class=&quot;external_link&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~lsof&#x2F;x&#x2F;tree&#x2F;main&#x2F;item&#x2F;vla&#x2F;life.c&quot;&gt;Conway&#x27;s Game of Life using SDL for graphics&lt;&#x2F;a&gt;.
I was also working on a more interesting and &quot;useful&quot; program but I kind of
lost motivation halfway through. I&#x27;ll update this article if I ever come back
to finish that.&lt;&#x2F;p&gt;
&lt;p&gt;In case it wasn&#x27;t clear enough, there is zero practical reason to ever do any
of this. I hope you&#x27;ll agree it&#x27;s a fun party trick though :).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>test post</title>
        <published>2022-02-02T00:00:00+00:00</published>
        <updated>2022-02-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/w/first/"/>
        <id>/w/first/</id>
        
        <content type="html" xml:base="/w/first/">&lt;h1 id=&quot;test&quot;&gt;test&lt;&#x2F;h1&gt;
&lt;p&gt;lorem ipsum dolor sit amet&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;u16 rng(u16 s){
s^=s&amp;lt;&amp;lt;8,s=(s&amp;lt;&amp;lt;8
|s&amp;gt;&amp;gt;8)^((s&amp;amp;0xff
)&amp;lt;&amp;lt;1),s=0x7e00^
(s&amp;gt;&amp;gt;1)^(0x9e74&amp;amp;
-(~s&amp;amp;1));return
46497^s?s:s^s;}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
</feed>
