I miss my Amiga 500 and all those days spent playing wonderful games so much. Thank you for the hit of nostalgia.
2,227 karma · joined December 9, 2011
I built dreamcoder.ai, it's a coding harness for people tired of squinting at terminal windows and want a real UI without any compromises. It runs in your browser on your hardware. It has a tiling window manager, proper keyboard support, and oodles of quality of life features for those of us who runs dozens or hundreds of agents!
I am also the author of "Mastering Emacs" book and blog - see masteringemacs.org
I write a lot of (mostly emacs lisp) open source here:
http://github.com/mickeynp/
You can email me on mickey at semantical.co.uk.
I miss my Amiga 500 and all those days spent playing wonderful games so much. Thank you for the hit of nostalgia.
I think it's just a shift in how development works: epicycles and all that. Luckily most OOP stuff they need to know can be taught quite quickly. And perhaps not knowing about GoF is a minor win for cyclomatic complexity in your codebase :-)
If you're a Typescript developer doing React you're probably not going to reach for classes, for example, as it's just not a common paradigm in most modern React/TS codebases.
The thing that empowers first-class functions and closures (lexical binding) is the exact same method by which encapsulation works, even if the latter opts for heap vs stack. The fundamentals are the same.
Here's a simple one in Emacs Lisp:
(defmacro send (object method &rest args)
"Sends a METHOD to an OBJECT with ARGS."
`(funcall ,object ',method ,@args))
(defun make-animal (name)
;; 'hunger' is entirely private (encapsulated)
(let ((hunger 5))
;; here's our lambda using lexical binding
(lambda (method &rest args)
(cond
((eq method 'get-name) name)
((eq method 'feed)
(setq hunger (max 0 (1- hunger)))
"Yum!")
(t (error "Animal does not understand: %s" method))))))
(let ((good-boy (make-animal "Rex")))
;; "call" (via our macro) the "get-name" method; then feed. hunger does down 1.
(send good-boy get-name)
(send good-boy feed)
;; pretty-print the "object" good-boy
(pp good-boy))
;; this is the state of it after the two calls.
#[(method &rest args)
((cond ((eq method 'get-name) name)
((eq method 'feed) (setq hunger (max 0 (1- hunger))) "Yum!")
(t (error "Animal does not understand: %s" method))))
((hunger . 4) (name . "Rex"))]We're collectively shaking a lot of trees when we build frameworks, languages and tools. What works? What does not? What is the right level of abstraction? How much developer ergonomy do we want to sacrifice?
Sadly we only seem to know in hindsight what works well. But that is also how we learn and grow; it was just meant to be this way.
What people forget -- much like the design patterns in the gang of four book -- is that languages and frameworks evolve.
A decorator pattern was a niche but useful abstraction in the 1990s. In Python today you can @decorate stuff just like that. It's evolution.
The same holds for OOP. Encapsulation and co-located methods with the encapsulating slots was an incredibly powerful upgrade over basic structs. Now most languages have first-class functions and lexical scoping so you can build your own encapsulation that way.
It's all good. Just use whatever fits best.
See also my reading guide: https://www.masteringemacs.org/reading-guide
My book is of course an option also, but it costs money.
github.com/mickeynp/combobulate
Deprecating :vc + :load-path without expressing why is a curious oversight. And "portability issues" is all fine and good, but why embed custom git clone + build grammar code in the treesit.el file if VC checkout portability is a concern? Surely VC is better at it than a bunch of brittle string concat code in treesit.el I do not understand why one part works and another supposedly does not.
The change is especially infuriating as for most of us it actually worked fine, and user-lisp directory does not solve the retrieval and setup problem, which `use-package` for all its flaws at least standardises.
Most users probably do care about discoverability of related packages, existing user or not. But that's in the eye of the beholder.
`package-review-policy` is security kabuki theatre. Someone who wants to harm an Emacs user can find many other ways of doing so with or without this flag.
There is very little reason for humans to get all too engrossed in this type of work now, today, with the hope of being good enough at it to command a high salary in 3-5 years. AI can already do it incredibly well, and they can do it persistently and doggedly 24 hours a day.
There's a lot of fun "lego-style" creativity to be had in designing rooms, mobs and coming up with grand area designs.
Cool idea.
I find the notion of auteur "game developers" somewhat puzzling. I say that as someone who played, and still play, these games when they came out. Most of these guys haven't made great games in a long, long while. Obsidian's only decent game in a long while is Pentiment, and that for all intents was a passion project.
So one open weight model might "meet" Opus or whatever on benchmarks, but then fail to follow a simple answer format and also tool call correctly. The models are whipped to within an inch of their lives to strictly adhere to their post training quality gates.
[0] https://www.dreamcoder.ai -> scroll down to the event graph.
It has an event sourced architecture in SQLite and it resolves queries using recursive CTEs (and sneaky projections to speed things up) to deliver exactly that. Identical, stable message chains to AI and complete introspection.
Bonus points include a constraint-satisfaction solver for the tiling window manager so windows never shrink too small to read. And many other keyboard-friendly features.
[0] https://www.dreamcoder.ai/ [1] https://www.dreamcoder.ai/assets/graph.webp
You can see the treeview it generates in the GIFs in the link below
I wish people would blog more like in the old days.
A smart, tiling window manager with workspaces and a great tool harness. An everything app, if you may; bring the terminals, code reviews, etc. into the tool itself, and make it high fidelity: no blocky terminals for the app itself.
Back in the 90s you needed a permanent internet connection (rare!) and fast enough to handle all the usually uncompressed text, so it had to be a - shocker - T1 or better. Then you needed a server.
My old MUD has a discord; turns out a lot of the people I knew 25 years ago were there and remembered the my nick if not a little about myself back then. That was a fun nostalgia trip.
MUDs will eventually see a resurgence, I think. Mobiles with little language models to give flavour text and quests, plus a little tool calling language behind it to make it happen? I can see it working; in fact, I might just myself...
1. Use a declarative-style format for config, which is fine, I guess; 2. ... and when that inevitably fails, you... use a programming language?
Some people -- not all, but some -- may prefer to skip the first step and go straight for the second option. Particularly if it's a complex thing indeed like a build system and not, y'know, configuring your blog.