This is my waterfall model of types, for thinking about compilers and programming language design. It is clearly biased towards Haskell but useful more generally, I think. A lot of compilers may only include a few stages from this model; none of them include stage 0. Waterfall Stage 0 is what the user intends for the types to express. This is a problem because there is no way to convey this. But…
Sticking Functions Where They Donʼt Belong
What does pure data mean? and how the heck do we stick functions in there? For me, pure data means a type that does or can implement: Show , to serialize the whole internal structure. NFData , to make sure the structure is fully evaluated (forces all the lazy thunks). Aside about NFData for functions There were a few debates around whether the shallow WHNF instance for functions should be allowed…
OOP Without the Goop
OOP gets a lot of things wrong. Objects themselves are not interesting, they are usually beside the point. It is their behaviors, their interfaces, that are interesting. Even lifecycle/RAII can be decoupled from an “object” and a “class”. Iʼve been experimenting with a different approach that simply seems cleaner. Less noise, fewer inconsequential details to worry about 1 , more flexibility. More…
Everything Should Be FRP Compatible
I think FRP (Functional Reactive Programming) is great. I don’t think everything should be written in an FRP style, it has its warts, but I think all types of dynamic objects should be compatible with the philosophy, concepts, and interfaces of FRP. the basic idea is reactive values that may come with a “current” value or other form of history, and notify you when they change (if they aren’t…
Accuracy Makes Artʼs Stories Persuasive
O ne of the things I believe about art is that accuracy is rarely wasted. A couple days ago I made a piece of art that I found really satisfying, but it isnʼt quite accurate yet. I improved a lot of details: I eliminated flat colors that caught the eye, removed visible seams, added more textures and shapes to give depth to the scene, and rerendered it dozens of times to see how it was progressing.…
Thoughts about versioning,
I think versioning is one of the most important problems to deal with. Not “how do you slap version numbers on things and where do you put/distribute them”, but what do you actually do with that information. How do you deal with change ? Weʼve gotten better at dealing with change within a running system (as one example, FRP ), but dealing with change over larger timescales with less coherent…
Forms of resource acquisition
The main takeaway from this has been that instead of thinking about individual resources and their creation conditions and destructors, itʼs been more fruitful to think about it as consisting of scopes of resources, which can be destroyed when they are no longer needed. Resources only exist as destructors and wait-functions to call in the scope. This works much better since we are operating at the…
Monoids in Public
It is a weird historical quirk that Haskell/PureScript call the symmetric operation (<>) :: m -> m -> m by the name of “append”. Most of the world reserves append and prepend for the asymmetric operations shaped like List t -> t -> List t and t -> List t -> t , respectively, and call (<>) by the name of “concatenation” (literally meaning “ chaining together ”). That is pretty clearly a better…
Simple Local Nginx Config
I made this as a drop-in replacement for python3 -m http.server 8998 or the older Python 2 python -m SimpleHTTPServer 8998 , because I needed a file server that supported range requests and CORS . That is, this is a simple nginx config that serves static files from the current directory $PWD , with all the goodies that it supports out of the box: high performance, range requests, caching/ETags,…
Efficient Quapteryx Evaluator
Continued from Quapteryx Part III: Quaternary Combinators , where I was writing WASM by hand and then ported it to C and got it working. The next step was rewriting it from scratch for an efficient evaluator, and this is where I realized that having C structs and pointers (and malloc!) was really what I needed. I used walloc.c for the malloc implementation, also to keep it lightweight and WASMy.…
Quaternary Combinators
See Quapteryx Part I: On the SKI Combinator Calculus and Quapteryx Part II: Ojo: a Bitflipped Jot, and a Real Flop for introduction/background on this topic. Quaternary combinators. If binary is base 2, then quaternary is base 4. Just as binary has bits (digits) and bitstrings (sequences of digits), quaternary has crumbs and crumbstrings: By analogy with byte and nybble , a quaternary digit is…
Ojo: a Bitflipped Jot, and a Real Flop
See Quapteryx Part I: On the SKI Combinator Calculus for an introduction. Iota, Jot, Unlambda We ended with the iota combinator last time. The language Iota is just the language of the iota combinator and function application, expressed in a prefix manner: iota ::= "1" | "0" iota iota data Iota = Iota | App Iota Iota iota2SKI :: Iota -> SKI iota2SKI (App f x) = f :@ x iota2SKI Iota =…
On the SKI Combinator Calculus
For a long time Iʼve been fascinated by the idea that every number could be a program, every file could be executable. There would be no decoding errors, no bad bits or bytes, it would just interpret everything equally – regardless of whether you intended it or not, really. Sure thereʼs Gödel numberings of various systems, but they are pretty artificial, and they are usually not surjective: some…
Implementing FRP and Why
🐲 whatʼs upstream? 🌊 To explain why I wrote Riverdragon, we need to need to talk about what makes “ FRP ” Functional Reactive Programming, and the challenges that being purely functional imposes. Of course, it is not all challenges: the sequencing of effects is a boon for maintainable code, it just means that you have to be more careful and deliberate about it. The punchline of this article is…
Perfect Vector Graphics for a QR code
You would think that SVG would be a perfect medium for rendering QR codes (or other 2D matrix codes): it is perfectly scalable so the renderer can decide how best to render it at each resolution, thereʼs no need to mess around with hints like image-rendering: pixelated; , and so there should be no compromises, right? Right?? Well the quality of SVG renderers really varies, and iOS was having…
WebRTC over QR Connection Protocol
Details on the connection protocol for WebRTC over QR . How is it even possible, and how could you use it too? See there for caveats and compatibility and so on. Most notably: automatic connection only works on Chromium-based browsers and only for LAN connections. Chromium has changed and no longer allows the smol side channel . Baseline connection initiation (happy path ^^) This relies on a…
Code golf for computing a 32-byte QR code!
If you run .replaceAll(/ *(\/\/[^\n]*\n)?/g, '').replace('\\x20',' ').length on this fileʼs contents , you will see that this JavaScript comes in at 512 ASCII characters when minified! (Newlines without comments are still used as substitutes for semicolons, to keep the minified file somewhat readable. Other spaces are not important except for the one in the string.) Why would I do such a thing?…
Design your programming languages right!
I just think we should have some ground rules for new programming languages and their configuration. Yʼknow? Just some rambly thoughts on features I think you should include, or at least think about and not block yourself out of including. And other topics I am thinking about with no real answers yet. Solved problems / non-issues Indented multiline strings! Itʼs so ugly when you go to embed a…
Self-names (paths)
There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors. You know, Iʼve always heard this and been like, “Yeah, naming functions and variables is difficult, language and communication are difficult, I guess Iʼll just call it CreatePuppeteerAndChromiumInstanceOrTestingStubFactory and call it a day” 1 . However, I think the stronger problem is…
Infodumping About Selective Applicative Functors
Originally posted at https://tech.lgbt/@monoidmusician/112250458187094582 tonightʼs infodump on selective applicative functors: we know about monads, which have dynamic control flow: based on the result of a previous computation, you can invent a whole new computation to run in the chain (>>=) :: m x -> (x -> m y) -> m y this is the most flexible you can be, and it necessitates a linear order of…
Pickling Tasty Data
I want to talk about data today. In particular, I want to talk about runtime representations of data, real data – data that can be mutable and referentially opaque at runtime – and demystify what they actually are in terms of more familiar notions of data. You shouldnʼt just throw up your hands once you have cyclic references! Itʼs possible and worthwhile to design tools to work with the raw graph…
A Semiring From Any Semilattice
Iʼve been working on some theoretical aspects of programming recently. Writing new compiler optimization passes. Thinking about parsers through the lens of selective applicative functors , and tweaking them to encode exclusive choice . If you go far enough down the rabbit hole, it turns out that you want semirings for static analysis. This is not unheard of in compilers! Itʼs a really good…
TransMorphism Type Theory MetaTheory
🦋 heck u! *programs ur semicolons :3* 🦋 Iʼve been dreaming of making my own metalanguage for writing type theories for many years now. I havenʼt implemented much yet, but Iʼve been refining my ideas. Hereʼs a tiny taste: What you write: normalize:: Term -> Term ## If we are casing on a known boolean, we know which case to choose normalize: ["if" "true" "then" exprT "else" exprF] => exprT;…
Impossible Bézier Calligraphy
The story of how I implemented calligraphy for cubic Bézier curves (the kind widely used in graphics programs, especially the common Scalable Vector Graphics (SVG) format ). The problem statement: Given a pen nib of some shape, what composite shape is produced when that pen is drawn along any particular path? If the inputs are cubic Bézier curves, is the output as well? Is the Minkowski sum of two…
The Best Errors for Solving Dependency Versions
Just copy the Elm version solver from Haskell to PureScript, itʼll be easy. Uh huh. Totally. Oh we need good errors too. Yup. Thought so. 1 And so the feature creep started … but the journey was so worth it. How did I get here and what did I come up with? A novel algorithm for resolving dependency bounds to solved versions: Incorporates transitive dependency bounds for a breadth-first search: What…
Interactive Parser Explanations
I have been building this framework for explaining, analyzing, and teaching about LR(1) grammars for a couple months now. I hope to turn it into a series of interactive blog posts to explain what parsing is and some approaches we can take to it, most notably LR(1) parsing. Many notable parser generators like Haskellʼs Happy and the mainstream Yacc , Bison , and Tree-sitter use variants of LR(1),…
Eudoxus Real Numbers as Slopes of Pixelated Graphs
If you have a little background in classical constructions of the real numbers, you might have noticed that all of the usual constructions start with the rational numbers as a base, and then build up to real numbers. For example, Cauchy real numbers are constructed as sequences of rational numbers satisfying the Cauchy condition on the usual rational metric. Dedekind real numbers are constructed…
Selective Applicative Functors
I havenʼt seen a good accounting of the essence of selective applicative functors. Theyʼve been longing for a better description, to help explain what should be allowed and what should be disallowed, beyond “hey, here is a function select that seems to do useful things and enable us to write interesting code”. Selective applicative functors were originally proposed in 2019 in the paper Selective…
Quapteryx Takes Flight!
Example expressions Basics: First Second Share Simple arithmetic: 3 + 2 3 * 2 Factorial function: 4 factorial 6 factorial (slow) Infinity and beyond: Self-reducing Infinitely growing Smallest infinitely growing program Lazy: Non-strict evaluation Partial evaluation Shared evaluation? Reducing… Stop Combinators Based on https://www.angelfire.com/tx4/cus/combinator/birds.html with help from…