<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Llama the ultimate</title>
    <atom:link href="https://llama-the-ultimate.org/feed.xml" rel="self" type="application/rss+xml" />
    <link>https://llama-the-ultimate.org</link>
    <description>A blog with some stuff in it.</description>
    <language>en</language>
    <image>
      <url>https://llama-the-ultimate.org/assets/icon.png</url>
      <title>Llama the ultimate</title>
      <link>https://llama-the-ultimate.org</link>
    </image>
    <item>
      <title>A base 60 datetime format</title>
      <link>https://llama-the-ultimate.org/notes/datetime.html</link>
      <description>More sculpting I guess.</description>
      <pubDate>Sun, 20 Aug 2023 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/datetime.html</guid>
      <content:encoded><![CDATA[<h1>A base 60 datetime format</h1><p><a href="https://llama-the-ultimate.orghttps://github.com/buckket/twtxt">I have run into twtxt a couple of times.</a><br><a href="https://llama-the-ultimate.orghttps://wiki.xxiivv.com/site/time.html">Alos arvelie.</a></p><p>So anyway I was thinking about something like: What if twtxt but more hypertext? Or: If you want more of the basics, like, uh, “retwtxt” or replies, then I guess each twtxt needs an id of some kind. I guess url*timestamp is unique. What if a timestamp was shorter and looked more id-like? Maybe the way arvelie-dates look more id-like to me.</p><p>Playing with that idea. Regular calendar and time system. Just some formatting.</p><h2>Alphabet</h2><p>With a 60-character alphabet I can use one character for minute, one for day, and one for month. (And one for second, but eh, minute-precision seems fine.)</p><p>Also by avoiding base 64 I can use only ASCII letters and digits. Also I don't like the way the normal base 64 alphabet is ordered. Digits then uppercase letters then lowercase letters makes it easier to use regular string comparison stuff for comparing timestamps.</p><p>Trying this: 8 digits, 26 uppercase letters, 26 lowercase letters. Only the first 8 digits since that somehow seems less arbitrary to me than dropping some of the letters.</p><figure><pre><code>const alphabet = &quot;01234567ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&quot;;</code></pre></figure><h2>Numbers to chars and chars to numbers</h2><figure><pre><code>const b60FromInt = (i) =&gt; {
  let rest = i;
  let res = &quot;&quot;;
  while (rest &gt;= alphabet.length) {
    res = alphabet[rest % alphabet.length] + res;
    rest = (rest / alphabet.length) &gt;&gt;&gt; 0;
  }
  return alphabet[rest] + res;
};

const intFromB60 = (s) =&gt; {
  let res = 0;
  for (const c of s) {
    const idx = alphabet.indexOf(c);
    res = (res * 60) + (idx &lt; 0 ? 0 : idx);
  }
  return res;
};</code></pre></figure><h2>Datetime</h2><ul><li>Last character is minute.</li><li>The one before that is hour.</li><li>The one before that is day of month.</li><li>The one before that is month of year.</li><li>Everything before that is the year.</li></ul><figure><pre><code>const dateFromB60 = (s) =&gt; {
  const res = new Date();
  res.setUTCFullYear(intFromB60(s.slice(0, -4)));
  res.setUTCMonth(intFromB60(s.slice(-4, -3)));
  res.setUTCDate(intFromB60(s.slice(-3, -2)) + 1);
  res.setUTCHours(intFromB60(s.slice(-2, -1)));
  res.setUTCMinutes(intFromB60(s.slice(-1)));
  res.setUTCSeconds(0);
  res.setUTCMilliseconds(0);
  return res;
};

const b60FromDate = (d, minYLength = 0) =&gt; {
  const year = b60FromInt(d.getUTCFullYear()).padStart(minYLength , &quot;0&quot;);
  const month = b60FromInt(d.getUTCMonth());
  const day = b60FromInt(d.getUTCDate() - 1);
  const hour = b60FromInt(d.getUTCHours());
  const minute = b60FromInt(d.getUTCMinutes());
  return year + month + day + hour + minute;
};</code></pre></figure><p>Test:</p><figure><pre><code>console.log(b60FromDate(new Date()));
console.log(dateFromB60(b60FromDate(new Date())));</code></pre></figure><h2>Stuff</h2><p>It’s all within ASCII, so one byte per character in UTF-8: 4 bytes, or a 32-bit value, for month*day*hour*minute. As many bytes as I’d like for year, depending on which years I’m interested in. 2 bytes goes up to year 3600, 3 and 4 bytes go up to way more. If I want negative-number-years I can introduce a sign-byte.</p><p>I wonder if I should timestamp my posts here with something like this instead of how I currently do it. Mostly just obfuscation: I like the idea of not immediately being able to tell like “this is current, this is old.” I dunno.</p>]]></content:encoded>
    </item>
    <item>
      <title>Presentation-mode</title>
      <link>https://llama-the-ultimate.org/notes/slides.html</link>
      <description>Sliding.</description>
      <pubDate>Mon, 14 Aug 2023 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/slides.html</guid>
      <content:encoded><![CDATA[<h1>Presentation-mode</h1><p>If you run this in a browser with JavaScript enabled you should be able to turn the page into kind of a slideshow thing by running this code:</p><figure><pre><code>init(&quot;24px&quot;, &quot;40rem&quot;);</code></pre></figure><p>You can edit the code and change the <code>&quot;24px&quot;</code> and <code>&quot;40rem&quot;</code> to adjust font-size and width of page/slides.</p><p>Some new buttons should show up. You can enter slideshow mode and hop between slides with those, or with the <code>q</code>, <code>w</code> and e keys. (Also show/hide the bit that shows the current time with <code>t</code>.)</p><p>If you don’t run the JavaScript, you can still read through the page. There will be some repeated headings that would otherwise be on different slides.</p><p>If you want to (modify and) run the JavaScript as you read through the page, you can use use “wait” in the URL query thing:<br><a href="https://llama-the-ultimate.org/notes/slides.html?wait=true">This page, but it lets you edit and run the JavaScript as you go.</a></p><h2>Background</h2><p>This one time I needed to make some slides for a presentation and I thought:</p><ul><li>I don’t want to use Microsoft PowerPoint or Google Slides.</li><li>It’d be handy to put the slides somewhere I can point a web browser at.</li></ul><h2>Background</h2><p>There are HTML presentation frameworks.</p><ul><li>They let you create things like “stunning presentations.”</li><li>They’re frameworks, with probably hundreds or thousands of lines worth of stuff in them.</li></ul><p>I didn’t really want either of those things.</p><h2>Background</h2><ul><li>I decided that what I wanted was a very plain web page with some controls for showing different parts of the page.</li><li>I cobbled something together, and I’ve kind of remade it once or twice for other presentations.</li><li>This is me putting a version of it somewhere I’ll remember it.</li><li>This version has some basics. I can copy and modify it as needed.</li></ul><h2>elem</h2><p>Okay. Some code.</p><p><a href="https://llama-the-ultimate.org/notes/elem.html"><code>elem</code> function from other post:</a></p><figure><pre><code>const elem = (tagName, props, ...children) =&gt; {
  const el = Object.assign(document.createElement(tagName), props);
  el.replaceChildren(...children);
  return el;
};</code></pre></figure><h2>How much time is left?</h2><p>Not that much about the <em>slides</em>, but: When I give a talk I want to not use more time than I’m supposed to. I think it’s hard to keep track of time. If I put the time on top of the slides it’s a little easier for me.</p><h2>How much time is left?</h2><p>We’ll make an element that stays in a fixed position:</p><figure><pre><code>document.head.appendChild(elem(&quot;style&quot;, {}, `
.time {
  position: fixed;
  font-family: monospace;
  font-size: 2rem;
  top: 0.5rem;
  right: 0.5rem;
}
`));
const time = elem(&quot;div&quot;, { className: &quot;time&quot; }, &quot;it is now&quot;);
document.body.appendChild(time);</code></pre></figure><h2>How much time is left?</h2><p>And we’ll make it show the correct time:</p><figure><pre><code>let showTime = true;

const refreshTime = () =&gt; {
  const str = new Date().toISOString().slice(-13, -8);
  time.innerHTML = showTime ? str : &quot;&quot;;
};
refreshTime();</code></pre></figure><h2>How much time is left?</h2><p>Since what time it is changes every now and then, we’ll <code>refreshTime</code> frequently. We’re only showing hours and minutes, so refreshing a couple of times each second should be more than enough:</p><figure><pre><code>const timer = () =&gt; {
  refreshTime();
  setTimeout(timer, 500);
};
timer();</code></pre></figure><h2>Slides then</h2><p>Idea is:</p><ul><li>Run through the contents of the page and make a list of slides from it.</li><li>Make stuff for showing a slide, next/previous stuff, entering and leaving slideshow.</li><li>Add slideshow controls to page.</li><li>Stuff.</li></ul><h2>A list of slides and the currently selected slide.</h2><p><code>current</code> is the index of the slide we’re showing, or <code>null</code> if we’re showing the full page.</p><figure><pre><code>const slides = [[]];
let current = null;</code></pre></figure><h2>A slide is a list of elements</h2><p>We’ll just run through the page and add stuff to the current slide. We’ll add a new current slide whenever we run into a heading. (At least H1-H3. I never bother with the other ones.)</p><figure><pre><code>[...document.body.children].forEach((x, i) =&gt; {
  if ([&quot;H1&quot;, &quot;H2&quot;, &quot;H3&quot;].includes(x.tagName)) {
      slides.push([]);
  }
  slides[slides.length - 1].push(x);
});</code></pre></figure><p>This makes it so the first slide is just the bit with date and index-link, before the first heading. Not the best slide I’ve seen, but I’m okay with it.</p><h2>Showing a slide</h2><p>We show a slide by replacing everything in the <code>&lt;body&gt;</code> with the elements from the slide-list:</p><figure><pre><code>const addSlide = (slide) =&gt;
  document.body.append(...slide);

const show = (i) =&gt; {
  current = Math.min(slides.length - 1, Math.max(0, i));
  const slide = slides[current];
  document.body.replaceChildren(time);
  addSlide(slide);
  slide[0].scrollIntoView(true);
}</code></pre></figure><h2>Next and previous slide</h2><p><code>slide</code> is also a verb. Like you slide in this or that direction.</p><figure><pre><code>const slide = (offset) =&gt; {
  if (current !== null) {
    show(current + offset);
  }
};</code></pre></figure><h2>Entering</h2><p>If we’re viewing the full page and want to enter slideshow mode, we can find the first slide that is currently within view:</p><figure><pre><code>const enter = () =&gt; {
  if (current !== null) {
    return;
  }
  const elementInView = el =&gt; el.getBoundingClientRect().bottom &gt; 0;
  const inView = slide =&gt; elementInView(slide[slide.length - 1]);
  const idx = slides.findIndex(inView);
  show(idx &lt; 0 ? 0 : idx);
};</code></pre></figure><h2>Leaving</h2><p>We go back to the full page by putting the content of all the slides in the <code>&lt;body&gt;</code>. And we scroll the previously shown slide into view so that we end up in kind of the right part of the page.</p><figure><pre><code>const fullPage = () =&gt; {
  current = null;
  document.body.replaceChildren(time);
  slides.forEach(addSlide);
};

const leave = () =&gt; {
  if (current !== null) {
    const slide = slides[current];
    fullPage();
    slide[0].scrollIntoView(true);
  }
};</code></pre></figure><h2>Keyboard shortcuts</h2><ul><li><code>q</code>/<code>e</code> for previous/next slide.</li><li><code>w</code> toggles between full page and slideshow.</li><li><code>t</code> turns the element with the time on/off.</li></ul><figure><pre><code>const commands = new Map([
  [&quot;q&quot;, () =&gt; { enter(); slide(-1); }],
  [&quot;e&quot;, () =&gt; { enter(); slide(1); }],
  [&quot;w&quot;, () =&gt; (current === null ? enter: leave)()],
  [&quot;t&quot;, () =&gt; { showTime = !showTime; refreshTime(); }]
]);</code></pre></figure><h2>Keyboard shortcuts</h2><figure><pre><code>const addKeys = () =&gt;
  document.onkeydown = (e) =&gt; {
    const key = e.key.toLowerCase();
    if (commands.has(key)) {
      e.preventDefault();
      commands.get(key)();
    }
  };</code></pre></figure><h2>Buttons</h2><p>We’ll add some clickable buttons to the start of each slide:</p><figure><pre><code>const button = (text, title, onclick, disabled) =&gt;
  elem(
    &quot;button&quot;,
    { title: title, onclick: onclick, disabled: disabled },
    text
  );</code></pre></figure><h2>Buttons</h2><figure><pre><code>const addButtons = () =&gt;
  slides.forEach((slide, i) =&gt; {
    const toggle = () =&gt; {
      if (current === null) {
        show(i);
      } else {
        leave();
      }
    };
    const buttons = elem(
      &quot;div&quot;,
      {},
      button(&quot;◀&quot;, &quot;Previous&quot;, () =&gt; show(i - 1), i === 0),
      button(&quot;⛶&quot;, &quot;Toggle&quot;, toggle, false),
      button(&quot;▶&quot;, &quot;Next&quot;, () =&gt; show(i + 1), i === slides.length - 1)
    );
    slide.unshift(buttons);
  });</code></pre></figure><h2>Resizing stuff</h2><p>Slideshows often have larger letters and stuff.</p><figure><pre><code>const sizeElement = (rem, width) =&gt; elem(&quot;style&quot;, {}, `
:root {
  font-size: ${rem};
}
.slideshow {
  max-width: ${width};
  margin: 0 auto 0 auto;
}
`);</code></pre></figure><h2>Resizing stuff</h2><p>Resizing a <code>textarea</code> so the content kind of fits is kind of hacky.</p><figure><pre><code>const resizeTextarea = (ta) =&gt; {
  ta.setAttribute(&quot;style&quot;, &quot;height: 0;&quot;);
  const height = ta.scrollHeight;
  ta.setAttribute(&quot;style&quot;, `height: ${height }px;`);
  const extra = ta.offsetHeight - ta.clientHeight;
  ta.setAttribute(&quot;style&quot;, `height: ${height + extra}px;`);
};</code></pre></figure><h2>Init</h2><p><code>init</code> does the things. Arguments are passed along to <code>sizeElement</code>.</p><figure><pre><code>let size = null;

const init = (rem, width) =&gt; {
  if (size === null) {
    addKeys();
    addButtons();
    fullPage();
  } else {
    size.remove();
  }
  size = document.head.appendChild(sizeElement(rem, width));
  document.body.className = &quot;slideshow&quot;;
  for (const editor of document.getElementsByClassName(&quot;editor&quot;)) {
    resizeTextarea(editor);
  }
};</code></pre></figure><h2>That’s it</h2><p>That more or less it I guess.</p><h2>Variations, considerations</h2><p>I’ve previously done like a <code>&lt;div class=&quot;slide&quot;&gt;</code> for each slide. Makes it more straightforward to grab the list of slides with code. But a bit more nested stuff when writing the slides. I think I like this way better, but I dunno.</p><h2>Variations, considerations</h2><p>Also I’ve previously used some “container” element instead putting stuff directly into <code>&lt;body&gt;</code>. Makes it so I can put the time-element outside of the container instead of making sure I add it whenever I replace the contents of <code>&lt;body&gt;</code>.</p><p>On a similar note: The buttons could be moved to outside of the actual slides. I kind of like having them all over the place so that you have like a button for entering <em>this</em> slide and a button for entering <em>that</em> slide and so on, but...</p><h2>Variations, considerations</h2><p>It’s easy to change which elements should start new slides. It’s also possible to have separator-elements between slides instead/as well, like if I want slides with no headings. E.g. I could make it so that <code>&lt;hr&gt;</code> starts a new slide but is not added to the slide content. (Might wanna change the slide data structure to something that can hold on to the separator in addition to the content of the slide, if I want to restore the separators when I’m doing <code>fullPage</code>.)</p><h2>Variations, considerations</h2><p>I’m only dealing with elements when I put stuff into slides. If I also had text nodes directly under <code>&lt;body&gt;</code> I’d maybe have to do more stuff.</p><h2>Okay that’s actually all of it</h2><p>Done.</p><p>All of the code:</p><figure><pre><code>const editors = [...document.querySelectorAll(&quot;.editor&quot;)];</code></pre></figure><figure><pre><code>const code = `
${editors.slice(1, -2).map((e) =&gt; e.value).join(&quot;\n\n&quot;)}

${editors[0].value}
`;
console.log(code);</code></pre></figure><br>]]></content:encoded>
    </item>
    <item>
      <title>Lines</title>
      <link>https://llama-the-ultimate.org/notes/lines.html</link>
      <description>For drawing with.</description>
      <pubDate>Mon, 07 Aug 2023 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/lines.html</guid>
      <content:encoded><![CDATA[<h1>Lines</h1><p>(You need to view this in a browser with JavaScript enabled to use the editor.)</p><p>Controls:</p><ul><li>Add a new lines-point or reposition text: Click within the outlined svg-element.</li><li>Deselect: Enter or right-click within the outlined svg-element.</li><li>Add new text: Start writing when no thing is selected.</li><li>Select things to edit: Click, ctrl-click or shift-click the buttons. Also ctrl+arrow keys. Also ctrl+A.</li><li>Move selected things: Arrow keys.</li><li>Remove last point or character of selected thing(s): Backspace.</li><li>Remove selected things: Delete.</li><li>Resize drawing: Edit the numbers at the end of the <code>``` lines</code>-line in the textarea.</li></ul><p>(Things got a little single-page application here. Some browser keyboard shortcuts are broken. Sorry.)</p><p>Text-format:</p><ul><li><code>``` lines &lt;w h&gt;</code>: opening with <code>w×h</code>-size.</li><li><code>l &lt;x1 y1&gt; ... &lt;xn yn&gt;</code>: Lines from point to point.</li><li><code>t &lt;x y&gt; &lt;text&gt;</code>: &lt;text&gt; centered at <code>x,y</code>.</li><li><code>```</code>: closing line.</li></ul><p>Editing the text updates the drawing. Editing the drawing updates the text. Size of drawing can only be edited as text. If you need to edit/move individual points within a series-of-lines-thing that can (currently?) only be done in text.</p><p>The coordinate system is like based on the font size. When rendering to svg four units make one <code>em</code>.</p><h2>Glorpdown</h2><p>I’d been playing with the idea of putting inline svg or something in my posts.<br><a href="https://llama-the-ultimate.orghttps://akkartik.name/lines.html">Then I saw Kartik Agaram’s “Plain text. With lines.”</a><br>And that looked like a better fit for my markup language: A small language for drawings with lines in them. Also I was already using similar <code>```</code>-toggling for various stuff :)</p><p>I want to have stuff like text with lines or arrows between them. So my language supports lines and text. It’s also pretty Glorpdown-like, line-oriented and that, and can be parsed in a similar way.</p><p><a href="https://llama-the-ultimate.org/glorpdown.html">Example in Glorpdown-editor here.</a></p><p><a href="https://llama-the-ultimate.org/notes/lamb-what.html">It is currently used for the syntax tree in the “What do the lambdas?”-post. (Was previously separate svg-file.)</a><br>Can copypaste this into the textarea to see:</p><figure><pre><code>``` lines 104 80
t 59 8 (application)
t 59 12 (λa.a (foo a)) bar
l 52 15 36 22
t 36 25 (abstraction)
t 35 29 λa.a (foo a)
l 65 15 81 22
t 82 24 (reference)
t 82 28 bar
l 34 32 34 35
t 35 38 (application)
t 34 43 a (foo a)
l 29 46 18 49
t 16 52 (reference)
t 15 56 a
l 37 46 48 49
t 51 52 (application)
t 50 56 foo a
l 46 59 36 63
t 35 65 (reference)
t 34 69 foo
l 55 59 63 63
t 65 65 (reference)
t 66 69 a
```</code></pre></figure><h2>Implementation</h2><p>(The code below is picked up and executed when this page is loaded.)</p><details><summary>Style</summary><p><a href="https://llama-the-ultimate.org/notes/elem.html">(With <code>elem</code> function from other post.)</a></p><p>To make the svg-element more self-contained: Adding <code>svgStyle</code> to the svg-element later instead of to head.</p><figure><pre><code>const elem = (tagName, props, ...children) =&gt; {
  const el = Object.assign(document.createElement(tagName), props);
  el.replaceChildren(...children);
  return el;
};

const styles = `
.column {
  display: flex;
  flex-direction: column;
}

.buttons {
  display: flex;
  flex-direction: column;
  width: 20rem;
}

.lines-button {
  text-align: left;
  font-size: 1rem;
}

.row {
  display: flex;
  flex-direction: row;
}

.svg-canvas {
  outline-style: solid;
  margin: 0.3rem;
}

.lines-text {
  width: 25rem;
}
.selection-marker {
  width: 1rem;
}
`;
document.head.appendChild(elem(&quot;style&quot;, {}, styles));

const svgStyle = `
&lt;style&gt;
  svg {
    stroke: currentColor;
    fill: none;
  }
  text {
    stroke: none;
    dominant-baseline: middle;
    text-anchor: middle;
    fill: currentColor;
  }
  .selected {
    stroke: #00ff00;  
  }
  text.selected {
    stroke: none;
    fill: #00ff00;
  }
&lt;/style&gt;
`;</code></pre></figure></details><details><summary>Vectors</summary><p>For positions, sizes, directions. Vectors support addition.</p><figure><pre><code>class Vector {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  add(v) {
    return new Vector(this.x + v.x, this.y + v.y);
  }
  static get left() {
    return new Vector(-1, 0);
  }
  static get right() {
    return new Vector(1, 0);
  }
  static get up() {
    return new Vector(0, -1);
  }
  static get down() {
    return new Vector(0, 1);
  }
}</code></pre></figure></details><details><summary>A drawing has things in it</summary><p>The content of a drawing is a bunch of things. A thing is some lines or some text. There’s some stuff we can (attempt to) do to things:</p><ul><li>We can move a thing.</li><li>We can add a position to a thing or set the position of a thing.</li><li>We can (attempt to) add a character to a thing.</li><li>We can “go back.” This is vaguely undo-like, but really more backspace-like.</li></ul><figure><pre><code>class Lines {
  constructor(positions) {
    this.positions = positions === undefined ? [] : positions;
  }
  match(cases) {
    return cases.lines(this.positions);
  }
  move(vec) {
    this.positions = this.positions.map((pos) =&gt; pos.add(vec));
  }
  addPosition(position) {
    this.positions.push(position);
  }
  addCharacter(c) {}
  back() {
    this.positions.splice(-1, 1);
  }
}

class Text {
  constructor(position, str) {
    this.position = position;
    this.str = str === undefined ? &quot;&quot; : str;
  }
  match(cases) {
    return cases.text(this.position, this.str);
  }
  move(vec) {
    this.position = this.position.add(vec);
  }
  addPosition(position) {
    this.position = position;
  }
  addCharacter(c) {
    this.str += c;
  }
  back() {
    this.str = this.str.slice(0, -1);
  }
}</code></pre></figure><p>A drawing is width×height-size and an ordered list of things. Not too objecty, mostly just data. That’s okay.</p><figure><pre><code>class Drawing {
  constructor(size = new Vector(60, 40), things = []) {
    this.size = size;
    this.things = things;
  }
}</code></pre></figure><p>Parsing turns strings into things.</p><figure><pre><code>const regCase = (str, list) =&gt; {
  for (const [regex, f] of list) {
    const match = str.match(regex);
    if (match !== null) {
      return f(match);
    }
  }
  return null;
};

const parse = new (class {
  vec(str) {
    const match = str.match(/^\s*(\d+)\s+(\d+)\s*$/);
    return match === null
      ? null
      : new Vector(parseInt(match[1]), parseInt(match[2]));
  }
  vecs(str) {
    const res = [];
    let rest = str;
    while (true) {
      const match = rest.match(/^\s*(\d+)\s+(\d+)\s*(.*)$/);
      if (match === null) {
        return res;
      }
      res.push(new Vector(parseInt(match[1]), parseInt(match[2])));
      rest = match[3];
    }
  }
  drawing(str) {
    const res = new Drawing();
    for (const line of str.split(&quot;\n&quot;)) {
      regCase(line, [
        [
          /^```\s+lines\s+(\d+\s+\d+)\s*$/,
          (match) =&gt; {
            res.size = this.vec(match[1]);
          },
        ],
        [
          /^l(.*)$/,
          (match) =&gt; {
            res.things.push(new Lines(this.vecs(match[1])));
          },
        ],
        [
          /^t\s*(\d+\s+\d+)\s+(.*)$/,
          (match) =&gt; {
            res.things.push(new Text(this.vec(match[1]), match[2]));
          },
        ],
      ]);
    }
    return res;
  }
})();</code></pre></figure><p>And unparsing turns things into strings.</p><figure><pre><code>const unparse = new (class {
  thing(thing) {
    return thing.match({
      text: (position, str) =&gt; `t ${position.x} ${position.y} ${str}`,
      lines: (positions) =&gt; {
        let str = &quot;l&quot;;
        for (const pos of positions) {
          str += ` ${pos.x} ${pos.y}`;
        }
        return str;
      },
    });
  }
  drawing(drawing) {
    let res = &quot;``` lines &quot;;
    res += `${drawing.size.x} ${drawing.size.y}`;
    drawing.things.forEach((t) =&gt; {
      res += `\n${this.thing(t)}`;
    });
    res += &quot;\n```&quot;;
    return res;
  }
})();</code></pre></figure></details><details><summary>Selection</summary><p>A selection is used for keeping track of which things are selected when editing a drawing. It’s not too concerned with the actual things, just <em>where</em> in the ordered list they are. So it holds onto a set of indices and the total number of things.</p><figure><pre><code>class Selection {
  constructor(limit = 0) {
    this.limit = limit;
    this.ids = new Set();
  }
  isSelected(id) {
    return this.ids.has(id);
  }
  hasSelection() {
    return this.ids.size &gt; 0;
  }
  valid(id) {
    return id !== null &amp;&amp; id &gt;= 0 &amp;&amp; id &lt; this.limit;
  }
  wrap(id) {
    if (this.limit &lt; 1) {
      return null;
    }
    let res = id;
    while (res &lt; 0) {
      res += this.limit;
    }
    while (res &gt;= this.limit) {
      res -= this.limit;
    }
    return res;
  }
  select(id) {
    if (this.valid(id)) {
      this.ids = new Set([id]);
    }
  }
  deselect() {
    this.ids = new Set();
  }
  selectAll() {
    for (let i = 0; i &lt; this.limit; i++) {
      this.add(i);
    }
  }
  add(id) {
    if (!this.valid(id)) {
      return;
    }
    this.ids.add(id);
  }
  remove(id) {
    this.ids.delete(id);
  }
  toggle(id) {
    if (this.isSelected(id)) {
      this.remove(id);
    } else {
      this.add(id);
    }
  }
  expand(id) {
    const min = Math.min(id, ...this.ids);
    const max = Math.max(id, ...this.ids);
    for (let i = min; i &lt;= max; i++) {
      this.add(i);
    }
  }
  move(num) {
    if (!this.hasSelection()) {
      if (num &lt; 0) {
        this.ids = new Set([0]);
      } else if (num &gt; 0) {
        this.ids = new Set([-1]);
      }
    }
    const res = new Set();
    for (const i of this.ids) {
      res.add(this.wrap(i + num));
    }
    this.ids = res;
  }
  resize(limit) {
    this.limit = limit;
    for (const id of this.ids) {
      if (id &gt;= limit) {
        this.ids.delete(id);
      }
    }
  }
  itemsFrom(list) {
    const res = [];
    for (let i = 0; i &lt; this.limit; i++) {
      if (this.isSelected(i)) {
        res.push(list[i]);
      }
    }
    return res;
  }
}</code></pre></figure></details><details><summary>State</summary><p>The state ties things together. Keeps track of drawing and selection and has methods for stuff you can do.</p><figure><pre><code>class State {
  constructor(drawing = new Drawing()) {
    this.drawing = drawing;
    this.position = new Vector(0, 0);
    this.selection = new Selection(drawing.things.length);
  }
  selectedThings() {
    return this.selection.itemsFrom(this.drawing.things);
  }
  pushThing(thing) {
    this.drawing.things.push(thing);
    this.selection.resize(this.drawing.things.length);
    this.selection.select(this.drawing.things.length - 1);
  }
  selectedDo(f, orelse = () =&gt; {}) {
    if (this.selection.hasSelection()) {
      this.selectedThings().forEach(f);
    } else {
      orelse();
    }
  }
  move(vec) {
    this.selectedDo((thing) =&gt; thing.move(vec));
  }
  addPosition() {
    this.selectedDo(
      (thing) =&gt; thing.addPosition(this.position),
      () =&gt; this.pushThing(new Lines([this.position]))
    );
  }
  addCharacter(c) {
    this.selectedDo(
      (thing) =&gt; thing.addCharacter(c),
      () =&gt; this.pushThing(new Text(this.position, c))
    );
  }
  delete() {
    this.drawing.things = this.drawing.things.filter(
      (thing, id) =&gt; !this.selection.isSelected(id)
    );
    this.selection.deselect();
    this.selection.resize(this.drawing.things.length);
  }
  back() {
    this.selectedDo((thing) =&gt; thing.back());
  }
}</code></pre></figure></details><details><summary>Drawing into svg-element</summary><p>Rendering “into” an existing svg-element instead of returning a new thing. Since we have set up an svg-element, with events hooked up and such, that we want to keep using.</p><p>(Considered returning just the inner svg-stuff, but the scaling of things is kind of tied up to the height and width of the svg-element, so blah blah cohesion maybe.)</p><figure><pre><code>const svgScale = (size)  =&gt; (v) =&gt; {
  return {
    x: `${v.x * (100 / size.x)}%`,
    y: `${v.y * (100 / size.y)}%`,
  };
};

const drawToSvg = (state, svg) =&gt; {
  const drawing = state.drawing;
  const scale = svgScale(drawing.size);
  svg.setAttribute(&quot;width&quot;, `${drawing.size.x / 4}em`);
  svg.setAttribute(&quot;height&quot;, `${drawing.size.y / 4}em`);
  let res = svgStyle;
  drawing.things.forEach((thing, id) =&gt; {
    const selected = state.selection.isSelected(id) ? ` class=&quot;selected&quot;` : &quot;&quot;;
    thing.match({
      lines: (positions) =&gt; {
        let prev = null;
        for (const current of positions) {
          if (prev !== null) {
            const scaledPrev = scale(prev);
            const scaledCurrent = scale(current);
            res += `&lt;line${selected} x1=&quot;${scaledPrev.x}&quot; y1=&quot;${scaledPrev.y}&quot; x2=&quot;${scaledCurrent.x}&quot; y2=&quot;${scaledCurrent.y}&quot; /&gt;`;
          }
          prev = current;
        }
      },
      text: (position, str) =&gt; {
        const scaled = scale(position);
        res += `&lt;text${selected} x=&quot;${scaled.x}&quot; y=&quot;${scaled.y}&quot;&gt;${str}&lt;/text&gt;`;
      },
    });
  });
  svg.innerHTML = res;
};</code></pre></figure></details><details><summary>Making an editor</summary><p>A bunch of code:</p><figure><pre><code>const editor = (state) =&gt; {
  const posEl = document.createElementNS(
    &quot;http://www.w3.org/2000/svg&quot;,
    &quot;circle&quot;
  );
  posEl.setAttribute(&quot;r&quot;, &quot;2&quot;);

  const div = elem(&quot;div&quot;, { className: &quot;row&quot; });
  const buttons = div.appendChild(elem(&quot;div&quot;, { className: &quot;buttons&quot; }));
  const svgCol = div.appendChild(elem(&quot;div&quot;, { className: &quot;column&quot; }));

  const svg = svgCol.appendChild(
    document.createElementNS(&quot;http://www.w3.org/2000/svg&quot;, &quot;svg&quot;)
  );
  svg.classList.add(&quot;svg-canvas&quot;);
  const p = svgCol.appendChild(elem(&quot;p&quot;));

  const textarea = div.appendChild(elem(&quot;textarea&quot;, { className: &quot;lines-text&quot; }));
  textarea.oninput = () =&gt; {
    state.drawing = parse.drawing(textarea.value);
    state.selection.deselect();
    state.selection.resize(state.drawing.things.length);
    render.drawing();
    render.buttons();
  };

  const render = new (class {
    drawing() {
      drawToSvg(state, svg);
      render.mouse();
    }
    mouse() {
      const scaled = svgScale(state.drawing.size)(state.position);
      posEl.setAttribute(&quot;cx&quot;, scaled.x);
      posEl.setAttribute(&quot;cy&quot;, scaled.y);
      svg.appendChild(posEl);
      p.innerText = `${state.position.x},${state.position.y}`;
    }
    buttons() {
      buttons.replaceChildren();
      state.drawing.things.forEach((thing, i) =&gt; {
        const str = unparse.thing(thing);
        buttons.appendChild(
          elem(
            &quot;div&quot;,
            { className: &quot;row&quot; },
            elem(
              &quot;div&quot;,
              { className: &quot;selection-marker&quot; },
              state.selection.isSelected(i) ? &quot;&gt;&quot; : &quot;&quot;
            ),
            elem(
              &quot;button&quot;,
              {
                className: &quot;lines-button&quot;,
                onclick: (e) =&gt; {
                  if (e.shiftKey) {
                    state.selection.expand(i);
                  } else if (e.ctrlKey || e.metaKey) {
                    state.selection.toggle(i);
                  } else {
                    state.selection.select(i);
                  }
                  render.drawing();
                  render.buttons();
                },
              },
              str.length &gt; 38 ? str.slice(0, 35) + &quot;...&quot; : str
            )
          )
        );
      });
    }
    text() {
      textarea.value = unparse.drawing(state.drawing);
    }
  })();

  const posFromMouse = (e, size) =&gt; {
    const point = new DOMPoint(e.clientX, e.clientY);
    const translated = point.matrixTransform(svg.getScreenCTM().inverse());
    const box = svg.getBoundingClientRect();
    const x = Math.round((translated.x / box.width) * size.x);
    const y = Math.round((translated.y / box.height) * size.y);
    return new Vector(x, y);
  };

  svg.onmousemove = (e) =&gt; {
    state.position = posFromMouse(e, state.drawing.size);
    render.mouse();
  };
  svg.oncontextmenu = (e) =&gt; e.preventDefault();
  svg.onmousedown = (e) =&gt; {
    state.position = posFromMouse(e, state.drawing.size);
    render.mouse();
    if (e.buttons &lt; 2) {
      state.addPosition();
    }
    if (e.buttons == 2) {
      state.selection.deselect();
    }
    render.drawing();
    render.buttons();
    render.text();
  };

  const keyToSelectionOffset = (key) =&gt; {
    return key === &quot;ArrowUp&quot; ? -1 : key === &quot;ArrowDown&quot; ? 1 : null;
  };
  const keyToDir = (key) =&gt; {
    return key === &quot;ArrowLeft&quot;
      ? Vector.left
      : key === &quot;ArrowRight&quot;
      ? Vector.right
      : key === &quot;ArrowUp&quot;
      ? Vector.up
      : key === &quot;ArrowDown&quot;
      ? Vector.down
      : null;
  };

  document.onkeydown = (e) =&gt; {
    const active = document.activeElement.tagName;
    if (active === &quot;INPUT&quot; || active === &quot;TEXTAREA&quot;) {
      return;
    }
    const key = e.key;
    if (e.ctrlKey || e.metaKey) {
      const y = keyToSelectionOffset(key);
      if (y !== null) {
        e.preventDefault();
        state.selection.move(y);
        render.buttons();
        render.drawing();
        return;
      }
      if (key.toLowerCase() === &quot;a&quot;) {
        e.preventDefault();
        state.selection.selectAll();
        render.buttons();
        render.drawing();
        return;
      }
      return;
    }
    if (state.selected === null) {
      return;
    }
    if (key === &quot;Enter&quot;) {
      state.selection.deselect();
    } else if (key === &quot;Delete&quot;) {
      state.delete();
    } else if (key === &quot;Backspace&quot;) {
      state.back();
    } else {
      const dir = keyToDir(key);
      if (dir !== null) {
        state.move(dir);
      } else {
        if (key.length &gt; 1) {
          return;
        }
        state.addCharacter(e.key);
      }
    }
    e.preventDefault();
    render.drawing();
    render.buttons();
    render.text();
  };
  
  render.mouse();
  render.drawing();
  render.text();
  render.buttons();
  return div;
};</code></pre></figure><p>We’ll make one and put it somewhere near the top:</p><figure><pre><code>const state = new State(parse.drawing(
`
\`\`\` lines 100 60
l 35 21 35 25
l 51 21 51 26
l 31 32 31 32 36 37 48 38 56 32
t 42 30 o
\`\`\`
`
));
const h1 = document.getElementsByTagName(&quot;h1&quot;)[0];
h1.parentNode.insertBefore(editor(state), h1.nextSibling);</code></pre></figure></details>]]></content:encoded>
    </item>
    <item>
      <title>An 8-bit palette</title>
      <link>https://llama-the-ultimate.org/notes/palette.html</link>
      <description>A colourful array of colours.</description>
      <pubDate>Wed, 05 Apr 2023 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/palette.html</guid>
      <content:encoded><![CDATA[<h1>An 8-bit palette</h1><p>Bla blah. Some JavaScript for treating single bytes as RGB-values. Only works in browser with JavaScript and so on.</p><p><a href="https://llama-the-ultimate.orghttps://en.wikipedia.org/wiki/8-bit_color">From Wikipedia:</a></p><blockquote><p>The simplest form of quantization is to simply assign 3 bits to red, 3 bits to green and 2 bits to blue, as the human eye is less sensitive to blue light.</p></blockquote><figure><pre><code>Bit    7  6  5  4  3  2  1  0
Data   R  R  R  G  G  G  B  B</code></pre></figure><p>So that’s like 3-bit values (0-7) for R and G and a 2-bit value (0-3) for B. I multiply the R and G values by 36 and the B values by 85. Because that seems fine.</p><details><summary>Stylesheet stuff</summary><p><a href="https://llama-the-ultimate.org/notes/elem.html">(With <code>elem</code> function from other post.)</a></p><figure><pre><code>const elem = (tagName, props, ...children) =&gt; {
  const el = Object.assign(document.createElement(tagName), props);
  el.replaceChildren(...children);
  return el;
};

const styles = `
.palette {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}
.row {
  display: flex;
  flex-direction: row;
}
.square {
  box-sizing: border-box;
  border: none;
  width: 2rem;
  height: 2rem;
}
.selectedColor {
  border-style: dashed;
}
`;
document.head.appendChild(elem(&quot;style&quot;, {}, styles));</code></pre></figure></details><details><summary>Implementation details</summary><p><code>colorFromByte</code> gets the RGB-values from a byte and returns some hex:</p><figure><pre><code>let rFactor = 36;
let gFactor = 36;
let bFactor = 85;
const colorFromByte = (byte) =&gt; {
  const r = ((byte &amp; 0b11100000) &gt;&gt; 5) * rFactor;
  const g = ((byte &amp; 0b00011100) &gt;&gt; 2) * gFactor;
  const b = (byte &amp; 0b00000011) * bFactor;
  const hex = (i) =&gt; i.toString(16).padStart(2, &quot;0&quot;);
  return `#${hex(r)}${hex(g)}${hex(b)}`;
};
console.log(colorFromByte(15));</code></pre></figure><p>Which is <em>kind of</em> it. But also code for making palette that can be put on page:</p><figure><pre><code>const palette = () =&gt; {
  const colors = elem(&quot;div&quot;, { className: &quot;palette&quot; });
  let selectedColor = 0;
  const buttons = [];
  const selectColor = (idx) =&gt; {
    buttons[selectedColor].classList.remove(&quot;selectedColor&quot;);
    selectedColor = idx;
    buttons[selectedColor].classList.add(&quot;selectedColor&quot;);
  };

  const rowLength = 4;
  
  for (let row = 0; row &lt; 256 / rowLength; row++) {
    const rowDiv = elem(&quot;div&quot;, { className: &quot;row&quot; });
    colors.appendChild(rowDiv);
    for (let col = 0; col &lt; rowLength; col++) {
      const byte = (row * rowLength) + col;
      const button = elem(&quot;button&quot;, { className: &quot;square&quot; });
      rowDiv.appendChild(button);
      buttons.push(button);
      const color = colorFromByte(byte);
      button.style.background = color;
      button.onclick = () =&gt; {
        selectColor(byte);
        colors.dispatchEvent(
          new CustomEvent(&quot;selectColor&quot;, {
            detail: { byte: byte, color: color },
          })
        );
      };
    }
  }
  colors.selectColor = (idx) =&gt; {
    if (idx &gt;= 0 &amp;&amp; idx &lt; colorButtons.length) {
      selectColor(idx);
    }
  };
  return colors;
};
let pal;
let div;</code></pre></figure></details><p>Anyway run the code below to get a palette with clickable colours. Can also adjust some values and things in the code:</p><figure><pre><code>rFactor = 36;
gFactor = 36;
bFactor = 85;
pal = palette();
div = document.createElement(&quot;div&quot;);
div.style.width = &quot;10rem&quot;;
div.style.height = &quot;5rem&quot;;
outElement.replaceChildren(pal, div);
pal.addEventListener(&quot;selectColor&quot;, (e) =&gt; (div.style.background = e.detail.color));</code></pre></figure>]]></content:encoded>
    </item>
    <item>
      <title>JavaScript DOM framework</title>
      <link>https://llama-the-ultimate.org/notes/elem.html</link>
      <description>Creating an element.</description>
      <pubDate>Tue, 04 Apr 2023 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/elem.html</guid>
      <content:encoded><![CDATA[<h1>JavaScript DOM framework</h1><p>I tend to write a helper function for making a DOM element and these days it tend to end up looking kind of like this:</p><figure><pre><code>const elem = (tagName, props, ...children) =&gt; {
  const el = Object.assign(document.createElement(tagName), props);
  el.replaceChildren(...children);
  return el;
};</code></pre></figure><ul><li><code>tagName</code> is the tag name.</li><li><code>Object.assign</code> copies all the <code>props</code> over, so I can pass in <code>className</code> and such through that.</li><li><code>replaceChildren</code> puts the rest of the arguments in there.</li></ul><p>So uh we can use it for things. Beep boop:</p><figure><pre><code>const styles = `
.red {
  background-color: red;
}
.blue {
  background-color: blue;
}
.green {
  background-color: green;
}
`;
document.head.appendChild(elem(&quot;style&quot;, {}, styles));

outElement.appendChild(
  elem(
    &quot;div&quot;,
    {},
    elem(&quot;p&quot;, { className: &quot;red&quot; }, &quot;blue&quot;),
    elem(&quot;p&quot;, { className: &quot;blue&quot; }, &quot;red&quot;),
    elem(
      &quot;p&quot;,
      {
        onclick: (e) =&gt; e.target.classList.toggle(&quot;green&quot;),
      },
      &quot;green?&quot;
    )
  )
);</code></pre></figure>]]></content:encoded>
    </item>
    <item>
      <title>Sokoban: Winning the game</title>
      <link>https://llama-the-ultimate.org/notes/sokoboko-win.html</link>
      <description>Maybe feature-complete.</description>
      <pubDate>Thu, 30 Mar 2023 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/sokoboko-win.html</guid>
      <content:encoded><![CDATA[<h1>Sokoban: Winning the game</h1><p>(Best viewed in a browser with JavaScript enabled. You can click the play/run-buttons to run the JavaScript in the embedded editors. It should behave mostly like running the same code in the JavaScript console. (Hitting F12 or something and finding the console might also be useful if you wanna look around and inspect stuff more or something.))</p><p><a href="https://llama-the-ultimate.org/notes/sokoboko-move.html">Previously we made the cat move.</a></p><details><summary>Mostly the code from last time.</summary><figure><pre><code>const canvas = outElement.appendChild(document.createElement(&quot;canvas&quot;));
const scale = 3;
const ctx = canvas.getContext(&quot;2d&quot;);

let level;
let moveList;

const moveListP = outElement.appendChild(document.createElement(&quot;p&quot;));

const setLevel = (str) =&gt; {
  level = str.split(&quot;\n&quot;).map((x) =&gt; x.split(&quot;&quot;));
  if (level[0].every((x) =&gt; x === &quot; &quot;)) {
    level.shift();
  }
  if (level[level.length - 1].every((x) =&gt; x === &quot; &quot;)) {
    level.pop();
  }
  moveList = &quot;&quot;;
  canvas.width = level[0].length * 16 * scale;
  canvas.height = level.length * 16 * scale;
  ctx.imageSmoothingEnabled = false;
  drawLevel();
};
const level1 = `
#########
#  $ @..#
# $ $   #
#  ###  #
# $     #
##  ##..#
#########
`;

const levelGet = (position) =&gt; level[position.y][position.x];
const levelSet = (position, value) =&gt; level[position.y][position.x] = value;

const spriteSheet = document.createElement(&quot;img&quot;);
spriteSheet.src = &quot;./../assets/soko-sprites.png&quot;
spriteSheet.alt = &quot;sprite sheet&quot;;

const vector = (x, y) =&gt; ({ x: x, y: y });
const plus = (a, b) =&gt; vector(a.x + b.x, a.y + b.y);
const directions = {
  u: vector(0, -1),
  d: vector(0, 1),
  l: vector(-1, 0),
  r: vector(1, 0),  
};

const sprites = {
  &quot; &quot;: vector(0, 0), // top left is empty floor
  &quot;#&quot;: vector(1, 0), // top right is wall
  &quot;@&quot;: vector(0, 1), // middle left is player
  &quot;+&quot;: vector(0, 1), // same sprite for player on goal square
  &quot;$&quot;: vector(1, 1), // middle right is “box”
  &quot;.&quot;: vector(0, 2), // bottom left is goal square
  &quot;*&quot;: vector(1, 2), // middle left is “bosdx” on a goal square
};

const drawSquare = (square, position) =&gt; {
  const sprite = sprites[square];
  ctx.drawImage(
    spriteSheet,
    sprite.x * 16,
    sprite.y * 16,
    16,
    16,
    position.x * 16 * scale,
    position.y * 16 * scale,
    16 * scale,
    16 * scale
  );
};

const drawLevel = () =&gt; {
  level.forEach((row, y) =&gt; row.forEach((square, x) =&gt; drawSquare(square, vector(x, y))));
  moveListP.innerText = moveList;
};

spriteSheet.onload = () =&gt; setLevel(level1);

const playerPosition = () =&gt; {
  for ([y, row] of level.entries()) {
    for ([x, square] of row.entries()) {
      if (square === &quot;@&quot; || square === &quot;+&quot;) {
        return vector(x, y);
      }
    }
  }
};

const player = [&quot;@&quot;, &quot;+&quot;];
const box = [&quot;$&quot;, &quot;*&quot;];
const floor = [&quot; &quot;, &quot;.&quot;];

const move = (thing, from, direction) =&gt; {
  const fromIdx = thing.indexOf(levelGet(from));
  if (fromIdx &lt; 0) {
    return false;
  }
  const to = plus(from, direction);
  const toIdx = floor.indexOf(levelGet(to));
  if (toIdx &lt; 0) {
    return false;
  }
  levelSet(from, floor[fromIdx]);
  levelSet(to, thing[toIdx]);
  return true;
};

const movePlayer = (directionLetter) =&gt; () =&gt; {
  const direction = directions[directionLetter];
  const position = playerPosition();
  const movedBox = move(box, plus(position, direction), direction);
  const movedPlayer = move(player, position, direction);
  if (!movedPlayer) {
    return false;
  }
  moveList += movedBox ? directionLetter.toUpperCase() : directionLetter;
  return true;
};

const commands = new Map([
  [&quot;w&quot;, movePlayer(&quot;u&quot;)],
  [&quot;a&quot;, movePlayer(&quot;l&quot;)],
  [&quot;s&quot;, movePlayer(&quot;d&quot;)],
  [&quot;d&quot;, movePlayer(&quot;r&quot;)]
]);

const doCommand = (key) =&gt; {
  if (commands.has(key)) {
    commands.get(key)();
    drawLevel();
  }
};
canvas.tabIndex = 0;
canvas.onkeydown = event =&gt; doCommand(event.key.toLowerCase());

const button = (key) =&gt; {
  const element= outElement.appendChild(document.createElement(&quot;button&quot;));
  element.innerText = key;
  element.style.fontSize = &quot;2rem&quot;;
  element.style.width = &quot;3rem&quot;;
  element.onclick = () =&gt; doCommand(key);
};

const space = outElement.appendChild(document.createElement(&quot;div&quot;));
space.style.float = &quot;left&quot;;
space.style.height = &quot;1px&quot;;
space.style.width = &quot;3rem&quot;;
button(&quot;w&quot;);
outElement.appendChild(document.createElement(&quot;br&quot;));
&quot;asd&quot;.split(&quot;&quot;).forEach(button);</code></pre></figure><p>Very playable.</p></details><h2>Win condition</h2><p>You’ve won the game if every goal has a box on it. So if there are no goal squares left with either nothing on them or player on them:</p><figure><pre><code>const won = () =&gt;
  !level.some((row) =&gt; row.some((square) =&gt; square === &quot;.&quot; || square === &quot;+&quot;));

console.log(won());</code></pre></figure><p>We’ll test it with a won level:</p><figure><pre><code>setLevel(`
######
# @  #
#*  *#
######
`);
console.log(won());</code></pre></figure><p>Seems fine. Let’s fix the commands so they take winning into account, and switch to very winnable level for testing:</p><figure><pre><code>const wonP = document.createElement(&quot;p&quot;);
moveListP.insertAdjacentElement(&quot;beforebegin&quot;, wonP);

const takeWinningIntoAccount = (command) =&gt; () =&gt; {
  if (!won()) {
    command();
    wonP.innerText = won() ? &quot;Yay!&quot; : &quot;&quot;;
  }
};
[...commands.entries()].forEach(([key, command]) =&gt; commands.set(key, takeWinningIntoAccount(command)));

setLevel(`
######
# @  #
#   $#
#.$ .#
######
`);</code></pre></figure><p>Seems fine.</p><h2>Undo</h2><p>Also let’s implement undo. Undoing a move is kind of like moving in the opposite direction:</p><figure><pre><code>const opposite = (v) =&gt; vector(-v.x, -v.y);
console.log(opposite(directions.r));</code></pre></figure><p>We undo by:</p><ul><li>Removing the last character from <code>moveList</code>.</li><li>Moving the player in the opposite direction of the move we removed from <code>moveList</code>.</li><li>If the move we removed was in uppercase, “dragging” a box along after the player.</li></ul><figure><pre><code>const undo = () =&gt; {
  if (moveList === &quot;&quot;) {
    return;
  }
  const moveMade = moveList.slice(-1);
  moveList = moveList.slice(0, -1);
  const moveDir = directions[moveMade.toLowerCase()];
  const undoDir = opposite(moveDir);
  const playerPos = playerPosition();
  move(player, playerPos, undoDir);
  if (moveMade === moveMade.toUpperCase()) {
    move(box, plus(playerPos, moveDir), undoDir);
  }
};
commands.set(&quot;z&quot;, undo);
outElement.appendChild(document.createElement(&quot;br&quot;));
button(&quot;z&quot;);</code></pre></figure><p>We can restart a level by undoing a lot:</p><figure><pre><code>const restart = () =&gt; {
  while (moveList !== &quot;&quot;) {
    undo();
  }
};
commands.set(&quot;r&quot;, restart);
button(&quot;r&quot;);</code></pre></figure><p>Okay okay. It’s probably a game now...</p><figure><pre><code>setLevel(level1);</code></pre></figure>]]></content:encoded>
    </item>
    <item>
      <title>Sokoban: Making cat move</title>
      <link>https://llama-the-ultimate.org/notes/sokoboko-move.html</link>
      <description>It’s a pushycat.</description>
      <pubDate>Wed, 22 Feb 2023 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/sokoboko-move.html</guid>
      <content:encoded><![CDATA[<h1>Sokoban: Making cat move</h1><p>(Best viewed in a browser with JavaScript enabled. You can click the play/run-buttons to run the JavaScript in the embedded editors. It should behave mostly like running the same code in the JavaScript console. (Hitting F12 or something and finding the console might also be useful if you wanna look around and inspect stuff more or something.))</p><p><a href="https://llama-the-ultimate.org/notes/sokoboko-gfx.html">In previous post we drew a level.</a></p><details><summary>Mostly the code from last time.</summary><figure><pre><code>const canvas = outElement.appendChild(document.createElement(&quot;canvas&quot;));
const scale = 3;
const ctx = canvas.getContext(&quot;2d&quot;);

let level;
let moveList;

const moveListP = outElement.appendChild(document.createElement(&quot;p&quot;));

const setLevel = (str) =&gt; {
  level = str.split(&quot;\n&quot;).map((x) =&gt; x.split(&quot;&quot;));
  if (level[0].every((x) =&gt; x === &quot; &quot;)) {
    level.shift();
  }
  if (level[level.length - 1].every((x) =&gt; x === &quot; &quot;)) {
    level.pop();
  }
  moveList = &quot;&quot;;
  canvas.width = level[0].length * 16 * scale;
  canvas.height = level.length * 16 * scale;
  ctx.imageSmoothingEnabled = false;
  drawLevel();
};
const level1 = `
#########
#  $ @..#
# $ $   #
#  ###  #
# $     #
##  ##..#
#########
`;

const spriteSheet = document.createElement(&quot;img&quot;);
spriteSheet.src = &quot;./../assets/soko-sprites.png&quot;
spriteSheet.alt = &quot;sprite sheet&quot;;

const vector = (x, y) =&gt; ({ x: x, y: y });

const sprites = {
  &quot; &quot;: vector(0, 0), // top left is empty floor
  &quot;#&quot;: vector(1, 0), // top right is wall
  &quot;@&quot;: vector(0, 1), // middle left is player
  &quot;+&quot;: vector(0, 1), // same sprite for player on goal square
  &quot;$&quot;: vector(1, 1), // middle right is “box”
  &quot;.&quot;: vector(0, 2), // bottom left is goal square
  &quot;*&quot;: vector(1, 2), // middle left is “bosdx” on a goal square
};

const drawSquare = (square, position) =&gt; {
  const sprite = sprites[square];
  ctx.drawImage(
    spriteSheet,
    sprite.x * 16,
    sprite.y * 16,
    16,
    16,
    position.x * 16 * scale,
    position.y * 16 * scale,
    16 * scale,
    16 * scale
  );
};

const drawLevel = () =&gt; {
  level.forEach((row, y) =&gt; row.forEach((square, x) =&gt; drawSquare(square, vector(x, y))));
  moveListP.innerText = moveList;
};

spriteSheet.onload = () =&gt; setLevel(level1);</code></pre></figure></details><h2>Some vectors</h2><p>We want to move the cat. We can make a function that returns its position, so that we know where to move it from. (Cats tend to move from where they are.)</p><figure><pre><code>const playerPosition = () =&gt; {
  for ([y, row] of level.entries()) {
    for ([x, square] of row.entries()) {
      if (square === &quot;@&quot; || square === &quot;+&quot;) {
        return vector(x, y);
      }
    }
  }
};

console.log(playerPosition());</code></pre></figure><p><a href="https://llama-the-ultimate.orghttp://www.sokobano.de/wiki/index.php?title=Level_format#Solution">A Sokoban solution is like a string where each character corresponds to one move made.</a></p><p>We will make vectors for the directions the cat can move in, and a plus-function that we can use for adding a direction to a position. We’ll use the (lowercase) letters that are used in Sokoban solutions as property names.</p><figure><pre><code>const directions = {
  u: vector(0, -1),
  d: vector(0, 1),
  l: vector(-1, 0),
  r: vector(1, 0),  
};

const plus = (a, b) =&gt; vector(a.x + b.x, a.y + b.y);

console.log(plus(playerPosition(), directions.l));</code></pre></figure><p>Should be the position of the square to the left of the cat.</p><h2>Stupid is fun</h2><p>Okay the array with the arrays with the characters is not a <em>great</em> way to model things, but I like using the symbols from the level format. Like this is fun:</p><figure><pre><code>console.log(level.map(x =&gt; x.join(&quot;&quot;)).join(&quot;\n&quot;));</code></pre></figure><p>But it <em>is</em> awkward having more than one symbol for one thing (it’s the player if it’s a <code>@</code> <em>or</em> a <code>+</code>, and so on). Something that takes different “collision layers” or something into account probably makes it easier to implement some things.</p><p><a href="https://llama-the-ultimate.orghttps://www.puzzlescript.net/">PuzzleScript is cool btw.</a></p><p>Also, instead of one move being a functional update of the game state or something like that, we’ll just mutate the arrays. I dunno I just think the side-effecty way to do the movement is somehow neat. And it’s fun to kind of recklessly mutate state and then trust that we can implement undo-functionality in order to restore the state we destroyed :)</p><h2>Moving one thing</h2><figure><pre><code>const levelGet = (position) =&gt; level[position.y][position.x];
const levelSet = (position, value) =&gt; level[position.y][position.x] = value;

const player = [&quot;@&quot;, &quot;+&quot;];
const box = [&quot;$&quot;, &quot;*&quot;];
const floor = [&quot; &quot;, &quot;.&quot;];

const move = (thing, from, direction) =&gt; {
  const fromIdx = thing.indexOf(levelGet(from));
  if (fromIdx &lt; 0) {
    return false;
  }
  const to = plus(from, direction);
  const toIdx = floor.indexOf(levelGet(to));
  if (toIdx &lt; 0) {
    return false;
  }
  levelSet(from, floor[fromIdx]);
  levelSet(to, thing[toIdx]);
  return true;
};

console.log(move(box, vector(3, 1), directions.l));
console.log(move(player, playerPosition(), directions.l));
console.log(move(player, playerPosition(), directions.l));
console.log(move(player, playerPosition(), directions.l));
drawLevel();</code></pre></figure><p>So I think is at least mildly stupid-clever, what with the arrays and the indexes, but kind of fun. We use <code>indexOf</code> to check if the <code>from</code>-square is the expected <code>thing</code> (player or box), and to check that the <code>to</code>-square is floor. <code>indexOf</code> also finds out if a square has a goal on it:</p><ul><li>If <code>fromIdx</code> is <code>0</code> the <code>to</code>-square has the expected <code>thing</code> and its on empty floor.</li><li>If it is <code>1</code> the square has the expected <code>thing</code> on a goal square.</li><li>If it is less than <code>0</code> the expected <code>thing</code> is not on the square and we can’t make the move.</li></ul><p>Same with <code>toIdx</code> but for floor: <code>0</code> is empty floor, <code>1</code> is goal square with nothing on it. Less than <code>0</code> means it’s blocked (wall or a floor/goal square with something on it).</p><p>And then we use those indexes to choose the correct characters for the two squares when making the moves. If the <code>to</code>-square was a goal square then we choose the “on goal” character from <code>thing</code>, and so on.</p><h2>Pushing a box</h2><p>Anyway: We attempted to move things four times. First the box near the top one move to the left. Then the player to the left, three times. The last player-move didn’t go through since the <code>to</code>-square was blocked by the box. When moving the player we want to attempt to move any box on the <code>to</code>-square first, in the same direction. Then we can add the move to the move list by checking which moves went through:</p><ul><li>If the player didn’t move, no move was made.</li><li>If the player moved and a box was moved we add the direction letter in uppercase.</li><li>If the player moved and no box was moved we add the direction letter in lowercase.</li><li>It can’t be the case that a box was moved and the player did not move. If a box was moved that must have made room for the player to make its move too.</li></ul><figure><pre><code>
const movePlayer = (directionLetter) =&gt; () =&gt; {
  const direction = directions[directionLetter];
  const position = playerPosition();
  const movedBox = move(box, plus(position, direction), direction);
  const movedPlayer = move(player, position, direction);
  if (!movedPlayer) {
    return false;
  }
  moveList += movedBox ? directionLetter.toUpperCase() : directionLetter;
  return true;
};

console.log(movePlayer(&quot;l&quot;)());
console.log(movePlayer(&quot;d&quot;)());
console.log(movePlayer(&quot;l&quot;)());
console.log(movePlayer(&quot;l&quot;)());
drawLevel();</code></pre></figure><p>The movelist says <code>LDl</code>: We pushed a box to the left, then pushed a box down, then moved to the left. (Then tried to move to the left again. But wall.)</p><h2>Controls</h2><p>That’s pretty much it for movement. If we make so we can push some buttons to call the <code>movePlayer</code> function things will be pretty gamelike:</p><figure><pre><code>const commands = new Map([
  [&quot;w&quot;, movePlayer(&quot;u&quot;)],
  [&quot;a&quot;, movePlayer(&quot;l&quot;)],
  [&quot;s&quot;, movePlayer(&quot;d&quot;)],
  [&quot;d&quot;, movePlayer(&quot;r&quot;)]
]);

const doCommand = (key) =&gt; {
  if (commands.has(key)) {
    commands.get(key)();
    drawLevel();
  }
};
canvas.tabIndex = 0;
canvas.onkeydown = event =&gt; doCommand(event.key.toLowerCase());

const button = (key) =&gt; {
  const element= outElement.appendChild(document.createElement(&quot;button&quot;));
  element.innerText = key;
  element.style.fontSize = &quot;2rem&quot;;
  element.style.width = &quot;3rem&quot;;
  element.onclick = () =&gt; doCommand(key);
};

const space = outElement.appendChild(document.createElement(&quot;div&quot;));
space.style.float = &quot;left&quot;;
space.style.height = &quot;1px&quot;;
space.style.width = &quot;3rem&quot;;
button(&quot;w&quot;);
outElement.appendChild(document.createElement(&quot;br&quot;));
&quot;asd&quot;.split(&quot;&quot;).forEach(button);</code></pre></figure><p>The <code>tabIndex</code> thing makes it so that the canvas can have focus and send <code>keydown</code> events. So you should be able to click the level and then move the cat with wasd. Also buttons. Maybe you can click on them if you don’t have a keyboard.</p><p>Can restart with <code>setLevel</code>:</p><figure><pre><code>setLevel(level1);</code></pre></figure><p>Okay that’s it for now. Boop.</p>]]></content:encoded>
    </item>
    <item>
      <title>Drawing a Sokoban level</title>
      <link>https://llama-the-ultimate.org/notes/sokoboko-gfx.html</link>
      <description>“imageSmoothingEnabled = false” is JavaScript for “tighten up”</description>
      <pubDate>Mon, 06 Feb 2023 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/sokoboko-gfx.html</guid>
      <content:encoded><![CDATA[<h1>Drawing a Sokoban level</h1><p>JavaScript is not a Lisp and a web browser is not a Lisp machine. But, you know, definitely more Lisp machiney than most of the things that <em>everyone has installed</em>. I like how alive things are in them, and how lots of fun stuff is like very within reach if you’re in one :)</p><p><a href="https://llama-the-ultimate.orghttps://en.wikipedia.org/wiki/Sokoban">Sokoban is fun stuff.</a></p><p>Anyway, this is best viewed in a browser with JavaScript enabled. You can click the play/run-buttons to run the JavaScript in the embedded editors. It should behave mostly like running the same code in the JavaScript console. (Hitting F12 or something and finding the console might also be useful if you wanna look around and inspect stuff more or something.)</p><h2>A level</h2><p><a href="https://llama-the-ultimate.orghttp://www.sokobano.de/wiki/index.php?title=Level_format">Sokoban level format.</a></p><ul><li><code>#</code> is wall</li><li>space is empty floor</li><li><code>.</code> is goal square</li><li><code>@</code> is player, or <code>+</code> if the player is on a goal square</li><li><code>$</code> is box, or <code>*</code> if the box is on a goal square</li></ul><figure><pre><code>const levelString = `
#########
#  $ @..#
# $ $   #
#  ###  #
# $     #
##  ##..#
#########
`;
const level = levelString.slice(1, -1).split(&quot;\n&quot;).map(x =&gt; x.split(&quot;&quot;));
console.log(level);</code></pre></figure><h2>Image onto a canvas</h2><p>We have a variable called <code>outElement</code> here. <code>outElement</code> is just some <code>div</code>, and like it’d also work to just do <code>document.body.appendChild(...)</code> or something, but <code>outElement</code> is automatically moved to where we’re at when we run some code:</p><figure><pre><code>const spriteSheet = outElement.appendChild(document.createElement(&quot;img&quot;));
spriteSheet.src = &quot;./../assets/soko-sprites.png&quot;
spriteSheet.alt = &quot;sprite sheet&quot;;</code></pre></figure><p>The sprite sheet is a set of 8 sprites. Each sprite is 16×16 pixels.</p><p>We’ll create a canvas and put it in the <code>outElement</code>.<br><a href="https://llama-the-ultimate.orghttps://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage">Then we can get a <code>CanvasRenderingContext2D</code> and use <code>drawImage</code> on that.</a><br>Also we turn off image smoothing because pixels. Also also, we multiply some numbers by 3, because more pixels.</p><figure><pre><code>const canvas = document.createElement(&quot;canvas&quot;);
outElement.replaceChildren(canvas);
const scale = 3;
canvas.width = spriteSheet.width  * scale;
canvas.height = spriteSheet.height * scale;
const ctx = canvas.getContext(&quot;2d&quot;);
ctx.imageSmoothingEnabled = false;

ctx.drawImage(
  spriteSheet,
  0,
  0,
  spriteSheet.width * scale,
  spriteSheet.height * scale
);</code></pre></figure><h2>Drawing one square</h2><p>We’re going to need objects with <code>x</code> and <code>y</code> properties for a bunch of stuff. First for positions of sprites. Later for positions in the level and also for directions the player can move in. We make a <code>vector</code> data structure:</p><figure><pre><code>const vector = (x, y) =&gt; ({ x: x, y: y });
console.log(vector(4, 2));</code></pre></figure><p>We’ll create an object for keeping track of where in the sprite sheet the different sprites are. Then, by passing a bunch of arguments to <code>drawImage</code> we can specify coordinates and width/height both for the part of the source image we want to draw and for the destination in the canvas. (The last 4 arguments are “destination” arguments. The ones that are multiplied by <code>scale</code>.)</p><figure><pre><code>const sprites = {
  &quot; &quot;: vector(0, 0), // top left is empty floor
  &quot;#&quot;: vector(1, 0), // top right is wall
  &quot;@&quot;: vector(0, 1), // middle left is player
  &quot;+&quot;: vector(0, 1), // same sprite for player on goal square
  &quot;$&quot;: vector(1, 1), // middle right is “box”
  &quot;.&quot;: vector(0, 2), // bottom left is goal square
  &quot;*&quot;: vector(1, 2), // middle left is “box” on a goal square
};

const drawSquare = (square, position) =&gt; {
  const sprite = sprites[square];
  ctx.drawImage(
    spriteSheet,
    sprite.x * 16,
    sprite.y * 16,
    16,
    16,
    position.x * 16 * scale,
    position.y * 16 * scale,
    16 * scale,
    16 * scale
  );
};

ctx.clearRect(0, 0, canvas.width, canvas.height);
drawSquare(&quot;@&quot;, vector(1, 2));</code></pre></figure><h2>Drawing the level</h2><figure><pre><code>canvas.width = level[0].length * 16 * scale;
canvas.height = level.length * 16 * scale;
ctx.imageSmoothingEnabled = false;
level.forEach((row, y) =&gt; row.forEach((square, x) =&gt; drawSquare(square, vector(x, y))));</code></pre></figure><p>Is level.</p>]]></content:encoded>
    </item>
    <item>
      <title>Markup for hypertext</title>
      <link>https://llama-the-ultimate.org/notes/html.html</link>
      <description>It is funny to capitalize the T in HyperText and it is funny that that’s done in “HTML.”</description>
      <pubDate>Fri, 03 Feb 2023 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/html.html</guid>
      <content:encoded><![CDATA[<h1>Markup for hypertext</h1><p>So I write posts in Glorpdown, but web browser support for Glorpdown is not spectacular. There exists a HyperText Markup Language that is sometimes used for marking up hypertext. And it is possible to convert Glorpdown to HTML and serve that instead. Many web browsers come with support for HTML :)</p><p><a href="https://llama-the-ultimate.orghttps://html.spec.whatwg.org/">HTML has a bunch of stuff in it.</a><br><a href="https://llama-the-ultimate.org/notes/glorpdown.html">Glorpdown has less stuff in it.</a><br>So when converting I get to choose which bits of HTML to use for what. I’ve learned some HTML and have ended up with something like this for now:</p><h2>HTML</h2><p>Reasonably semantic. <code>h1</code>/<code>h2</code>/<code>h3</code>, <code>p</code>, <code>ul</code> and <code>li</code>, <code>figure</code> and <code>figcaption</code>, <code>blockquote</code>, <code>em</code> and <code>code</code> and <code>pre</code>. Stuff like that. No <code>div</code>s. Almost no CSS classes. No JavaScript for pages that are basically just text content. I use JavaScript when I have actually interactive content, like editors with REPL-functionality in the lambda calculus posts.</p><p>For images I used to use an <code>img</code> tag and put any description in its <code>alt</code> attribute. Then I wanted the description to show up not just as an <em>alternative</em> to the image so I also put it in the <code>title</code> attribute. I think that was a bad idea and that a screen reader would maybe read both the <code>title</code> and the <code>alt</code>, and also <code>title</code> seems a little awkward since you often have to like go look for it by hovering over the image or something. Now I put the <code>img</code> in a <code>figure</code>, leave the <code>alt</code> empty and put the description in a <code>figcaption</code> instead.<br><a href="https://llama-the-ultimate.orghttps://stackoverflow.com/a/58468470">This “<code>alt</code> and <code>figcaption</code>”-answer seems good.</a></p><p>I <em>could</em> add stuff like <code>nav</code> and <code>main</code> and maybe <code>header</code>. I haven’t bothered with it since there’d be so little stuff outside of <code>main</code> anyway, like the <code>nav</code> would contain only the index-link. But I dunno maybe I should.</p><h2>Also CSS</h2><p>The HTML should be mostly fine on its own. It’d be nice if user style sheets were more of a thing and I could just give HTML and let it be styled according to the preferences of whoever was reading. But because circumstances, I apply some styling. I think my “philosophy” is that if I think that a piece of CSS is small and understandable and makes something look better, then okay fine. If something takes a lot of CSS and/or it feels like I’m fighting with it, then I won’t bother. I might look for an alternative solution or something, or maybe just decide that no actually I <em>want</em> it to look the way it does without additional styling.</p><p>I use one CSS <code>class</code> that I've called “page”. It sets <code>max-width</code> to 70rem, which seems to make for a line length that isn’t too bad. For the regular text content pages, I put the page-class on the <code>body</code>-element. Not styling the <code>body</code> directly here because I’m using the same CSS file for stuff like my Glorpdown editor, where I want to use more of the horizontal space (editor and preview side by side).</p><p>For everything else I use element selectors, or <code>:root</code>. Like I apply some styling to the <code>p</code>s, not to some class I’m using for my paragraphs. I used to think I should use classes for styling. I don’t remember why. Maybe it appeared to be best practice or “more flexible” or something, or maybe it was just that I though that “classes are CSS stuff.” Either way, I don’t actually want to have like five different ways to style paragraphs and it’s less noisy without the classes :)</p><p>So there’s stuff like:</p><ul><li><code>font-family: sans-serif</code>, because because.</li><li><code>max-width</code> set to <code>100%</code> for <code>img</code> to keep them within the <code>70rem</code> thing. Also I let the images be links to the themselves, so if the image is too small and you don’t want to zoom in on the page you can click the image instead.</li><li>I mostly set <code>padding</code> to <code>0</code> and use <code>margin</code> instead. My impression is that the margin collapse thing makes sense for stuff like this. (Like, I want at least <em>this</em> much space above a <code>h2</code>, but I don’t need to have it <em>in addition</em> to the empty space that I want to have under the last <code>p</code> before the heading.)</li><li>Mostly <code>rem</code>-values for margins and font sizes.</li><li>I set <code>font-size</code> for the heading-elements and for <code>pre</code>/<code>code</code>. I think code/monospace and regular text next to each other looked a bit weird before I increased the font size for the code.</li><li>I add a border to the left of <code>blockquote</code>s. I’m a bit uncertain about that choice. Feels a little extravagant. Also <code>padding</code> to the left since the the <code>padding</code> (but not the <code>margin</code>) goes between the border and the text.</li><li><code>color-scheme: light dark</code> for <code>:root:</code>. So if people want dark they get dark.</li></ul><p>I dunno. Okay.</p><p><a href="https://llama-the-ultimate.org/style.css">The CSS I’m using is here. It’s like 60-70 lines these days, which seems okay to me.</a></p><hr><p>I’ve remade this website a few times. One of the times I did that I thought I wanted to make it look good and I read some practical typography. I no longer want to make it look good. But like I guess it’s a nice book if you’re into that kind of thing:<br><a href="https://llama-the-ultimate.orghttps://practicaltypography.com/">Butterick’s Practical Typography</a><br>I mean it’s <em>probably</em> the only book on typography that has a section called “Why Racket? Why Lisp?”</p>]]></content:encoded>
    </item>
    <item>
      <title>Briefcases and libraries</title>
      <link>https://llama-the-ultimate.org/notes/briefcase-lib.html</link>
      <description>Devs should use more microfiche.</description>
      <pubDate>Wed, 25 Jan 2023 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/briefcase-lib.html</guid>
      <content:encoded><![CDATA[<h1>Briefcases and libraries</h1><blockquote><p>Each of these projects contributed its own lessons, tools and techniques. Moore carried microfiche listings of all previous projects in his briefcase, and often referred to them to get the code for some unique primitive or driver from the past. Frequently used words might become a standard fixture of the system. Also, improved techniques for solving common problems were integrated into the system.</p></blockquote><p><a href="https://llama-the-ultimate.orghttps://www.forth.com/resources/forth-programming-language/">The Evolution of Forth</a></p><p>A thing I like about Chuck Moore’s briefcase is that “briefcase” kind of sounds like it could be a metaphor of the same kind as “library.” Clearly more personal and less “published works” than a library, but you can have some pretty of useful stuff there. Maybe sets of ideas/“patterns”, tricks and techniques and ways of thinking about things. Not necessarily complete and final solutions but like, things you bring along with you because they’ve worked for you.</p>]]></content:encoded>
    </item>
    <item>
      <title>The dawn of glorp</title>
      <link>https://llama-the-ultimate.org/notes/glorpdown.html</link>
      <description>Smol markup language for blog.</description>
      <pubDate>Tue, 06 Dec 2022 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/glorpdown.html</guid>
      <content:encoded><![CDATA[<h1>The dawn of glorp</h1><p>I think Einar said that if you want to blog you should write blog posts, not write blog engine. At least sometimes people say something like that.</p><p><a href="https://llama-the-ultimate.orghttps://einarwh.wordpress.com/">Einar uses WordPress.</a><br><a href="https://llama-the-ultimate.orghttps://einarwh.wordpress.com/2011/05/12/the-indispensable-idisposable/">So when Einar writes about weird DSL for writing HTML it is typically <em>not</em> a description of how his blog works.</a></p><p>Anyway it’s a thing that makes sense. So here’s a new home-made markup language for my home-made blog engine.</p><p>I’ve played around with making my own language for this a few times. I like the idea of having something where it’s so easy to implement tooling for it that, if I ever need or want to reimplement it, maybe in a different language/environment, then that won’t be a big deal. Preferably not even much of a factor in deciding if I’m going to move to a different language or something. And also simple enough so that I can write (and read) posts in that format correctly without much help from specialized tools or something.</p><p>I tend to mess up and things tend to get too complicated.</p><h2>Gemtext</h2><p><a href="https://llama-the-ultimate.orghttps://gemini.circumlunar.space/docs/gemtext.gmi">Gemtext</a></p><p>I ran into Gemtext the other day. Gemtext takes a pretty straightforward approach to some things.</p><blockquote><p>You get one kind of list and you can't nest them</p></blockquote><p>Which goes for most things. Like generally you can’t have &lt;thing&gt; within &lt;other thing&gt;. No quote within a list, or link within a heading, or whatever. Or, it’s very line-oriented, and you can’t like, nest lines.</p><p>It’s not too hard to build a Gemtext-parser. It’s also really easy to write Gemtext in any text editor.</p><p>Also it tends to look kind of like my plaintext-notes would look anyway. E.g. I tend to end up with stuff like paragraphs being long lines and use separate lines for links.</p><p>(Also also I like how using a full line for a link tricks me into writing more self-contained link texts (instead of stuff like the link text being “here”). Which I’m told people using screen readers sometimes appreciate.)</p><h2>Glorpdown</h2><p>So I decided to steal ideas from Gemtext and make something with a lot less functionality than what I have attempted previously:</p><p><a href="https://llama-the-ultimate.org/glorpdown.html">A Glorpdown editor.</a><br><a href="https://llama-the-ultimate.org/gd/notes/glorpdown.txt">This post in Glorpdown.</a></p><p>Some basics:</p><ul><li>A line usually goes like &lt;start&gt;&lt;arguments&gt;&lt;text&gt;. The line type (typically determined by the &lt;start&gt; of the line) decides how many (whitespace-separated) arguments there are. E.g. a link (starts with <code>=&gt;</code>) has two arguments, link type and path. A blockquote has no arguments, just a <code>&gt;</code>-start followed by the text that goes in the quote.</li><li>Within the &lt;text&gt; you can format text: Text between <code>_</code>-characters is <em>emphasized</em>. Text between <code>`</code>-characters is <code>code</code>. You can’t nest/combine those things.</li><li>Within the &lt;text&gt; you can escape a character with a <code>\</code>-character. Necessary for escaping formatting characters or for having regular text lines start with the &lt;start&gt; of another line type.</li></ul><p>Most of the things:</p><h3>Regular text/paragraphs</h3><p>More or less like in Gemtext. The &lt;start&gt; of a regular text line is the empty string. Or: If the start of a line does not match the &lt;start&gt; of any of the other line types, it is a regular text. Should be empty lines between paragraphs. Line breaks within paragraphs are preserved when translating to HTML and such.</p><h3>Headings</h3><p>Same as in Gemtext, three levels: Lines that start with <code>#</code>, <code>##</code> or <code>###</code>. E.g. I do this for the following heading:</p><figure><pre><code>### Blockquotes</code></pre></figure><h3>Blockquotes</h3><p>Same as in Gemtext: Lines that start with <code>&gt;</code></p><figure><pre><code>&gt; Hello.</code></pre></figure><blockquote><p>Hello.</p></blockquote><h3>Lists</h3><p>Same as in Gemtext: Lines that start with <code>*</code> are list items.</p><figure><pre><code>* Item one
* Item two</code></pre></figure><ul><li>Item one</li><li>Item two</li></ul><h3>Linky bits</h3><p>Regular links are similar to the ones in Gemtext, but with a “type” argument before the path/url:</p><figure><pre><code>=&gt; url https://placekitten.com/ Kittens</code></pre></figure><p><a href="https://llama-the-ultimate.orghttps://placekitten.com/">Kittens</a></p><p>Unlike in Gemtext there’s a different line type for stuff that should be included in, or viewed in context of, the document. Typically images:</p><figure><pre><code>&lt;= img https://placekitten.com/200/300 A kitten!</code></pre></figure><figure><a href="https://llama-the-ultimate.orghttps://placekitten.com/200/300"><img src="https://llama-the-ultimate.orghttps://placekitten.com/200/300"></a><figcaption>A kitten!</figcaption></figure><p>(In my mind the way this makes sense is that the <code>=&gt;</code>-arrow points to some thing that you can go to, while the <code>&lt;=</code>-arrow is more like, the thing is moving into the current document.)</p><h3>Preformatted text</h3><p>Same as in Gemtext, preformatted text is turned on by a line that starts with <code>```</code>. Not like in Gemtext, any non-whitespace characters directly after the <code>```</code> are considered part of the &lt;start&gt; and must be matched by the start of a later line to turn it off again (so you can e.g. do four backticks for the &lt;start&gt; if you want to have a line of preformatted text start with three backticks without that being a “turn off the preformatted text”-line). No line types or text formatting or escaping characters within preformatted text.</p><p>So:</p><figure><pre><code>````
code here
```
not turned off yet so things are still code
````</code></pre></figure><p>Becomes:</p><figure><pre><code>code here
```
not turned off yet so things are still code</code></pre></figure><p>In Gemtext you can write some stuff after the &lt;start&gt; of a line that turns preformatted text <em>on</em> and have that be “alt text.” In Glorpdown this text is instead potentially used when rendering. E.g. for marking some preformatted text as a “repl,” so that later code can turn it into a editable textare or something.</p><p>If there’s text after the &lt;start&gt; of a line that turns preformatted text <em>off</em>, then that’s used as a caption for the preformatted text.</p><h3>Lines</h3><p>A section of preformatted text where the text after the &lt;start&gt; if the line that turns it on goes like <code>lines &lt;w h&gt;</code>.</p><p><a href="https://llama-the-ultimate.org/notes/lines.html">More lines-stuff, including an editor.</a></p><figure><pre><code>``` lines 40 36
t 33 5 oh no
l 20 14 19 8 11 8 10 14 3 18 4 21 10 20 9 31 12 31 15 24 17 30 21 31 19 20 25 21 25 17 20 14
l 13 10 13 11
l 17 10 17 11
l 14 14 16 14
l 23 11 29 8
```</code></pre></figure><figure><svg width="10em" height="9em"><style>svg {stroke: currentColor;fill: none;}text {stroke: none;dominant-baseline: middle;text-anchor: middle;fill: currentColor;}</style><text x="82.5%" y="13.88888888888889%">oh no</text>
<line x1="50%" y1="38.888888888888886%" x2="47.5%" y2="22.22222222222222%" /><line x1="47.5%" y1="22.22222222222222%" x2="27.5%" y2="22.22222222222222%" /><line x1="27.5%" y1="22.22222222222222%" x2="25%" y2="38.888888888888886%" /><line x1="25%" y1="38.888888888888886%" x2="7.5%" y2="50%" /><line x1="7.5%" y1="50%" x2="10%" y2="58.33333333333333%" /><line x1="10%" y1="58.33333333333333%" x2="25%" y2="55.55555555555556%" /><line x1="25%" y1="55.55555555555556%" x2="22.5%" y2="86.11111111111111%" /><line x1="22.5%" y1="86.11111111111111%" x2="30%" y2="86.11111111111111%" /><line x1="30%" y1="86.11111111111111%" x2="37.5%" y2="66.66666666666666%" /><line x1="37.5%" y1="66.66666666666666%" x2="42.5%" y2="83.33333333333333%" /><line x1="42.5%" y1="83.33333333333333%" x2="52.5%" y2="86.11111111111111%" /><line x1="52.5%" y1="86.11111111111111%" x2="47.5%" y2="55.55555555555556%" /><line x1="47.5%" y1="55.55555555555556%" x2="62.5%" y2="58.33333333333333%" /><line x1="62.5%" y1="58.33333333333333%" x2="62.5%" y2="47.22222222222222%" /><line x1="62.5%" y1="47.22222222222222%" x2="50%" y2="38.888888888888886%" />
<line x1="32.5%" y1="27.77777777777778%" x2="32.5%" y2="30.555555555555554%" />
<line x1="42.5%" y1="27.77777777777778%" x2="42.5%" y2="30.555555555555554%" />
<line x1="35%" y1="38.888888888888886%" x2="40%" y2="38.888888888888886%" />
<line x1="57.5%" y1="30.555555555555554%" x2="72.5%" y2="22.22222222222222%" /></svg></figure><h3>Details</h3><p>Not in gemtext. This it “toggled,” kind of like with the preformatted text. Lines that start with <code>+++</code>. The text after the first <code>+++</code> becomes the summary. The content between a first and second <code>+++</code>-line is details (the stuff you see if you click to expand or something).</p><figure><pre><code>+++ Things
* One thing
* Another thing
* A third thing
+++</code></pre></figure><details><summary>Things</summary><ul><li>One thing</li><li>Another thing</li><li>A third thing</li></ul></details><h3>Key-value pairs</h3><p>Not at all in Gemtext. Mostly for metadata. Lines that start with <code>:</code> are key-value lines. If a line goes <code>:&lt;argument&gt; &lt;text&gt;</code> then &lt;argument&gt; is the key and &lt;text&gt; is the value. E.g. this post has a line that goes:</p><figure><pre><code>:date 2022-12-06</code></pre></figure><p>And then I have some blogging machinery that uses that date for displaying list of posts with their dates.</p><h3>Horizontal rule/thematic change</h3><p>Not in Gemtext. Lines that start with <code>----</code></p><figure><pre><code>----</code></pre></figure><hr><p>Blah blah. That’s mostly it.</p>]]></content:encoded>
    </item>
    <item>
      <title>Land of some other order</title>
      <link>https://llama-the-ultimate.org/notes/order.html</link>
      <description>Order of evaluation-stuff.</description>
      <pubDate>Sun, 09 Jun 2019 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/order.html</guid>
      <content:encoded><![CDATA[<h1>Land of some other order</h1><p>We start with</p><figure><pre><code>#lang racket</code></pre></figure><p>or</p><figure><pre><code>#lang lazy</code></pre></figure><p>And make some natural and/or unnatural numbers:</p><figure><pre><code>(struct zero () #:transparent)
(struct succ (pred) #:transparent)

(define one (succ (zero)))
(define two (succ one))
(define (inf) (succ (inf)))</code></pre></figure><p>And a less-than-or-equal-to function:</p><figure><pre><code>(define (&lt;= a b)
  (cond
    [(zero? a) #t]
    [(zero? b) #f]
    [else (&lt;= (succ-pred a) (succ-pred b))]))</code></pre></figure><p>(<code>&lt;=</code> is a function with parameters <code>a</code> and <code>b</code>: If <code>a</code> is zero then true else if <code>b</code> is zero then false else try with one-less-than-<code>a</code> and one-less-than-<code>b</code> instead.)</p><p>Okay. We can try to apply the function to some arguments. The following are are fine and evaluate to <code>#t</code> and <code>#f</code>.</p><figure><pre><code>(&lt;= one two)

(&lt;= two one)</code></pre></figure><p>If we started with <code>#lang racket</code> the next two will run forever and we won’t get values back. If we started with <code>#lang lazy</code> they’re fine and evaluate to <code>#t</code> and <code>#f</code>.</p><figure><pre><code>(&lt;= two (inf))

(&lt;= (inf) two)</code></pre></figure><p>The next one will run forever in both <code>#lang racket</code> and <code>#lang lazy</code>.</p><figure><pre><code>(&lt;= (inf) (inf))</code></pre></figure><p>(Forever means until we are out of memory or something.)</p><p>Anyway. We can choose:</p><ul><li>If we want as many expressions as possible to give back values, we might prefer <code>#lang lazy</code></li><li>If we want as many applications as possible of <code>&lt;=</code> to give back values, we might prefer <code>#lang racket</code></li></ul><p>(In <code>#lang racket</code> the forever happens when evaluating the <code>(inf)</code>-arguments before the <code>&lt;=</code>-function is applied. In <code>#lang lazy</code> we might have to decide: Is it the <code>(inf)</code> or the <code>&lt;=</code> that causes forever? Is it reasonably to expect there to be a base case?)</p>]]></content:encoded>
    </item>
    <item>
      <title>A little JavaScript, a few sums</title>
      <link>https://llama-the-ultimate.org/notes/js-sums.html</link>
      <description>Tagging some unions in JS.</description>
      <pubDate>Sun, 07 Oct 2018 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/js-sums.html</guid>
      <content:encoded><![CDATA[<h1>A little JavaScript, a few sums</h1><p><a href="https://llama-the-ultimate.orghttps://gist.github.com/Glorp/4c7917ad351e1340b07b1cdeb827d62c">Standard ML code</a><br><a href="https://llama-the-ultimate.orghttps://gist.github.com/Glorp/fc614dae2d91b79c4c7d4c96785da558">JavaScript code</a><br><a href="https://llama-the-ultimate.orghttps://mitpress.mit.edu/books/little-mler">The Little MLer</a></p><p>In chapter 6 of The Little MLer there is some stuff.</p><p>There is <code>fruit</code>:</p><figure><pre><code>datatype fruit =
    Peach
  | Apple
  | Pear
  | Lemon
  | Fig</code></pre></figure><p>There is <code>tree</code>:</p><figure><pre><code>datatype tree =
    Bud
  | Flat of fruit * tree
  | Split of tree * tree</code></pre></figure><p>There is height, which looks <em>kind of</em> like this in the book:</p><figure><pre><code>(* height : tree -&gt; int *)
fun height Bud = 0
  | height (Flat(_,  t)) = 1 + height (t)
  | height (Split(s, t)) = 1 + Int.max (height(s), height(t))</code></pre></figure><p>And some other stuff that we don’t want for this. Anyway we can make a couple of trees:</p><figure><pre><code>val smol_tree = Split (Bud, Flat (Peach, Bud))
val larger_tree = Split (Flat (Apple, Flat (Lemon, Bud)), Flat (Peach, Bud))</code></pre></figure><p>And so in a REPL:</p><figure><pre><code>- height smol_tree;
val it = 2 : int

- height larger_tree;
val it = 3 : int</code></pre></figure><p>Okay.</p><hr><p>So JavaScript is a pretty nonstandard ML. If you view this in a web browser you should be able to click the play/run buttons to run the JavaScript.</p><p>In the book we use sums for the tree-stuff. Sums are also sometimes called tagged unions. We will make a <code>tag</code>-function for tagging some stuff and then try to tag something:</p><figure><pre><code>const tag = t =&gt; (...args) =&gt; ({ tag: t, values: [...args] });
console.log(tag(&quot;label&quot;)(1, &quot;horse&quot;, [2,3]));</code></pre></figure><p>Which gives us an object with <code>&quot;label&quot;</code> for its <code>tag</code> and <code>[1, &quot;horse&quot;, [2, 3]]</code> for its <code>values</code>. That is the tag and the stuff we passed in. Good. We can make constructors and some trees now:</p><figure><pre><code>// fruit constructors:
const Peach = tag(&quot;Peach&quot;)();
const Apple = tag(&quot;Apple&quot;)();
const Pear = tag(&quot;Pear&quot;)();
const Lemon = tag(&quot;Lemon&quot;)();
const Fig = tag(&quot;Fig&quot;)();

// tree constructors:
const Bud = tag(&quot;Bud&quot;)();
const Flat = tag(&quot;Flat&quot;);
const Split = tag(&quot;Split&quot;);

smol_tree = Split(Bud, Flat(Peach, Bud));
const larger_tree = Split(Flat(Apple, Flat(Lemon, Bud)), Flat(Peach, Bud));

console.log(smol_tree);</code></pre></figure><p>So we have half the sum stuff now. We can construct. We want destruct.</p><p>Okay with sums it’s like, in order to construct a value you have to do <em>one of the things</em>. A fruit is a peach <em>or</em> an apple <em>or</em> one of the other ones. In order to construct one we only have to choose one of them.</p><p>But when we’re going to destruct a value, that value can be any one of the things, so we have to know how to deal with <em>all the things</em>. We have to know what to do if it is a peach <em>and</em> we have to know what to do if it is an apple <em>and</em> so on.</p><p>So if we have a product of all the things, like maybe an object along the lines of:</p><figure><pre><code>{
  Peach: // what to do if it is a peach
  Apple: // what to do if it is an apple
  // and so on...
}</code></pre></figure><p>Then we can use the tag from the sum-thing to look up the “what to do” in the product-thing. We will make a <code>match</code>-function for destructing sums:</p><figure><pre><code>const match = cases =&gt; x =&gt; cases[x.tag](...x.values);

const is_apple =
  match(
    {
      Peach: () =&gt; false,
      Apple: () =&gt; true,
      Pear: () =&gt; false,
      Lemon: () =&gt; false,
      Fig: () =&gt; false
    }
  );

console.log(is_apple(Apple));
console.log(is_apple(Fig));</code></pre></figure><p>Gives us <code>true</code> and <code>false</code>. Seems fine.</p><p><code>height</code> then:</p><figure><pre><code>const height =
  match(
    {
      Bud: () =&gt; 0,
      Flat: (_, t) =&gt; 1 + height(t),
      Split: (a, b) =&gt; 1 + Math.max(height(a), height(b))
    }
  );

console.log(height(smol_tree));
console.log(height(larger_tree));</code></pre></figure><p>Gives us 2 and 3. Okay.</p>]]></content:encoded>
    </item>
    <item>
      <title>Manifesto for software development</title>
      <link>https://llama-the-ultimate.org/notes/manifesto.html</link>
      <description>I like smol.</description>
      <pubDate>Sat, 06 Oct 2018 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/manifesto.html</guid>
      <content:encoded><![CDATA[<h1>Manifesto for software development</h1><p>Small over large.</p><p>I value the item on the left more.</p>]]></content:encoded>
    </item>
    <item>
      <title>Church encoding is object-orientation</title>
      <link>https://llama-the-ultimate.org/notes/church-oo.html</link>
      <description>Booleans in Smalltalk are extremely Church encoded.</description>
      <pubDate>Sun, 15 Jul 2018 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/church-oo.html</guid>
      <content:encoded><![CDATA[<h1>Church encoding is object-orientation</h1><p>The central idea of traditional object-orientation is that everything is a function. The thing we can do with a function is apply it to an argument. We cannot inspect it, look into how it was constructed. Only apply.</p><p>In a traditional object-oriented language, the argument a function is applied to is a selector-and-arguments-tuple.</p><p>E.g. some Smalltalk:</p><figure><pre><code>3 + 2.
5 negated.
3 to: 10 by: 2.</code></pre></figure><p>That is:</p><ul><li><code>3</code> applied to the selector <code>+</code> and a list of arguments containing <code>2</code>.</li><li><code>5</code> applied to the selector <code>negated</code> and the empty list of arguments.</li><li><code>3</code> applied to the selector <code>to:by:</code> and a list of arguments containing <code>10</code> and <code>2</code>.</li></ul><p>There are details and there is often some cheating and pragmatism going on somewhere. But the idea is that everything is a function and we cannot “look inside” a function.</p><p>A number is a function that behaves and responds appropriately when applied to an argument. We do not care how the number is constructed. More precisely, we cannot care how the number is constructed.</p><blockquote><p>If a function walks like a number and it quacks like a number, then it must be a number.</p></blockquote><p>―Alonzo Church</p><p>(Contrast with more data-oriented languages like those in the extended ML family. Here we tend to define numbers by how they are constructed. “A natural number is zero or the successor of a natural number.” And when operating on a number we look into how it was constructed and do case analysis (typically by using pattern matching). “If it is zero, then such and such, if it is the successor of something, then this other thing instead.”)</p>]]></content:encoded>
    </item>
    <item>
      <title>The 4 types of technical debt</title>
      <link>https://llama-the-ultimate.org/notes/technical-debt.html</link>
      <description>Tech, ni, cal and debt.</description>
      <pubDate>Tue, 19 Jun 2018 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/technical-debt.html</guid>
      <content:encoded><![CDATA[<h1>The 4 types of technical debt</h1><p>I think this title is pretty thought leader because it sounds like fairly assertive and also has a number in it.</p><ul><li>Technical debt</li><li>Not technical debt</li><li>Technical not debt</li><li>Not technical not debt</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Types of functions</title>
      <link>https://llama-the-ultimate.org/notes/types-of-functions.html</link>
      <description>Functions are sometimes a useful way to think about things.</description>
      <pubDate>Sat, 09 Jun 2018 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/types-of-functions.html</guid>
      <content:encoded><![CDATA[<h1>Types of functions</h1><p>Blah. So functions are fun and for me they are often a useful way to think about programs.</p><p>And then, for me, types more or less come with the territory. A function applied to an argument can be evaluated to a result value. When I think about a function, I tend to think about things like:</p><ul><li>What do arguments I can apply this to look like?</li><li>Which expressions are likely to evaluate to things I can use as arguments?</li><li>What will results I get from applying the function look like?</li><li>Where can I use such results?</li></ul><p>And that is like, type stuff, far as I can tell.</p><p>(Which is not to say that the thinking is necessarily in terms of a type <em>system</em>, or that any of this has a thing to do with type <em>checking</em>, or anything. Just, types, okay yes.)</p>]]></content:encoded>
    </item>
    <item>
      <title>Sculpting in java.time</title>
      <link>https://llama-the-ultimate.org/notes/time.html</link>
      <description>Javadoc!</description>
      <pubDate>Sun, 21 Jan 2018 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/time.html</guid>
      <content:encoded><![CDATA[<h1>Sculpting in java.time</h1><figure><pre><code>public final class Instant
extends Object
implements Temporal, TemporalAdjuster, Comparable&lt;Instant&gt;, Serializable</code></pre></figure><p>This class models a single instantaneous point on the time-line. Time is one and undivided.</p><p>If you throw even a cursory glance into the past, at the life which lies behind you, not even recalling its most vivid moments, you are struck every time by the singularity of the events in which you took part, the unique individuality of the characters whom you met. This singularity is like the dominant note of every moment of existence; in each moment of life, the life principle itself is unique. To achieve this, the class stores a <code>long</code> representing epoch-seconds and an <code>int</code> representing nanosecond-of-second, which will always be between 0 and 999,999,999.</p><p>Life, constantly moving and changing, allows everyone to interpret and feel each separate moment in his own way; use of identity-sensitive operations (including reference equality (<code>==</code>), identity hash code, or synchronization) on instances of <code>Instant</code> may have unpredictable results and should be avoided.</p><hr><figure><pre><code>public final class Duration
extends Object
implements TemporalAmount, Comparable&lt;Duration&gt;, Serializable</code></pre></figure><p>A time-based amount of time, such as '34.5 seconds'.</p><p>This class models a quantity or amount of time in terms of seconds and nanoseconds. But I am not thinking of linear time, meaning the possibility of getting something done, performing some action. The action is a result, and what I am considering is the cause which makes man incarnate in a moral sense.</p><p>A physical duration could be of infinite length. The model is of a directed duration, meaning that the duration may be negative. It is not possible to catch the moment at which the positive goes over into its opposite, or when the negative starts moving towards the positive. Infinity is germane, inherent in the very structure.</p><hr><figure><pre><code>public abstract class Clock
extends Object</code></pre></figure><p>A clock providing access to the current instant, date and time using a time-zone.</p><p>In a certain sense the past is far more real, or at any rate more stable, more resilient than the present. The present slips and vanishes like sand between the fingers, acquiring material weight only in its recollection.</p><p>Best practice for applications is to pass a <code>Clock</code> into any method that requires the current instant.</p><hr><figure><pre><code>public class DateTimeException
extends RuntimeException</code></pre></figure><p>Time can vanish without trace in our material world for it is a subjective, spiritual category. This exception is used to indicate problems with creating, querying and manipulating date-time objects.</p>]]></content:encoded>
    </item>
    <item>
      <title>A design pattern?</title>
      <link>https://llama-the-ultimate.org/notes/lamb-design-pattern.html</link>
      <description>Datatypes and Church encody stuff with constructing and destructing things.</description>
      <pubDate>Sun, 14 Jan 2018 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/lamb-design-pattern.html</guid>
      <content:encoded><![CDATA[<h1>A design pattern?</h1><p><a href="https://llama-the-ultimate.org/notes/lambs.html">(There's a list with all the lambda notes here.)</a></p><p><a href="https://llama-the-ultimate.org/notes/lamb-succ.html">Previously we made zero and successor:</a></p><figure><pre><code>0 ≜ λf.λx.x

S ≜ λn.λf.λx.f (n f x)</code></pre></figure><p>Now there are some things. Or maybe this encourages a way of thinking about some things.</p><p>One thing is: We can think that any natural number must necessarily be built from 0 and a series of Ses. (and if want to we can think about the types of things and think that <code>0 : nat</code> and <code>S : nat -&gt; nat</code>)</p><p>Another thing is: A number like this is a function. And that function kind of is the “eliminator function” for that number. An “eliminator function” like this is similar to the foldr-function for lists: We can think of it as a function for doing “constructor replacement.”</p><p>If we have a number built from <code>S (S 0)</code>, and we wanna replace the <code>S</code>es with <code>foo</code>s and the <code>0</code> with <code>bar</code>, we can apply the number to <code>foo</code> and <code>bar</code>:</p><figure><pre><code>(S (S 0)) foo bar</code></pre></figure><hr><p>Let's say we have the numbers 2 and 3:</p><figure><pre><code>S (S 0)

S (S (S 0))</code></pre></figure><p>Reduced to normal form:</p><figure><pre><code>2 ≜ λf.λx.f (f x)

3 ≜ λf.λx.f (f (f x))</code></pre></figure><p>And let's say we want to add them together. If we want the sum, we can take the number 2 and do the “constructor replacement” thing. The number 2 is built from the <code>0</code>-constructor and 2 <code>S</code>-contructors: <code>S (S 0)</code>. We should be able to get sum by taking that number and, keeping all the <code>S</code>es, replacing the 0 with 3: <code>S (S 3)</code>.</p><p>We'll try. Taking the number 2, we replace <code>S</code> with <code>S</code>, which should let us “keep” all the <code>S</code>es, and we replace 0 with 3:</p><figure><pre><code>2 S 3</code></pre></figure><p>We get 5 :)</p><p>A bit of abstraction and we will have a +-function.</p><figure><pre><code>+ ≜ λa.λb.a S b

+ 2 3</code></pre></figure><hr><p>Or maybe we want to multiply 2 by 3.</p><p>This time the idea is that we want to replace things so that we turn the number 2, or <code>S (S 0)</code>, into <code>+ 3 (+ 3 0)</code>. We replace the <code>S</code>es with a function that adds 3 to something, and we replace 0 with 0:</p><figure><pre><code>2 (+ 3) 0</code></pre></figure><p>6!</p><p>Again, abstraction:</p><figure><pre><code>* ≜ λa.λb.a (+ b) 0

* 2 3</code></pre></figure><hr><p>(So, uh. In my experience, thinking about these things in terms of constructors and constructor replacement lets me look away from the “inner workings” of the numbers a little bit, and also make the things feel slightly more like working with datatypes in e.g. an ML dialect. It sometimes makes some things clearer to me. But like, we totally did do addition and multiplication earlier, and it’s not like the functions we did here are very different from those earlier ones. Just a little different.)</p>]]></content:encoded>
    </item>
    <item>
      <title>Successor</title>
      <link>https://llama-the-ultimate.org/notes/lamb-succ.html</link>
      <description>+1</description>
      <pubDate>Fri, 29 Dec 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/lamb-succ.html</guid>
      <content:encoded><![CDATA[<h1>Successor</h1><p><a href="https://llama-the-ultimate.org/notes/lambs.html">(There's a list with all the lambda notes here.)</a></p><p>We have made some numbers and some functions for working with numbers. Also some other datatypes.</p><p>We haven’t really done so here, but sometimes when we define numbers we fuss more about how they are constructed, about what the constructors are. We say things like: “A natural number is zero or it is the successor of a natural number.” (In a Standard ML we might say: <code>datatype nat = Zero | Succ of nat</code>)</p><p>We can do something similar but with the lambdas.</p><p>---</p><p>We already know what zero looks like:</p><figure><pre><code>0 ≜ λf.λx.x</code></pre></figure><p>We do not know that successor looks like:</p><figure><pre><code>S ≜ λn.λf.λx.f (n f x)</code></pre></figure><p>It takes a number, <code>n</code>, as its argument. <code>S</code> applied to <code>n</code> should return a number that is one larger than <code>n</code>.</p><p>(Remember: The number <code>n</code> is a function that, if given two arguments, applies the first argument <code>n</code> times to the second.)</p><p>So, <code>S</code> takes a number, <code>n</code>, as its argument, and returns one of those <code>λf.λx.</code>-functions. Within that function we do <code>n f x</code> (we apply <code>n</code> to <code>f</code> and <code>x</code>). This should amount to applying <code>f</code> “<code>n</code> times” to <code>x</code>. And then we apply <code>f</code> to the result of <code>n f x”, so that in total </code>f<code> should be applied “</code>n<code>+1 times” to </code>x<code>.</code></p><p>We can test it some and see if it looks right:</p><figure><pre><code>S 0

S (S 0)

S (S (S 0))

S (S (S (S (S 0))))</code></pre></figure><p>And like that’s it, that’s our successor. Maybe less impressive than the addition and multiplication functions we did earlier. But it’s kind of cool:</p><ul><li>We have zero-and-successor constructors. Much like the grown-ups have.</li><li>We can build any natural number with <code>0</code> and <code>S</code>. We have <code>0</code>, and we can throw <code>S</code>es at it until we have the number we really want.</li><li>Related: We kind of don’t really have to write the <code>λf.λx.</code>-bit ever again. Unless we want to. If we’re defining addition and we stick to <code>0</code> and <code>S</code>, we won’t have to do the <code>λf.λx.</code>-bit in order to construct the result-number.</li></ul><p>Will take a look at that last ting later.</p>]]></content:encoded>
    </item>
    <item>
      <title>Code Mesh and infinite llamas</title>
      <link>https://llama-the-ultimate.org/notes/mesh17.html</link>
      <description>Y combinator.</description>
      <pubDate>Wed, 08 Nov 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/mesh17.html</guid>
      <content:encoded><![CDATA[<h1>Code Mesh and infinite llamas</h1><p>Kind of a companion post for a Code Mesh talk we did:<br><a href="https://llama-the-ultimate.orghttp://www.codemesh.io/codemesh2017/jonas-winje">Infinite Lambda Calculus</a></p><p><a href="https://llama-the-ultimate.orghttps://github.com/Glorp/lambs/tree/mesh17">The code we used for the talk</a><br><a href="https://llama-the-ultimate.orghttps://github.com/Glorp/lambs/blob/mesh17/lambs/mesh.txt">The file we ended up with in the talk (it is what it is)</a></p><p><a href="https://llama-the-ultimate.org/notes/lambs.html">Also there are some lambdas over here</a></p><hr><p>Maybe the talk has a main point. Goes like this:</p><ul><li>We wanna get something like infinite, or at least pretty infinite, loops.</li><li>Lambda calculus is Turing complete, but it kind of wasn’t supposed to be?</li><li>Turing complete things can probably do infinite loops,</li><li>Type systems tend to get rid of like accidental Turing completeness.</li></ul><p>We can come up with a recipe for making a loopy thing:</p><ul><li>Look for a tiny expression that wouldn't typecheck if we had a type system-and-checker (if the type system doesn’t like an expression, then maybe that expression has something to do with Turing completeness and leads to infinite loops)</li><li>Type checkers sure don’t like <code>λx.x x</code></li><li><code>(λx.x x) (λx.x x)</code> goes on and on. Maybe for forever.</li><li>Adding e.g. <code>foo</code> like so: <code>(λx.x x) (λx.foo (x x))</code> will give us as many <code>foo</code>s as we want. Doing a few steps of evaluation will get us <code>foo (foo ((λx.foo (x x)) (λx.foo (x x))))</code>. If we do more steps we get more <code>foo</code>s.</li><li>We can do this with any <code>f</code>, instead of just with <code>foo</code>, because lambda abstraction: <code>λf.(λx.x x) (λx.f (x x))</code></li><li>One step of evaluation takes us from <code>λf.(λx.x x) (λx.f (x x))</code> to <code>λf.(λx.f (x x)) (λx.f (x x))</code></li></ul><br><p><code>λf.(λx.f (x x)) (λx.f (x x))</code> is the Y combinator :)</p>]]></content:encoded>
    </item>
    <item>
      <title>Something, foldr, sugar</title>
      <link>https://llama-the-ultimate.org/notes/foldr.html</link>
      <description>foldr and constructor replacement.</description>
      <pubDate>Fri, 04 Aug 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/foldr.html</guid>
      <content:encoded><![CDATA[<h1>Something, foldr, sugar</h1><p>I dunno. Does taking away some sugar and infixity make some things more clear?</p><p>Some Standard ML:</p><figure><pre><code>- nonfix +;
nonfix +
- + (1, 2);
val it = 3 : int
- nonfix ::;
nonfix ::
- :: (1, :: (2, :: (3, nil)));
val it = [1,2,3] : int list
- foldr + 0 (:: (1, :: (2, :: (3, nil))));
val it = 6 : int</code></pre></figure><p>(We removed the infix thing from <code>+</code> and <code>::</code> (the plus function and the list “cons”). They take tupled arguments. Infix <code>1 + 2</code> is nonfix <code>+ (1, 2)</code>, and so on.)</p><p>Here, I guess we can say that</p><figure><pre><code>foldr + 0 (:: (1, :: (2, :: (3, nil))))</code></pre></figure><p>is kind of equivalent to</p><figure><pre><code>+ (1, + (2, + (3, 0))).</code></pre></figure><p>And it is maybe more clear how</p><figure><pre><code>+ (1, + (2, + (3, 0)))</code></pre></figure><p>is similar to the list</p><figure><pre><code>0 (:: (1, :: (2, :: (3, nil)))</code></pre></figure><p>It is like the list we but with the list constructors, <code>::</code> and <code>nil</code>, replaced with <code>+</code> and <code>0</code> (the first two values we gave to <code>foldr</code>).</p><p>Also maybe unsurprising that</p><figure><pre><code>foldr :: nil (:: (1, :: (2, :: (3, nil))))</code></pre></figure><p>will be equivalent to</p><figure><pre><code>:: (1, :: (2, :: (3, nil)))</code></pre></figure><p>and evaluate to a list that looks like the one we started with?</p><hr><p>(At least, more clear than when saying that</p><figure><pre><code>foldr (op +) 0 [1, 2, 3]</code></pre></figure><p>is equivalent to</p><figure><pre><code>1 + (2 + (3 + 0))?)</code></pre></figure><hr><p>And also like maybe not I dunno.</p>]]></content:encoded>
    </item>
    <item>
      <title>Pairs</title>
      <link>https://llama-the-ultimate.org/notes/lamb-pairs.html</link>
      <description>It’s Real Programming if you can make getters.</description>
      <pubDate>Sun, 30 Jul 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/lamb-pairs.html</guid>
      <content:encoded><![CDATA[<h1>Pairs</h1><p><a href="https://llama-the-ultimate.org/notes/lambs.html">(There's a list with all the lambda notes here.)</a></p><p>Prelude. Some things we defined in earlier posts:</p><figure><pre><code>0 ≜ λf.λx.x
1 ≜ λf.λx.f x
2 ≜ λf.λx.f (f x)
+ ≜ λa.λb.λf.λx.a f (b f x)
* ≜ λa.λb.b (+ a) 0</code></pre></figure><p>We wanna make some 2-tuples, or pairs. Pairs are good for building things and we’re going to need them to build a thing reasonably soon.</p><p>A pair is a “finite ordered list” of two elements. It’s a thing with two things. Since it can’t not be, a pair is going to be a function. The way we’re going to use a pair is we’re going to apply it to an argument. And then that argument (another function) must somehow get access to the two elements that the pair is holding on to.</p><p>So: A pair should be a function that, given one function as an argument, gives its two elements to that argument-function. A pair with the elements <code>foo</code> and <code>bar</code>, then, should look like this:</p><figure><pre><code>foobarpair ≜ λf.f foo bar</code></pre></figure><p>If we give the pair an argument, that argument will go in the place of the <code>f</code> in <code>f foo bar</code>, and then <code>foo</code> and <code>bar</code> will be given to it:</p><figure><pre><code>foobarpair (λa.λb.a b quux)</code></pre></figure><p>That is, <code>λa.λb.a b quux</code> is given <code>foo</code> and <code>bar</code> as arguments from the <code>foobarpair</code>, so in the body <code>a b quux</code>, <code>a</code> and <code>b</code> are replaced with <code>foo</code> and <code>bar</code>. We can access the elements of a pair by accessing <code>a</code> and <code>b</code> within some <code>λa.λb.</code>-function that we apply the pair to.</p><p>So it looks like we have a pair that kind of works. We sometimes want other pairs than the “<code>foo</code> and <code>bar</code>” one, so we will build a constructor-function. A constructor for pairs will be a function that takes two arguments, and returns something along the lines of that <code>λf.f foo bar</code>-function. Only instead of <code>foo</code> and <code>bar</code>, we should use the two arguments we got.</p><figure><pre><code>pair ≜ λa.λb.λf.f a b

(pair foo bar) (λa.λb.a b quux)

(pair far boo) (λa.λb.a b quux)</code></pre></figure><p>And that’s really everything we need. But if we want to, for convenience, we can make a couple of “getter”-functions. We can get the first element of a pair by applying it to a two-argument function that returns its first argument:</p><figure><pre><code>foobarpair (λa.λb.a)</code></pre></figure><p>We will make a <code>fst</code>-function that will do that, but with some pair given as an argument instead of with the <code>foobarpair</code>. And a <code>snd</code>-function that does the same as <code>fst</code>, only it will use a function that returns its second argument.</p><figure><pre><code>fst ≜ λp.p (λa.λb.a)
snd ≜ λp.p (λa.λb.b)

fst foobarpair

snd foobarpair</code></pre></figure><p>Now we can do useful things. We can make a function that takes a number as an argument and like, doubles the number and squares the number, and returns a pair with the two result-numbers. And a function that takes a pair of numbers and adds those two numbers together.</p><figure><pre><code>useful-thing1 ≜ λn.pair (+ n n) (* n n)
useful-thing2 ≜ λp.+ (fst p) (snd p)
compose ≜ λf.λg.λx.f (g x)
useful-things ≜ compose useful-thing2 useful-thing1

useful-things (+ 1 2)</code></pre></figure><p>Woop.</p>]]></content:encoded>
    </item>
    <item>
      <title>Some booly functions</title>
      <link>https://llama-the-ultimate.org/notes/lamb-bools.html</link>
      <description>Business logic!</description>
      <pubDate>Thu, 27 Jul 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/lamb-bools.html</guid>
      <content:encoded><![CDATA[<h1>Some booly functions</h1><p><a href="https://llama-the-ultimate.org/notes/lambs.html">(There's a list with all the lambda notes here.)</a></p><p>Bit of prelude first.</p><p><a href="https://llama-the-ultimate.org/notes/lamb-nums.html">Some stuff from an earlier numbery post:</a></p><figure><pre><code>0 ≜ λf.λx.x
1 ≜ λf.λx.f x
2 ≜ λf.λx.f (f x)
5 ≜ λf.λx.f (f (f (f (f x))))
+ ≜ λa.λb.λf.λx.a f (b f x)</code></pre></figure><p>(And in the earlier post we said something like: The number n is a function that, if given two arguments, applies the first argument n times to the second. The +-function takes the numbers <code>a</code> and <code>b</code> as arguments and gives back a new <code>λf.λx.</code>-function that applies <code>f</code> “<code>a</code> times” to the result of applying <code>f</code> “<code>b</code> times” to <code>x</code>.)</p><p>We can do multiplication as well before moving on. Multiplication is like addition, just more. We will make a function that, if given the numbers <code>a</code> and <code>b</code> as arguments will start with the number zero, and add <code>a</code> “<code>b</code> times” to it:</p><figure><pre><code>* ≜ λa.λb.b (+ a) 0

* 5 2</code></pre></figure><hr><p>Soo. We have several numbers and also a couple of ways to make more numbers. So we pretty much have business: We can decide that one of the numbers is the number of monies and another one is the number of products. If we also have booleans we can do business logic.</p><p>Booleans are used for if-then-else. We have a stuff we maybe wanna do and another stuff we maybe wanna do instead, and we use a boolean to pick one of the stuffs. So, we would like to have a true-value and a false-value, and we wanna set things up so that something like <code>if true stuff otherstuff</code> will evaluate to <code>stuff</code>, and something like <code>if false stuff otherstuff</code> will evalute to <code>otherstuff</code>.</p><p>We will make the two boolean values be functions. (A reasonably easy choice, so long as we can only make functions in our language.) <code>true</code> will, if given two arguments, return the first one. <code>false</code>, if given two arguments, will return the second one.</p><figure><pre><code>true ≜ λa.λb.a
false ≜ λa.λb.b

true stuff otherstuff

false stuff otherstuff</code></pre></figure><p>Okay so it looks like <code>true stuff otherstuff</code> evaluates to <code>stuff</code> just fine on its own, and <code>false stuff otherstuff</code> evaluates to <code>otherstuff</code>, and we don’t really need <code>if</code>. But if we want an <code>if</code> we can have one. It can take a boolean as its first argument and then two more arguments, and then just hand those two last arguments over to the boolean.</p><figure><pre><code>if ≜ λb.λt.λe.b t e

if true stuff otherstuff

if false stuff otherstuff</code></pre></figure><p>Should get same results as with just the booleans. (If we want to, we can redefine <code>if</code> to be the identity function, <code>λx.x</code>. Will work fine.)</p><hr><p>Okay, some boolean logic bits:</p><ul><li><code>not</code> takes one boolean, <code>b</code>. If <code>b</code> is <code>true</code>, we return <code>false</code>. If <code>b</code> is <code>false</code>, we return <code>true</code>.</li><li><code>and</code> takes two booleans, <code>a</code> and <code>b</code>. If <code>a</code> is <code>true</code>, we return <code>b</code>. If <code>a</code> is <code>false</code>, we return <code>false</code>.</li><li><code>or</code> takes two booleans, <code>a</code> and <code>b</code>. If <code>a</code> is <code>true</code>, we return <code>true</code>. If <code>a</code> is <code>false</code>, we return <code>b</code>.</li></ul><figure><pre><code>not ≜ λb.if b false true
and ≜ λa.λb.if a b false
or ≜ λa.λb.if a true b

if (and (or true false) (not false)) stuff otherstuff</code></pre></figure><p>We’ll do some boolean stuff with numbers. We can check if a number is zero by giving it two arguments. The first argument is a function that always returns false: <code>λ_.false</code>. If the number is not zero this function will be applied to something and we’ll get <code>false</code> back. The second argument is <code>true</code>. If the number is zero this <code>true</code> will be returned, without any applying of the <code>λ_.false</code> function.</p><figure><pre><code>zero? ≜ λn.n (λ_.false) true

zero? 0

zero? 2</code></pre></figure><p>Good. Now we can do everyday business logic things. Like you know when boss is like hey we need a program that checks if the number of monies times the number of products is zero and if it is zero we should add five to the number of monies and if it is not zero we should multiply the number of products by 2. No problem:</p><figure><pre><code>do-business ≜ λmonies.λproducts.if (zero? (* monies products)) (+ 2 monies) (* 2 products)

do-business 2 5

do-business 2 0</code></pre></figure><p>That’s a lot of business.</p><hr><p>(Oh. If we cared about side effects or performance or something, we could worry about stuff like: Will the else-stuff be evaluated even if the boolean is true and we really only want the then-stuff? We don’t really care, since it’s going to correctly return the stuff we want either way. But if we cared: We’re evaluating things in normal order, and will give the then-stuff and the else-stuff to the boolean first, before we “step into” any of the then-stuff or else-stuff. So in the case of true the else-stuff will disappear before we do anything with it.)</p>]]></content:encoded>
    </item>
    <item>
      <title>What do the lambdas?</title>
      <link>https://llama-the-ultimate.org/notes/lamb-what.html</link>
      <description>Some lambda calculus syntax and semantics.</description>
      <pubDate>Mon, 24 Jul 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/lamb-what.html</guid>
      <content:encoded><![CDATA[<h1>What do the lambdas?</h1><p><a href="https://llama-the-ultimate.org/notes/lambs.html">(There's a list with all the lambda notes here.)</a></p><p>An expression is one of the following:</p><ul><li><code>&lt;identifier&gt;</code> (variable reference)</li><li><code>λ&lt;identifier&gt;.&lt;exp&gt;</code> (function abstraction, but sometimes we’ll just call it a lambda)</li><li><code>&lt;exp&gt; &lt;exp&gt;</code> (function application)</li></ul><p>Is like tree. Variable references are leaves. Function application branches into two sub-trees, one for function and one for argument.</p><p>Function application is left associative. So <code>a b c</code> and <code>(a b) c</code> works out the same.</p><p>For example, can take a look at expression <code>(λa.a (foo a)) bar</code> and its sub-expressions:</p><ul><li><code>(λa.a (foo a)) bar</code> is a function application with a function <code>(λa.a (foo a))</code> and an argument <code>bar</code></li><li><code>λa.a (foo a)</code> is a function abstraction with a parameter <code>x</code> and a body <code>a (foo a)</code></li><li><code>a (foo a)</code> is a function application with a function <code>a</code> and argument <code>foo a</code></li><li><code>foo a</code> is a function application with a function <code>foo</code> and argument <code>a</code></li></ul><figure><svg width="26em" height="20em"><style>svg {stroke: currentColor;fill: none;}text {stroke: none;dominant-baseline: middle;text-anchor: middle;fill: currentColor;}</style><text x="56.73076923076923%" y="10%">(application)</text>
<text x="56.73076923076923%" y="15%">(λa.a (foo a)) bar</text>
<line x1="50%" y1="18.75%" x2="34.61538461538461%" y2="27.5%" />
<text x="34.61538461538461%" y="31.25%">(abstraction)</text>
<text x="33.65384615384615%" y="36.25%">λa.a (foo a)</text>
<line x1="62.5%" y1="18.75%" x2="77.88461538461539%" y2="27.5%" />
<text x="78.84615384615385%" y="30%">(reference)</text>
<text x="78.84615384615385%" y="35%">bar</text>
<line x1="32.69230769230769%" y1="40%" x2="32.69230769230769%" y2="43.75%" />
<text x="33.65384615384615%" y="47.5%">(application)</text>
<text x="32.69230769230769%" y="53.75%">a (foo a)</text>
<line x1="27.884615384615387%" y1="57.5%" x2="17.307692307692307%" y2="61.25%" />
<text x="15.384615384615385%" y="65%">(reference)</text>
<text x="14.423076923076923%" y="70%">a</text>
<line x1="35.57692307692308%" y1="57.5%" x2="46.15384615384615%" y2="61.25%" />
<text x="49.03846153846154%" y="65%">(application)</text>
<text x="48.07692307692308%" y="70%">foo a</text>
<line x1="44.23076923076923%" y1="73.75%" x2="34.61538461538461%" y2="78.75%" />
<text x="33.65384615384615%" y="81.25%">(reference)</text>
<text x="32.69230769230769%" y="86.25%">foo</text>
<line x1="52.88461538461539%" y1="73.75%" x2="60.57692307692308%" y2="78.75%" />
<text x="62.5%" y="81.25%">(reference)</text>
<text x="63.46153846153846%" y="86.25%">a</text></svg><figcaption>Syntax tree for <code>(λa.a (foo a)) bar</code></figcaption></figure><p>(So really, syntax is mostly like in an ML family language or a Haskell or something. Only instead of like, <code>fn x =&gt; foo</code> or <code>fun x -&gt; foo</code> or <code>x -&gt; foo</code>), we do <code>λx.foo</code>. Andalso there’s never any infix stuff for function application.)</p><hr><p>Evaluation is mostly: <code>(λ𝐱.𝐁) 𝐀 ⟶ [𝐀/𝐱]𝐁</code>.</p><p>Meaning something like, a “reducible expression” (the bit to the left of the arrow) is:</p><ul><li>a function application</li><li>with a function-part that is a function abstraction, with some identifier <code>𝐱</code> as its parameter and some expression <code>𝐁</code> as its body</li><li>and with an argument-part that is some expression <code>𝐀</code></li></ul><p>And if we have a reducible expression, then we can do “beta reduction”: Substitute the argument <code>𝐀</code> for every free occurence of the parameter <code>𝐱</code> in the body <code>𝐁</code>, and replace the whole function application with the result of that.</p><p>(The part that goes <code>[𝐀/𝐱]𝐁</code> means that substitution thing: <code>𝐁</code> but with every free <code>x</code> replaced with <code>𝐀</code>. So <code>(λ𝐱.𝐁) 𝐀 ⟶ [𝐀/𝐱]𝐁</code> is a bit like a pattern match on the syntax of an expression. The expression to the left of the arrow binds the variables <code>𝐱</code> and <code>𝐁</code> and <code>𝐀</code>, and the expression to the right uses them.)</p><p>Can try. With the expression <code>(λz.z bar) foo</code>, the parameter <code>𝐱</code> is <code>z</code>, the body <code>𝐁</code> is <code>z bar</code>, and the argument <code>𝐀</code> is <code>foo</code>. So for this “instance” of <code>(λ𝐱.𝐁) 𝐀 ⟶ [𝐀/𝐱]𝐁</code> we get <code>(λz.z bar) foo ⟶ [foo/z]z bar</code>. It should evaluate to the body <code>z bar</code> with every free <code>z</code> replaced by the argument <code>foo</code>: <code>foo bar</code>.</p><figure><pre><code>(λz.z bar) foo</code></pre></figure><p>A variable reference is free if it is not bound by a parameter in a function abstraction. With the expression <code>(λz.z (λz.bar z) bar) foo</code>, the parameter <code>𝐱</code> is <code>z</code>, the body <code>𝐁</code> is <code>z (λz.bar z) bar</code>, and the argument <code>𝐀</code> is <code>foo</code>. Here, only the first <code>z</code> in the body <code>z (λz.bar z) bar</code> is free, so only that one is replaced with <code>foo</code>.</p><figure><pre><code>(λz.z (λz.bar z) bar) foo</code></pre></figure><p>(In maybe more programmy jargon, we could maybe say that the inner <code>z</code> shadows the outer.)</p><p>Sometimes we have to change the names of some variables before doing beta reduction, in order to avoid having “variable capture” change the meaning of our expression. With the expression <code>(λx.λy.y x) y</code>, the parameter <code>𝐱</code> is <code>x</code>, the body <code>𝐁</code> is <code>λy.y x</code>, and the argument <code>𝐀</code> is <code>y</code>. If we just replace the <code>x</code> in <code>λy.y x</code> with y, we get <code>λy.y y</code>. Our argument-y becomes bound (“captured”) by the parameter of the lambda within the body. Since we should be able to keep referring the outer <code>y</code>, we change the name of the parameter of the lambda (and all references to it) before we do beta reduction. (ctrl+enter two times, since the first one will just rename the parameter)</p><figure><pre><code>(λx.λy.y x) y</code></pre></figure><hr><p>That’s mostly it. We:</p><ul><li>look through our expression-tree in some order</li><li>maybe find a reducible expression</li><li>rename things if necessary</li><li>and do the substitution thing</li></ul><p>The order we look through the expression-tree is “normal order”. We check the outermost expression first, and then the function-parts of applications before the argument-parts. If we can’t find any reducible expression, then the expression is on “normal form”.</p><p>Typically we want to evaluate something down to normal form. So we run through those steps over and over until it is. (If we’re unlucky that takes actually forever. But that’s kind of fun too.)</p><p>Can do (ctrl+shift+enter) to evaluate the following until it’s on normal form:</p><figure><pre><code>(λz.z foo) (λx.λy.x bar y) quux</code></pre></figure>]]></content:encoded>
    </item>
    <item>
      <title>How do the lambdas?</title>
      <link>https://llama-the-ultimate.org/notes/lamb-how.html</link>
      <description>How to lambda on blog?</description>
      <pubDate>Wed, 12 Jul 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/lamb-how.html</guid>
      <content:encoded><![CDATA[<h1>How do the lambdas?</h1><p><a href="https://llama-the-ultimate.org/notes/lambs.html">(There's a list with all the lambda notes here.)</a></p><p>Assuming you're viewing this in a web browser with JavaScript and so on...</p><p>Some editors are readonly. Its content is evaluated when page loads or so. Mostly for adding definitions to toplevel so they can be used later in the post:</p><figure><pre><code>id ≜ λx.x
0 ≜ λf.λx.x
ω ≜ λx.x x</code></pre></figure><hr><p>In the regular editors we can do stuff.</p><figure><pre><code>(can do stuff here)</code></pre></figure><p>Normal text-editor-stuff should work. Also:</p><ul><li>ctrl+l inserts a <code>λ</code> (or you can use <code>` instead of </code>λ<code>)</code></li><li>ctrl+d inserts a <code>≜</code> (or you can use <code>:=</code> instead of <code>≜</code>)</li><li>ctrl+enter is used to add a definition to toplevel, or remove a definition, or do one step of evaluation</li><li>ctrl+shift+enter is used to do a bunch of evaluation (stops when the term is on normal form, or after a thousand steps of evaluation)</li><li>ctrl+r is used to replace the names used in toplevel definitions with terms from the definitions</li></ul><p>ctrl+enter, ctrl+shift+enter and ctrl+r all work on the line the cursor is on. Results are printed on new line(s), after. (And the cursor moves to end of result.)</p><hr><p>So, normally, if we have written some term that uses some of the toplevel defintions, we do ctrl+r and then either ctrl+enter a few times, or ctrl+shift+enter once.</p><figure><pre><code>(λa.λb.b a) 0 ω 0</code></pre></figure><p>Lines with <code>≜</code> (or <code>:=</code> are for definitons). ctrl+enter on a line that goes like &lt;identifier&gt; ≜ &lt;term&gt; adds a definition.</p><figure><pre><code>S ≜ λn.λf.λx.f (n f x)</code></pre></figure><p>(Most characters can be used in identifiers. But not whitespace ones, and not the ones that are used for other stuff: <code>:</code>, <code>`, </code>≜<code>, </code>λ<code>, </code>.<code>, </code>(<code>, </code>)<code>.)</code></p><p>The terms used in definitions can use the names of definitions that already exist. We can define <code>2</code> like this now, as long as we have defined <code>0</code> and <code>S</code> first: (ctrl+enter)</p><figure><pre><code>2 ≜ S (S 0)</code></pre></figure><p>(We can evaluate it to check that the result looks reasonably twoish. Two applications of f is very two-like, so the result should look like <code>λf.λx.f (f x)</code>. (ctrl+r, then ctrl+shift+enter))</p><figure><pre><code>2</code></pre></figure><p>If we wanna get rid of a definition we can do <code>&lt;identifier&gt; ≜</code>. We’ll remove <code>ω</code> (it’s scary): (ctrl+enter)</p><figure><pre><code>ω ≜</code></pre></figure><p>If we try to evaluate the thing we did earler, we won’t get the same result now, since <code>ω</code> will just be treated as some free variable... (ctrl+r, then ctrl+shift+enter)</p><figure><pre><code>(λa.λb.b a) 0 ω 0</code></pre></figure><hr><p>That’s more or less it. In posts like this it’s mostly enough to do ctrl+enter on definitions, and ctrl+r and then ctrl+shift+enter on other stuff...</p>]]></content:encoded>
    </item>
    <item>
      <title>Some numbery functions</title>
      <link>https://llama-the-ultimate.org/notes/lamb-nums.html</link>
      <description>Some lambda calculus.</description>
      <pubDate>Thu, 06 Jul 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/lamb-nums.html</guid>
      <content:encoded><![CDATA[<h1>Some numbery functions</h1><p><a href="https://llama-the-ultimate.org/notes/lambs.html">(There's a list with all the lambda notes here.)</a></p><p>Somewhat a test-post, for having not-dead lambda calculus within a post. If you're viewing this in a web browser and it runs the JavaScript and so on, it should be interactive.</p><p><a href="https://llama-the-ultimate.org/lambdas.html">(There’s also kind of a lambda playground over here.)</a></p><p>To try, put cursor on line below and do ctrl+enter couple of times:</p><figure><pre><code>(λx.λy.y x) bar foo</code></pre></figure><p>If it works (if the ctrl+enter-business leads to a line that goes <code>foo bar</code>), we can make a few numbers... (ctrl+enter each line).</p><figure><pre><code>0 ≜ λf.λx.x
1 ≜ λf.λx.f x
2 ≜ λf.λx.f (f x)
5 ≜ λf.λx.f (f (f (f (f x))))</code></pre></figure><p>The idea, or at least one way to look at it, is that the number five is the function that does something five times. So, if we want to <code>foo</code> a <code>bar</code> five times, then we can... (ctrl+r to replace <code>5</code> with the lambdas from the definition we did above. Then ctrl+enter a couple of times.)</p><figure><pre><code>5 foo bar</code></pre></figure><p>Which maybe evaluated to <code>foo (foo (foo (foo (foo bar))))</code>. Five <code>foo</code>s.</p><p>Okay. Addition is pretty numbery. Below is a function that takes arguments <code>a</code> and <code>b</code>, and gives back, uh, a <code>λf.λx.</code>-function. This function applies <code>f</code> to <code>x</code> and it will do that “<code>b</code> times.” And it will apply <code>f</code> to the result of that “<code>a</code> times.” Hopefully that amounts to <code>f</code> being applied  “<code>a</code> + <code>b</code> times” to <code>x</code> (ctrl+enter on line below)</p><figure><pre><code>+ ≜ λa.λb.λf.λx.a f (b f x)</code></pre></figure><p>If things seem fine so far, we can try to use it. ctrl+r on line below to replace the names of the things we’ve defined with their lambdas. Then ctrl+enter a bunch of times to evaluate. (Or ctrl+shift+enter one time.)</p><figure><pre><code>5 (+ 5 2)</code></pre></figure><p>It’s maybe twelve! (Hopefully.)</p>]]></content:encoded>
    </item>
    <item>
      <title>Solving a number problem using idiomatic LISP</title>
      <link>https://llama-the-ultimate.org/notes/LISP-forty-two.html</link>
      <description>Lisp! Parentheses!</description>
      <pubDate>Sun, 26 Mar 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/LISP-forty-two.html</guid>
      <content:encoded><![CDATA[<h1>Solving a number problem using idiomatic LISP</h1><p>Hi okay one time I ran into a number problem that went something like this: “How many (natural) numbers less than or equal to one million are there whose digits add up to forty-two?”</p><p>Okay let’s solve this using Racket. Racket is a maybe a LISP. In LISP, pretty much the only thing that matters is you have to use parentheses.</p><blockquote><p>Parentheses essentially are the basis of computation.</p></blockquote><p><a href="https://llama-the-ultimate.orghttps://www.youtube.com/watch?v=OubXOd0Twl4">―Robert Constable, 8 minutes or so into this OPLSS 2015 lecture</a></p><p>Anyway we can stare at this problem for a while and then notice three things.</p><ul><li>One thing is that the digits in one million do not add up to forty-two.</li><li>Another thing is that the numbers less than one million all have six digits (or they might as well have, and can be padded with leading zeroes).</li><li>Anothother thing is that forty-two divided by six equals seven.</li></ul><p>So. We only need to care about numbers that have six digits, and if every digit is seven they add up to forty-two. More, if the digits in a number are “balanced around seven” they also add up to forty-two. (A six can be made up for by an eight, a three by two nines, and so on.)</p><p>Okay so that’s extremely good to know. We pretty much just wanna balance stuff. And parentheses are like incredibly good things to balance.</p><hr><p>Racket comes with a read-procedure. read reads an expression from something, and it makes sure parentheses are balanced. Problem solved, then, more or less...</p><figure><pre><code>#lang racket</code></pre></figure><p>We need some halp. <code>read-string</code> will <code>read</code> a string until its end. If any parentheses are out of balance, read will throw and the <code>with-handlers-bit</code> will catch and make it so that we return the number zero. Otherwise one.</p><figure><pre><code>(define (read-string s)
  (with-handlers
      ([(λ (_) #t) (λ (_) 0)])
    (define in (open-input-string s))
    (let loop ()
      (unless (eof-object? (read in))
        (loop)))
    1))</code></pre></figure><p>Woop woop. We can use <code>read-string</code> to kind of check if a string has balanced parentheses. If we can turn numbers into strings, so that a string only has balanced parentheses in it if the digits in the number add up to forty-two, then stuff.</p><p><code>number-&gt;chars</code> will turn a number into a list of characters, maybe padded with some zeroes:</p><figure><pre><code>(define (number-&gt;chars n)
  (string-&gt;list (~a n
                    #:min-width 6
                    #:pad-string &quot;0&quot;)))</code></pre></figure><p>Now we can have one character for every digit in a number. We make a <code>char-&gt;string</code>-function that will turn a character like that into a string. The string will have parentheses that are just as much balanced as the digit was balanced around seven:</p><figure><pre><code>(define (char-&gt;string c)
  (match c
    [#\0 &quot;(((((((&quot;]
    [#\1 &quot;((((((&quot;]
    [#\2 &quot;(((((&quot;]
    [#\3 &quot;((((&quot;]
    [#\4 &quot;(((&quot;]
    [#\5 &quot;((&quot;]
    [#\6 &quot;(&quot;]
    [#\8 &quot;)&quot;]
    [#\9 &quot;))&quot;]
    [_ &quot;horses&quot;]))</code></pre></figure><p>So, in order to turn a number into a good string, we use <code>number-&gt;chars</code>, then <code>char-&gt;string</code> each digit-character. And then adjust as necessary: We will sort the characters in the string so that any left parentheses come before any right parentheses. <code>number-&gt;string</code> does:</p><figure><pre><code>(define (number-&gt;string n)
  (define char-list
    (map char-&gt;string (number-&gt;chars n)))

  (list-&gt;string
   (sort (append* (map string-&gt;list char-list))
         char&lt;?)))</code></pre></figure><p>Now all that remains is to pick the numbers we care about, then feed to <code>read-string</code> the strings we get by applying <code>number-&gt;string</code>. <code>read-string</code> should return one if things are balanced and zero if not, so if we add together all those zeroes and ones we’re good.</p><figure><pre><code>(for/sum ([n (in-range 1000000)])
  (read-string (number-&gt;string n)))</code></pre></figure><p>You can get the full program at blah. Put it into your DrRacket, press F5 or so, and voi—some 20 seconds wait—là, you will have an answer.</p>]]></content:encoded>
    </item>
    <item>
      <title>Llama the ultimate object</title>
      <link>https://llama-the-ultimate.org/notes/ltuo.html</link>
      <description>If it looks like an object, walks like an object, and spits you in the face like an object, then it probably</description>
      <pubDate>Tue, 24 Jan 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/ltuo.html</guid>
      <content:encoded><![CDATA[<h1>Llama the ultimate object</h1><p>It does extend animal.</p>]]></content:encoded>
    </item>
    <item>
      <title>Exceptions are for exceptions</title>
      <link>https://llama-the-ultimate.org/notes/exceptions.html</link>
      <description>beep boop bap</description>
      <pubDate>Mon, 02 Jan 2017 00:00:00 GMT</pubDate>
      <guid>https://llama-the-ultimate.org/notes/exceptions.html</guid>
      <content:encoded><![CDATA[<h1>Exceptions are for exceptions</h1><p>If you have like an <code>A -&gt; B</code>, then you can usually count on getting a <code>B</code> back if you pass in an <code>A</code>. In this or that language, there may be exceptions to this. For example, an exception would be an exception.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
