I'm interested in machine learning, distributed systems, programming languages, and entrepreneurship. I have a personal site at https://noelwelsh.com/
I'm a partner at Inner Product (http://inner-product.com) and Underscore (http://underscore.io), where I teach, mentor, and develop Scala.
I'm previously was a co-founder of a startup called Myna which applied multi-armed bandit algorithms to the problem of content optimisation -- where A/B testing is traditionally used.
Wow. Not a Haskell user, but a big user of other languages with expressive type systems (mostly Scala; some Rust). My experience is the complete opposite. I can't imagine using a language without a good type system to catch all the junk the LLM produces. In fact I thought people would move away from languages from poor type systems, like Python, given the cost of using languages with expressive type systems has decreased with LLMs.
This is the book I'm working on about mental models for better code. It's getting very close to complete, and there is a 150 page free sample.
The book is all about making explicit the structure in code, and the structure in the process of creating code, and using the structure to produce code more effectively. In more academic jargon, it's about metacognitive strategies.
That's a reasonable way of looking at it, but capabilities are not restricted to low-level system properties. Here's a terminal UI system built around three main capabilities:
- layout (adding components to the component tree)
- event (handling user input events)
- react (reacting to changes in reactive values)
You're right, they are related. One difference is simply lineage. Capabilities come out of the erights / security world (e.g. [0]), while dependency injection comes from the XP / agile / Martin Fowler world. More interesting is that to do capabilities correctly you need some type system extensions, namely capture checking. Essentially, this means you delimit where a program can hold a reference to a value derived from a capability. So if you have a function that allocates memory, you can say "there are no references to any allocated memory outside this function call" and hence no use-after-free bugs. It gives a form of resource management that is simpler than Rust's lifetimes. See [1] and [2]. (Technically it's a modal type system versus Rust's substructural type system.) To my mind it's an obvious thing for Zig to add.
Shameless plug. If you're interested in more on this, for a programmer's rather than academic perspective, this is going into my book [3]. I'm writing the chapter of capability passing right now.
What Zig is doing is called "capability passing". I don't know if the Zig team is aware of this field of work, or have independently arrived upon it, but that's what is achieved by passing IO, memory allocators, and other stuff around.
The core idea is that you create a "capability" for any action you want to track, such as using IO, allocating memory, or in your example making cross core or cross server calls. Now to perform these actions code has to have access to the capability. It's a very simple, but powerful, model.
The Effekt language formalizes this, and adds safety properties: https://effekt-lang.org/ Scala 3 also has this.
The papers are pretty readable, if you ignore the middle bits which go into the formal models.
Exactly. I don't understand why people think the ternary operator is needed when you can just make `if` an expression instead of a statement. Then there is no new syntax to learn and `if` just becomes more useful.
The "shovels for gold miners" analogy is generally a good one. It applies to Nvidia, for example. It doesn't generally apply to developers though. Developer tooling is notoriously difficult to monetize. Developers themselves are a shovel.
* The core idea sounds interesting. Make it the first paragraph, not paragraph seven.
* Spend more words describing what makes Oak different.
* "I built a version control system in my free-time called Jam". You probably didn't name your free time. "I built a version control system, called Jam, in my free time."
I'm currently writing up what is the last major chapter, which introduces capability-passing as an architecture, and builds a simple TUI framework using it. Fun stuff!
I'm a few months away from launching the book, but the early feedback is very positive. I find writing enjoyable but also, damn, do I need to get this book finished. :-)
The biggest problem Emacs has will not be solved by blog posts like this. For most people the editor is a means to an end. They are invested in their end goal, not in hunting down blog posts telling them how to make better use of their tools. If Emacs wants wider adoption is needs a better out-of-the-box experience, which is something that distros like Doom Emacs and Spacemacs offer. That's the only way to make a dent: when people boot it up it has to have the good stuff right in their face. This also means ditching the "vanilla Emacs only" snobbery.
That said, I'm the kind of person to invest time in my editor and I appreciate this post.
I've used Doom Emacs for years and it rarely breaks. Sometimes things get out of sync, and I delete the git repo and clone it again. That happens once every few years.
People holding your attitude is one thing that keeps people away from Emacs. Very few people want to get into the weeds of customizing their editor. They want to do whatever it is they are interested in and the editor is tool to get it done. Doom Emacs, and other approachable "distributions" are the way to make the power of Emacs accessible.
I wish people would describe in more detail the tasks they use LLMs to code. My experience is that simple components in an existing architecture are fine, but anything requiring architectural considerations quickly becomes a mess. On my projects (e.g. a ui framework), running multiple agents in parallel would just increase the speed at which it can stuff up the project.
But really this is something you should search up yourself to follow your particular interests + constraints.
I've worked with people from Ada. Some were slackers, but the people I worked with directly were great. They were still studying, so not very experienced but keen to learn and improve. Very applied / practical focus, which has advantages and drawbacks.
I love this. (I probably won't use it as these days I'm a Doom Emacs user and don't want to monkey around with my setup too much, but the concept is great.)
The guy's whole website is also worth clicking around. A huge amount of effort.
Equipping cats and dogs with talking buttons (see, for example, https://www.youtube.com/playlist?list=PLBh-BXgsO9IjhN-thTLvm... or https://www.youtube.com/@floundercat) has shown me there is a lot more going in their little heads than I suspected. There are examples of cats describing their dreams, or worrying about what will happen in the future, or theorizing about the nature of the world (in a very naive way).
Birds have higher neural density than mammals (https://www.pnas.org/doi/10.1073/pnas.1517131113) so can pack a lot into their tiny heads. I do wonder what they'd have to say, if given the chance.
When I read up, it sounded like the same idea as work-stealing to me. Not surprising that different fields come up with the same idea under different terminology.
Very brief. I'm not sure what this adds over reading the language documentation (which itself is not great). As it's entirely organized by language features it doesn't really talk about any larger scale design decisions, which is where I think language proficiency is really found.
I'm a partner at Inner Product (http://inner-product.com) and Underscore (http://underscore.io), where I teach, mentor, and develop Scala.
I'm previously was a co-founder of a startup called Myna which applied multi-armed bandit algorithms to the problem of content optimisation -- where A/B testing is traditionally used.