Abstract Nonsense

A place for musings, observations, design notes, code snippets - my thought gists.

Rust for everyone [video]

A while ago I mentioned that I thought that Rust was a fiendishly complex language at first glance. Well, that hasn’t changed. Don’t get me wrong, I love Rust, and I wish I had the time to dive deeper into it, but it has a steep learning curve.

That said, I recently came across a fantastic video, “Rust for Everyone”, presented by Will Crichton at Jane Street that explores the various tools he’s built to make Rust more accessible to newcomers. It’s not in the video description, but here’s an outline of the tools Will discusses:

  1. Aquascope: A tool that provides a visual representation of Rust’s ownership model, making it easier to understand how ownership and borrowing work in Rust.
  2. Argus: An improved Trait debugger that lets you drill down as much (or as little) as you want through a Trait type-check compiler error.
  3. Flowistry: I think this is the coolest tool here. It allows you to trace the ’effect-flow’ of your program, highlighting only the sections of code that could possibly affect a selected variable.

The font of all knowledge

TIL that Google Search has a font-based Easter Egg. If you search for “Georgia font”, the results page will change the typeface to Georgia. I initially thought it was limited to System-fonts, but Wikipedia shows that it works for Roboto too!

I discovered this when looking up various fonts for this blog. I initially specified the default browser sans-serif font in my CSS, but ended up switching to Georgia for the text-body as I find it more readable for longer posts. There are some beautiful fonts in Google Font I’d love to use, but for now I’m going to stick with the System Font Stack to avoid loading more external resources on page-load.

From Lambda Calculus to Lifelong Learning

About a decade ago, whilst meandering through a late-night Wikipedia rabbit holeSome things haven’t changed at all, I stumbled across the page for the Lambda Calculus.

A small footnote linked to An Introduction to Lambda Calculus and Scheme, a transcript of a short talk presented by Jim Larson, and, well, I fell in love. I loved the fact that there was this beautiful correspondence between foundational mathematics and models of computation; and that you could describe it through these symbolic wrappers called Lambda terms. There was something deep and abstract about it that I felt immensely drawn to.

The fact that you could start with primitive definitions like

$$ \begin{cases} \textsf{true} &= \lambda x.\lambda y.x \\ \textsf{false} &= \lambda x.\lambda y.y \end{cases} $$

and with a couple of basic reduction operations (\(\alpha\)-reduction and \(\beta\)-reduction) construct the ternary conditional:

$$ \textsf{if-then-else} = \lambda a.\lambda b.\lambda c.((a)b)c $$

just blew my mind. I’m not completely sure, but I think looking up the Y-combinator is how I ended up discovering Hacker News and began my lifelong, monotonically increasing tab-count trajectory.

Fast forward to university, and I had the pleasure of studying the Lambda Calculus in a more crystallised form, where I fell in love a second time - this time with Haskell.

And now? Well, now you’re reading this post on a blog called Abstract Nonsense, a subject of layers of abstraction, much like the calculus that inspired it.

Speaking of abstraction, if you haven’t had a chance to read the excellent post Up and Down the Ladder of Abstraction by Bret Victor, go and read it now. It’s superb.He’s even got a post on the Lambda Calculus!

The endless procrastination of meta-blogging

I came across this great piece on the act of blogging. Since I started pursuing blogging as a practice, it’s been a very rewarding experience. But my drafts and ideas list is ever growing and my output of substantive content is decreasing proportionately.

I’ve learnt a lot from the simple act of setting up my blog in the first instance: from quality learnings about internet networking through to the dreaded menagerie of tooling that frontend developers call ’the web’. But I can’t deny I spend far too much time blogging about blogging than I do actually blogging (this post is no exception).

This succinct graphic visualises the blog-metablog tragedy:

I mean to change this, I really do. I just can’t deny it’s far easier to sit down and feel productive by fixing yet-another website presentation bug than it is to actually be productive by sitting down to write quality content. This is the tyranny of meta-blogging. But good content doesn’t come without discipline and effort, and I am vowing to myself to reverse the balance.

The Illusion of ... the Illusion of Thinking

As of late there’s been a lot of thinking engendered by Apple’s The Illusion of Thinking paper.

I propose we get ahead of this sequence of paper-rebuttal-paper and define the iterated function sequence \( \{ n \ge 1: \textsf{(The Illusion of)}^{n} \textsf{(Thinking)} \} \). Whether this series of thoughts will converge to any fixed point is left as a conjecture for the reader.

A new post by Sean Godecke, commenting on a recent publication Is chain-of-thought AI reasoning a mirage? includes this incisive critique:

“LLMs construct superficial chains of logic based on learned token associations, often failing on tasks that deviate from commonsense heuristics or familiar templates Models often incorporate … irrelevant details into their reasoning, revealing a lack of sensitivity to salient information models may overthink easy problems and give up on harder ones Together, these findings suggest that LLMs are not principled reasoners but rather sophisticated simulators of reasoning-like text”

I want to tear my hair out when I read quotes like these, because all of these statements are true of human reasoners. Humans rely on heuristics and templates, include irrelevant details, overthink easy problems, and give up on hard ones all the time! The big claim in the paper - that reasoning models struggle when they’re out of domain - is true about even the strongest human reasoners as well.

Well, I think there’s a strong point here. I’m not maintaining that humans and LLMs are equally powerful at arbitrary reasoning, but reasoning is an intrinsically complex task that we might sometimes forget humans grapple intensively with too.

Writing collapsible inline footnotes in Hugo with Markdown

I use Hugo as the static site builder for my blog. I love it because it’s fast (blisteringly fast) and for the most part it just gets out of the way.

However, Hugo’s support for customising the rendering of Markdown into HTML is … lacking, to say the least. Hugo uses Goldmark under the hood, which supports Extensions, but Hugo doesn’t natively plug in to those. I’d previously been using a Hugo shortcode to wrap around some arbitrary Markdown and convert it into a footnote HTML:

<label for="fn{{ .Get "id" }}">{{ .Get "label" }}</label>
<input type="checkbox" id="fn{{ .Get "id" }}" />
<small id="fn{{ .Get "id" }}">
    {{ .Inner | markdownify }}
</small>

But using it in Markdown means writing something inordinately verbose and clunky like:

This is some text,{{< footnote id="1" label="footnote!" >}}and here's some **markdown** in a footnote{{< /footnote >}}

I considered switching to pandoc for my Markdown preprocessing, but that would mean changing my whole build system and using GitHub Actions with a pandoc workflow instead of the (super quick) Cloudflare Pages Hugo runner. I did some browsing and realised that I was not the only one thinking deeply about footnotes and sidenotes in Hugo.

I’ve been struggling with this for a while, but I realised that Hugo supports render hooks for select Markdown elements. Unfortunately, footnotes are not included, but images are! In Markdown, the standard syntax for images looks like: ![description](destination "title"), which is not too dissimilar to the footnote syntax [^label]: footnote. So I built a little layouts/_markup/render-image.html hook:

{{- if eq .Destination "fn" -}}
{{- /* This is a footnote using image syntax */ -}}
{{- $label := .PlainText | default "note" -}}
{{- $content := .Title | default "Footnote content" -}}
{{- $id := .Ordinal -}}
<label for="fn{{ $id }}" class="footnote-trigger">{{ $label }}</label><input type="checkbox" id="fn{{ $id }}" class="footnote-checkbox" /><small class="footnote-aside" id="fn{{ $id }}">{{ $content | markdownify }}</small>
{{- else -}}
{{- /* This is a regular image */ -}}
<img src="{{ .Destination | safeURL }}"
  {{- with .PlainText }} alt="{{ . }}"{{ end -}}
  {{- with .Title }} title="{{ . }}"{{ end -}}
>
{{- end -}}

so that I can write:

![fun fact](fn "_Abstract Nonsense_ is a blog about mathematics and computer science.")

and, with some pure CSS magic, have it render into a collapsible inline footnote! You can see it live on my website now: I’ve started using it to add maths proofs and asides as footnotes that expand inline on hover.