Independent notes · Warsaw
Ideas worth carrying into the work.
Essays about software, systems, and the quiet decisions that shape what we make.
From the archive
The menu owns the clock
Weapon wheels, command menus, quick swaps, and live inventories change how much time the player has to choose, so selection UI belongs in combat pacing rather than outside it.
The type checker gets a second context
Fibre keeps principal structural types in one small algebra and moves refinements, relationships, dependent results, and generic predicates into a separate local logic.
A generic should know less
Facet treats types as bundles of observable surfaces, then compiles a generic against the exact layout, operations, families, and facts it actually uses.
Who can still wake this goroutine?
Go 1.27's goroutine leak profile turns garbage-collector reachability into a liveness test: instead of listing every sleeper, it asks whether any runnable work can still reach a way to wake it.
The object boundary is optional
Slab separates logical identity, storage bands, relationship facts, and compiler summaries so the same program structure can improve memory locality and shrink compilation work.
The facts live beside the values
Rel is a sketch of a language where ordinary values keep ordinary types while the checker carries temporary facts about how those values relate.
Defense should buy something
A successful block, parry, dodge, or dash should change the next moment by buying time, space, position, posture damage, or initiative instead of only postponing the same pressure.
A button the page cannot fake
Chrome 151's <usermedia> element makes camera and microphone permission part of a browser-controlled control, not just another JavaScript call behind a page-owned button.
The attack starts before the hit
Startup, contact, and recovery form one readable action; animation, sound, and effects should tell the player what is coming before damage asks for an answer.
The include you never wrote
libc++ 23 is removing incidental transitive includes, turning a class of mysteriously successful C++ builds into small, useful compiler errors.
Keep the threat where you left it
When enemies leave the frame, predictable positioning and layered cues preserve the player's mental map; a warning arrow cannot repair a threat that moves in ways the camera hides.
Make the type checker forget
Blot already keeps refinement facts out of algebraic subtyping. Push that separation further and functions and data structures can become local solver islands that mint generic type families, close their proofs, emit HIR, and then disappear from the checker.
Let the data structure invent its own types
If each arena can generate its own local handle type, IDs from two otherwise identical arenas stop being interchangeable before any runtime bounds check.
The cliff at 100,000
PostgreSQL 19 turns JIT off by default because the planner could price a query more reliably than the LLVM compilation a cost threshold might suddenly add.
A language made of links
A follow-up experiment: make relationships between values a first-class part of the language, then let mutation invalidate only the links it actually touches.
Lock-on schedules the crowd
Target lock changes movement, framing, and how aggressively untargeted enemies can behave, so encounter design has to decide what the lock means before tuning the crowd.
The type between the fields
Relationship types let a record state why two ordinary values belong together without turning either value into a globally indexed type.
The bug queue needs provenance
SQLite fixed enough AI-discovered bugs to headline patch releases while moving machine reports into their own forum, because maintainer attention became the scarce part of bug finding.
A waypoint is part of the level
Navigation markers change what players have to read in the world, so guidance belongs in level design instead of arriving afterward as a neutral HUD layer.
Warnings are build policy
Cargo 1.97 can deny warnings for local packages without smuggling CI policy through RUSTFLAGS into every rustc invocation.
Camera control costs a thumb
A player-controlled camera consumes input and attention, so 3D games should decide what that extra verb contributes before treating free look as a default.
The page is the work unit
Go 1.26's Green Tea garbage collector gets faster by queuing heap pages instead of individual objects, letting physical locality shape a graph traversal that used to fight the CPU.
Failure needs a short commute
When a game expects repeated failure, retry boundaries should return players to the skill they are learning unless the wider reset changes enough to make the next attempt new.
The browser should move focus
Chrome 150 turns roving tabindex into a focusgroup primitive, putting arrow-key movement, tab-stop memory, and writing-mode rules where application code has been impersonating the browser.
Recovery sets the rhythm
Recovery mechanics teach players when to press, retreat, or reset, so health and ammo systems have to reinforce the tempo a combat game claims to want.
Refs should stop being files
Git 3.0 plans to make reftable the default reference store, demoting the filesystem layout that tools have spent years mistaking for Git's branch API.
Give the enemy one job
Readable enemy roles let encounter designers build complexity through composition instead of packing every possible pressure into every unit.
The textarea can measure itself
Firefox 152 closes the last major-browser gap for CSS field-sizing, so ordinary textarea autosize handlers can give layout back to the browser.
Packages should arrive inert
npm 12 separates fetching a dependency from granting its install script permission to execute, and records that permission where a reviewer can see it.
A gazillion tokens later
Prompting becomes productive when a vague idea collapses into a small building block with a chosen quality, a reference point, a harness, and a finish line.
Numbers are sets
Numeric types become practical when they denote sets of machine integers, letting guards intersect them and arithmetic map them while successor encodings remain available for induction.
Conservative to the token
The agent harness primitives that survived the last year are the ones you can read off deprecation notices: a loop with no limits, a frozen tool set, a markdown file, and a transcript on disk.
The language lives in the prelude
Ducklang implements structs, attributes, derivation, and protocol dispatch as compile-time Duck code over a smaller set of privileged compiler operations.
The IR has a front door
Gpufuck frontends author Functional Surface objects, pack them into a versioned WebGPU transport, and receive numeric resolved Core only after GPU checking.
Let the easy fight live
Simple encounters give players room to recognize, practice, recover, and feel strong, so complexity works best as paced escalation rather than a quota every room must satisfy.
A compiler made of resumable lanes
Gpufuck turns functional-language semantics into bounded GPU state machines, batches independent programs across lanes, and reads resolved Core back to emit ordinary WebAssembly on the host.
The hinges are the product
comp0 treats accessible interaction, native form contracts, and server rendering as the durable product, leaving every visual decision to the application.
Please, sir. I’m tired.
Codex usage limits have been reset for outages, launches, milestones, cache bugs, vibes, and literal RESET week until the exception became a public ritual.
The garage, years later
Revisiting Reddit's one-person languages by age instead of debut shows what solo years actually produce: a plan to freeze, a dormant design other people keep alive, an eight-year 0.3, a line-count budget that holds, and a release routine older than Linux.
The document needs a sandbox
PDF preserves the page by making every reader parse a programmable container, infer missing semantics, and defend itself against malformed or active content.
In defense of long hallways
Quiet traversal, recovery rooms, and measured repetition give players time to predict, recover, and notice what the next burst of action will cost.
Raise another bar
When one game-development discipline outruns the rest, another week of polish buys less than a small pass on the weakest player-facing channel.
Make the game answer
A small indie scene can feel connected when one action produces immediate feedback, persistent state, a later world response, and enough quiet for the player to notice.
Combos and conversations
A game feels coherent when actions combine into readable consequences, the world answers back, and clarity and pacing give both enough room to land.
Infinity on demand
Haskell’s infinite lists are finite producers whose usefulness depends on productivity, short-circuiting consumers, fair enumeration, and forgetting prefixes the program has already used.
The thunk should be the fallback
Default laziness becomes plausible when compilers evaluate demanded work eagerly, represent common delays as inspectable data, and reserve closure thunks for the cases they cannot understand.
Bytes stop pretending to be text
ECMAScript's Base64 methods put binary conversion on Uint8Array and make callers choose how forgiving a decoder should be.
The compiler needs a test stand
Five familiar programs go into a benchmark filter and four come out labeled with how they would ruin the measurement; cmark survives, pinned to a contract.
A value can carry proof
Pattern matching on a GADT key teaches the type checker the result type, turning an unchecked registry cast into an ordinary lookup.
Evidence belongs in the result
Three programming-languages papers ask what inspectable evidence must accompany a bug report, a parallel-cost bound, or a generated test.
The call was cheaper
A controlled inline benchmark shows how disassembly and code size can explain a performance result that call-count intuition gets wrong.
The edge case has a derivation
Reducing JavaScript’s [] == ![] produces a deterministic chain of coercion rules and identifies where code should reject the default conversion.
Accessibility as creativity
Three aggressive redesigns of one event page leave its accessibility tree untouched — which is exactly what frees them to be aggressive.
A problem worth the tokens
Agent work earns its cost when the system carries a case to an externally verified result or a precise escalation.
Modules that disappear at runtime
1SubML checks modules as existential record values, then erases coercions, aliases, and identity witnesses before emitting JavaScript.
The renderer stays yours
Spirdo stops at compiled shader bytes and reflection, leaving pipeline creation, frame scheduling, and draw calls to the host renderer.
Typed shaders, visible Vulkan
vpipe’s typed triangle carries shader intent down to SPIR-V, and its particle example shows exactly where Vulkan still pokes through.
The type checker that can wait
An elaborator that can answer “not yet” keeps evaluation order from turning missing type information into false rejections.
The processor’s instruction sheet
Decoding the VisionFive 2’s RV64GC listing shows which facts describe the RISC-V instruction set and which describe the processor implementing it.
A template can say no
A useful design template records the audience, decision, hierarchy, and vetoes that make a polished output fit its task.
The tree before the pixels
An accessibility snapshot exposes the headings, labels, form, and button that a screenshot-matched checkout can lose before semantic HTML repairs them.
The page before CSS
A billing-page inventory becomes a usable hierarchy by grouping related facts, promoting the routine action, and separating destructive account changes before CSS adds polish.
The catalog dreams in i32
Guarded While reveals how a hundred distinct grammars are constrained by one small expression language and an i32 WebAssembly result.
Two kinds of control
One reproducible Rust–Odin run retires a compile-speed slogan and a runtime slogan, then traces what remains to where each language places control.
The function with a backpack
Follow one counter closure through lowering: a code pointer paired with an environment record, a lifetime decided by escape, and an optimizer trying to unpack the bag.
Someone else owns main
Roc applications hand main! to a platform that owns startup, effects, allocation, and exit — a tenancy agreement written in checked syntax.
Small compilers with sharp opinions
Axe, EDL, and Tig each commit to one opinion — parallel syntax, compile-time resources, readable C output — and stay small enough to read the commitment.
The typed shadow
Type inference keeps human source concise, while coding agents need a compiler-generated semantic shadow containing inferred types, symbol targets, and diagnostics.
Six loops finish level
A nine-profile WebAssembly rerun finds six prime loops clustering within about two percent in V8, while compiler rewrites, ABIs, and runtimes keep the rest of the table apart.
A compiler in two dispatches
A WebGPU compute shader compacts raw Brainfuck source and emits a WebAssembly module in parallel, which the host checks byte-for-byte before the browser runs it.
The nodes HVM5 skips
HVM5 appears to gain most of its advantage by keeping more program structure as static code and allocating far less of HVM4's interaction graph at runtime.
The engine stays home
Porffor points toward JavaScript at the edge by compiling each program ahead of time into Wasm while leaving the engine, parser, and optimization work at build time.
Five languages with no committee
A tour of five creator-led languages from Reddit shows that tiny languages are strongest when they pursue one rude idea and weakest when they try to become an ecosystem.
The collapse flag
Reading HVM4's single-file runtime shows the interaction calculus surviving its fourth rewrite while the machine around it quietly turns from an evaluator into a program-search engine.
Just one more IR
Compilers need several intermediate representations because each lowering stage should discard source meaning only after the analyses and transformations that depend on it have finished.
The button in the painting
WebGPU reached baseline in January and Chrome is now trialing HTML-in-canvas, so this walkthrough writes a first WGSL shader and then draws a live, clickable DOM element into the same kind of canvas.
Sixty kilobytes and a window
Writing Tetris in Grain and wrapping it in Deno's new desktop command revives the Flash-era shape of a game: a tiny compiled artifact you can play in the page or download and run in a native window.
The invisible army
Building a 251-line terminal RTS on aztecs, the Haskell ECS, uncovers a genuinely pleasant pure-world core underneath stale documentation, a scheduler that does not exist, and an optional query that is secretly mandatory.
The backend developer costume
Programmers turn languages and job titles into moral ranks because managed cloud primitives have made ordinary application backends embarrassingly small, and the resulting status theater distorts hiring, reviews, and architecture.
The mercy merge
Pity merging substitutes sympathy for evidence, moving an exhausted pull request into main before its known defects have earned approval.
Following the wire
Bend becomes understandable once its HVM output is read as an interaction-calculus wiring diagram whose independent active pairs can reduce in parallel.
The proof budget
Types are useful proofs when they encode stable, expensive invariants at compositional boundaries, while stronger proof languages trade automation and ergonomics for richer claims.
Print the path
Temporary print statements solve many bugs because they capture a rerunnable chronology with less setup than an interactive debugger.
Friction where damage starts
Developer tools prevent predictable errors when the safe path stays easy, damaging actions demand explicit intent, and escape hatches still expose the model programmers need to learn.
Functions need spaces
Snake case makes function names readable verb phrases by writing word boundaries explicitly instead of asking capitalization to impersonate punctuation.
Leave the scar visible
Workarounds need angry comments, ugly names, and explicit exit conditions so later maintainers recognize debt instead of inheriting it as design.
The locker at the corner
Poland’s parcel-locker ecosystem beats Amazon’s captive delivery model by separating where you buy from where and when you receive.
Poland in cat ears
The Polish catgirl-programmer stereotype comes from overlapping internet visibilities rather than evidence that Poland produces unusually many gender-nonconforming developers.
Types considered harmful
TypeScript becomes dangerous when you silence honest absence with plausible defaults that satisfy the shape and corrupt the meaning.
The guild and the commons
Programming-language communities place the cost of learning either on entrants or on stewards, and each choice can harden into a status system.
The route changes the road
SUMO confronted the feedback between route choice and congestion in its earliest design, then made routing and simulation correct each other through an explicit iterative toolchain.
Advice after the warning
Accessibility guidance becomes useful when reviewers separate requirements from design judgment and leave developers with a next action instead of a vague veto.
The branch predictor cannot force your thunk
Compiling a lazy functional language to WebAssembly works best when demand analysis removes thunks before lowering; branch hints can only annotate the predictable control flow left behind.
The round-trip test
Bun's Rust rewrite changed the language, implementation, review process, and security budget at once; an LLM port back to Zig would reveal which improvement came from where.
The cabinet of impossible machines
Five languages from one archived esolang repository show what happens when functions, bits, sets, a self-modifying machine description, or Peano arithmetic is forced to carry an entire program.
The future has plaque
Technological progress keeps expanding what we can do, but living systems still demand the same repetitive care every day, because maintenance is a permanent condition of the body rather than a bug waiting to be patched.
The runtime surplus
WebAssembly has an engine surplus because runtimes can compete independently while useful contracts, packages, debugging, and deployment require ecosystem agreement.
Polish does not compile
Polish makes a terrible programming language because too much of each sentence lives outside the text, in the speaker and the conversation.
Functional before runtime
Zig's comptime can compose functions and types into specialized programs while the runtime keeps allocation and control flow in plain sight.
Grain meets you halfway
Trying Grain convinced me that functional language design becomes approachable when algebraic data types feel ordinary, mutation is explicit, and WebAssembly stays a deployment detail.
Thirty-two bytes at once
In stable Rust, a practical SIMD workflow keeps the scalar loop around as the oracle for one fenced AVX2 kernel and lets the benchmark decide whether the kernel survives.
Straight to the module
Hand-written WebAssembly is a pleasure while the whole contract fits on one screen, and misery the moment it needs an ABI.
Fail where the fault lives
Fail-fast is a debugging rule about exposing faults near their cause; reliable systems contain the damage there and make recovery explicit rather than crashing broadly.
The architecture diagram shrank
Cloudflare keeps folding routing, state, durable work, browsers, containers, and AI into one programmable surface, and that compression is the real advantage.
Who the button hides
A button that promises dinner or a ride compresses another person's time and judgment into a single clickable verb.
The review needs a suspect
An LLM can catch bugs in its own patch because the first draft gives the review pass concrete evidence to inspect.
“Make no mistakes” is not a method
Telling people to make no mistakes hides the evidence a reliable system runs on; a process built to catch and repair a mistake gets closer to zero than the demand ever does.
The missing bridge
A nonsense sentence about bananas and hats shows how little the material conditional has to do with the connection English hears in the word if.
Typeclasses with the grain
Functional programming in TypeScript becomes elegant when Haskell's laws are translated through native JavaScript shapes instead of copied as foreign syntax.
The ternary hangover
AI writes nested ternaries without feeling their weight, leaving the reviewer to reconstruct control flow from punctuation.
Make evaluation visible
Haskell performance improves when you measure demand, allocation, and residency, then make evaluation and representation explicit only at proven hot paths.
Tokens for yesterday
AI spends much of its intelligence preserving documents and workflows that only exist because human coordination used to be slow.
The forty-second first draft
Disclosure Day shows what happens when 42 drafts of revision polish a screenplay without anyone reopening its premise.
The AI sheen
AI-generated images remain hard to accept because their default polish has become a visible shorthand for cheap, unconsidered work.
Beyond recursion
Recursion describes repeated structure well, but production traversal needs explicit work once depth, cycles, budgets, or cancellation matter.
Comptime behind glass
Zig's comptime is useful, but a public API generated where the editor can't see it makes the feature harder to trust.
The building block economy
Agents make integration cheap enough that small, dependable capabilities can become products in their own right.
The functional inheritance
Mainstream languages quietly inherited functional programming, and the next step is making mutation and effects visible in the types.
The compiler on the wide machine
A compiler can run on the GPU only if the language it compiles breaks the build into many small independent jobs.
Building for the second reading
A note on making software that grows clearer when people return to it.
The shape of a code block
How this journal renders code: a hand-rolled tokenizer on the server, and a copy button's worth of client JavaScript.
Browse by tag
craft43
- The menu owns the clock
- Defense should buy something
- The attack starts before the hit
- Keep the threat where you left it
- Lock-on schedules the crowd
- The bug queue needs provenance
- A waypoint is part of the level
- Camera control costs a thumb
- Failure needs a short commute
- Recovery sets the rhythm
- Give the enemy one job
- A gazillion tokens later
- Let the easy fight live
- Please, sir. I’m tired.
- In defense of long hallways
- Raise another bar
- Make the game answer
- Combos and conversations
- Evidence belongs in the result
- The edge case has a derivation
- Accessibility as creativity
- A problem worth the tokens
- A template can say no
- The tree before the pixels
- The page before CSS
- The catalog dreams in i32
- The backend developer costume
- The mercy merge
- Print the path
- Friction where damage starts
- Leave the scar visible
- Poland in cat ears
- The guild and the commons
- Advice after the warning
- The future has plaque
- Polish does not compile
- Who the button hides
- “Make no mistakes” is not a method
- The missing bridge
- The forty-second first draft
- The AI sheen
- Building for the second reading
- The shape of a code block
security1
software96
- The delay belongs in the import
- The type checker gets a second context
- A generic should know less
- Who can still wake this goroutine?
- The object boundary is optional
- The facts live beside the values
- A button the page cannot fake
- The include you never wrote
- Make the type checker forget
- Let the data structure invent its own types
- The cliff at 100,000
- A language made of links
- The type between the fields
- The bug queue needs provenance
- Warnings are build policy
- The page is the work unit
- The browser should move focus
- Refs should stop being files
- The textarea can measure itself
- Packages should arrive inert
- A gazillion tokens later
- Numbers are sets
- Conservative to the token
- The language lives in the prelude
- The IR has a front door
- A compiler made of resumable lanes
- The hinges are the product
- Please, sir. I’m tired.
- The garage, years later
- The document needs a sandbox
- Infinity on demand
- The thunk should be the fallback
- Bytes stop pretending to be text
- The compiler needs a test stand
- A value can carry proof
- Evidence belongs in the result
- The call was cheaper
- The edge case has a derivation
- A problem worth the tokens
- Modules that disappear at runtime
- The renderer stays yours
- Typed shaders, visible Vulkan
- The type checker that can wait
- The processor’s instruction sheet
- A template can say no
- The catalog dreams in i32
- Two kinds of control
- The function with a backpack
- Someone else owns main
- Small compilers with sharp opinions
- The typed shadow
- Six loops finish level
- A compiler in two dispatches
- The nodes HVM5 skips
- The engine stays home
- Five languages with no committee
- The collapse flag
- Just one more IR
- The button in the painting
- Sixty kilobytes and a window
- The invisible army
- The backend developer costume
- The mercy merge
- Following the wire
- The proof budget
- Print the path
- Friction where damage starts
- Functions need spaces
- Leave the scar visible
- The locker at the corner
- Poland in cat ears
- Types considered harmful
- The guild and the commons
- The route changes the road
- The branch predictor cannot force your thunk
- The round-trip test
- The cabinet of impossible machines
- The runtime surplus
- Polish does not compile
- Functional before runtime
- Grain meets you halfway
- Thirty-two bytes at once
- Straight to the module
- Fail where the fault lives
- The architecture diagram shrank
- The review needs a suspect
- Typeclasses with the grain
- The ternary hangover
- Make evaluation visible
- Tokens for yesterday
- Beyond recursion
- Comptime behind glass
- The building block economy
- The functional inheritance
- The compiler on the wide machine
- Building for the second reading
web19
- The browser should move focus
- The textarea can measure itself
- The hinges are the product
- The document needs a sandbox
- Bytes stop pretending to be text
- Accessibility as creativity
- The tree before the pixels
- The page before CSS
- Six loops finish level
- A compiler in two dispatches
- The engine stays home
- The button in the painting
- Sixty kilobytes and a window
- Advice after the warning
- The branch predictor cannot force your thunk
- The runtime surplus
- Straight to the module
- Who the button hides
- The shape of a code block