Skip to content

Instantly share code, notes, and snippets.

View wjlewis's full-sized avatar

William Lewis wjlewis

View GitHub Profile
@wjlewis
wjlewis / layout.py
Created October 31, 2024 12:08
A Wadler-style pretty-printer in Python
from __future__ import annotations
from dataclasses import dataclass
# + --- +
# | ASM |
# + --- +
def interpret(insts: list[AsmInst]) -> str:
def enum(**variants):
def enhance(cls):
def make_constructor(tag, sig):
def constructor(*data):
nonlocal sig
if callable(sig):
sig = sig()
if len(sig) != len(data):
raise ValueError(f"expected {len(sig)} items, not {len(data)}")
@wjlewis
wjlewis / ind.py
Created September 14, 2024 10:25
class Ind:
"""A representation of an uncertain or indeterminate value.
Ind(a, b) represents our _knowledge_ that some value lies between a and b."""
def __init__(self, lo, hi):
if lo > hi:
raise ValueError("lo must be less than or equal to hi")
self.lo = lo
self.hi = hi
class BinaryHeap {
private elements: number[] = [];
isEmpty(): boolean {
return this.elements.length === 0;
}
push(x: number) {
this.elements.push(x);
this.siftUp();
Every complex system that works started out as a simple system that worked (Gall's Law).
But I forget this every time!
It takes constant vigilance and _courage_ to make simple systems.
This is because simple systems are often slow and incomplete.
It's tempting to just jump to something more capable and more interesting,
but we do so at our own peril.
Why can't we design complex systems (that work) from scratch?

Models

In order to be useful, a map must be missing a great deal of information. This is perhaps surprising. But a map that replicated all of the features of the area in question would be identical to that region, and so it would be no more useful than the area itself. So it is with all models of reality.

While attempting to grok parsing a-la matklad, I've encountered two simple grammars. Kladov's idea—if I'm understanding it—is to generate a sequence of events during parsing, and use this to construct an actual parse tree. One way of thinking about this is that the sequence of events is itself an expression in some other (simpler) language that needs to be parsed into the final tree.

An event is either:

  • An "open" event, which marks the start of an interior syntax tree node.
  • A "close" event, which marks the end of the corresponding "open".

The Halting Problem

Many programs run for a certain amount of time and then stop, like:

def fact(n):
    if n == 0:
        return 1;
    else:
        return n * fact(n - 1)
@wjlewis
wjlewis / sendto1.md
Last active February 4, 2024 21:26
More information about `sendto`

More on sendto

I've been running into some strange bugs related to the sendto syscall. After a day or so of debugging, here's what I've learned.

I needed to fill out much more of the struct sockaddr_ll structure than I'd been doing. The man page for packet says:

When you send packets, it is enough to specify sll_family, sll_addr, sll_halen, sll_ifindex, and sll_protocol.

@wjlewis
wjlewis / random-variables.md
Last active January 19, 2024 11:11
Some quick thoughts on random variables

Random Variables

In probability we often see statements like

$$ P(X \le 4) = \frac{1}{3} $$

where $P$ is a function and $X$ is a random variable. I remember being totally confused by this as a novice: why isn't $X$ being used on the righthand side?