Matt Rickard writes short daily posts on startups, software engineering, infrastructure, and LLM tooling.
Commenters cite his posts on topics like pair programming and constrained LLM output, and one calls his regex-constraint post a good entry-level explanation.
> Automation was glued together in one of these with a series of grep, awk, sed, ls, test, commands glued together. Anything more complicated was written in C and called from one of these things.
This doesn't sound that horrific to me. It's the classic Unix approach of building small tools that do one thing well, and composing them in novel ways to solve problems. For any problem that can't be solved this way you write another small tool using your programming language of choice. Rinse and repeat.
But occasionally Unix attracts users and programmers who reject this approach, and who prefer building a monolithic tool, or in the case of Larry Wall, new programming languages. To be clear, I'm a fan of Perl and think it has its place, especially in the era it came out. It inspired many modern languages, and its impact is undeniable.
Personally, I find solutions you refer to as "unmaintainable nightmare" to be simple and elegant, if used correctly. No, you probably shouldn't abuse shell scripts to build a complex system, and beyond a certain level of complexity, a programming language is the better tool. But for most simple processing pipelines, Unix tools are perfectly capable and can be used to build maintainable solutions.
The classic Knuth-Mcllroy bout[1] comes to mind. Would you rather maintain Knuth's solution or Mcllroy's?
[1]: https://matt-rickard.com/instinct-and-culture
Yes and with relations.
In object orientated programming, there is the observer pattern and there is reactive style.
But how do you group a set of objects and run the equivalent of epoll() or select() on it when the objects state changes?
I kind of want to group a set of objects together and define a relation between them and tell them to maintain some invariant.
For example, if I wanted to implement multithreading and associate a 500 sockets per kernel thread and multiplex 1000 clients to each thread. And recv for receive threads and send for send threads. And have a pipeline of steps to process incoming messages and outgoing messages. This is a lot of code.
If I could just create a thread object and associate it with a list of sockets and tell them to send messages to eachother when to run what. Then I could use OOP to manage files, sockets, containers. Kubernetes is not really OOP but it does manage objects.
I feel the abstraction doesn't exist yet. What comes to mind is the Knuth shell script versus a low level program.
https://matt-rickard.com/instinct-and-culture
A shell pipeline is easily 1000s of lines in C.
I feel the interface to the operating system should help you write less code.
I want the messages sent between objects to be capable of reorganising the arrangement of the relations between objects themselves.
In analogy [0] to the pre- and post- ai-gen oversupply of information: In the movie The Matrix, Neo learns a martial art by importing directly to his brain. This obviously suggests demanding either high latency or efficient compression or equivalently optimal knowledge representation. Akin to what we might expect from neural interfaces like Neuralink, it suggests search through and generation of content (ai-gen or not) may not be enough. To me, it suggests a need for some kind of structured knowledge (how exactly?) world brain [1] and that of bridging hardware with the intricacies of human wetware.
Perhaps the scenario of creating a self-correcting AI is more immediate to that one of humans becoming borg-like [2] in the matrix sense.
Surely a human with infinite lifespan and mental capacity could digest all human works and have an internal mental model that could organize all the information.
[0] https://matt-rickard.com/the-low-background-steel-of-ai
[1] https://en.wikipedia.org/wiki/World_Brain
[1] https://en.wikipedia.org/wiki/Borg
Yes, it's definitely lagging the CUDA ecosystem. I did a write-up a few weeks back on the various approaches people are taking to do inference in the browser (WASM, WebGL, WebGPU): https://digest.browsertech.com/archive/browsertech-digest-the-race-to-run-inference-in/
Matt Rickard also had a short write-up recently: https://matt-rickard.com/implementing-llms-in-the-browser
My take is that we probably won't see much training done on WebGPU, because training is done upfront and it makes sense to standardize on a single GPU vendor and use an interface that can squeeze all the juice out of those GPUs (CUDA). But for inference and run-time computations, it could be very interesting to take a model trained with CUDA/PyTorch and export it (maybe with Apache TVM or tensorflow.js) into WebGPU that can run on end-user devices.
What you are looking for is Mockerfiles.
https://matt-rickard.com/building-a-new-dockerfile-frontend
It’s just a proof of concept. At least shows what can be done if one peeks under the hood a bit.
With multi stage builds you can already do quite few of the things you mention, like downloading in one container and copy into another, happening in parallel while apt install is running. It’s hopelessly verbose to do so though and one ends up with not using it and instead just brute forcing the most simple imperative file instead.
I know people that love it, but my experience has been that it usually feels like an inefficient use of time. I mostly agree with https://matt-rickard.com/against-pair-programming/ on the same site, especially this bit: 'For existing employees, pairs are often stuck at the speed of the least senior pair.'
It has a few powerful but niche use cases, particularly around mentorship (where I think asynchronous feedback is often too little, too late) and when two people are doing work that's closely intertwined.