Form HR-1099-RAT · Exit Interview · economic status: locked in Permanent Underclass
HN user
adityaathalye
Just another Human General Intelligence.
https://www.evalapply.org/about.html#standing-invitation
(In the tradition of HN denizens like sivers and patio11.)
mailto: safe.tent3152@fastmail.com
Places I feel Inspired
I am happiest when walking in snow. Being enveloped in fog and cold mountains allow me a chance to become invisible. Iceland, Alaska, Tuscany and California are my current inspirations.
Man I hope you are there now, happiest this way, in the "Big Later".
A sad day for us who learn of his passing. I hope it was painless and peaceful, as befits a person who gave so freely of himself. His collected body of work is a trustworthy chronicle of the Internet and the WWW's glow up era. It will inform generations to come. They will know Om too.
And through the same work, he remains alive to us; we who sought his dogged, prodigious, plain speaking influence, insight, and direct access to the beating heart of the place where it was all being invented and grown and scaled and blown up and resurrected.
Om's writing brought the excitement and possibility of the world to me, circa 2004. A 25-something B-school student, in faraway Pune, India, viscerally experiencing and studying the telecom boom at home, while also looking towards The Valley to see what might come to be, next.
I read him on GigaOm, and his various other later avatars / manifestations, but he is always going to be "Om Malik on Broadband" for me. As he will be for many of my cohort.
GigaOm is dead, long live GigaOm.com.
(´˘-˘人)Came here to say the same thing... A "building-sized financial product that incentivises extend and pretend" is fertile ground for an organised player like wework to "lease and sublet, except on a subscription basis".
viz. wework could apply the "single-use low-priced shampoo sachet" model [0] to SaaS-style rent-seeking of long-lived infrastructure. Infra. that is guaranteed to be always under-utilised... even in boom markets, because nothing functions at 100% capacity.
Adobe, as another example of (software) infrastructure --- i.e. traditionally, lifetime licence and ownership desktop software --- figured out their own "shampoo sachet" pricing. viz. how to make and ship desktop software product but kill-switch them with metered SaaS subscriptions.
The monthly price is just high enough to make gobs of cash for Adobe, while causing the typically-feast-and-famine freelancer to take the capitalist shellacking because it's just convenient enough. They can align software spends with active projects, and avoid the anxiety of cracked software doing nefarious things to their computers and data.
But over a long enough time, they pay Adobe a (presumably) huge premium over up-front priced software. And they stay locked into a planned obsolescence cycle controlled by Adobe... "The new version of your beloved editing software will only work with the latest Windoze which means hardware upgrade and oh, you have to do it because well we are soon kill-switching the current version you are dependent on."
Wework like operators can do exactly similar shenanigans with access to commercial infrastructure. Crowd out competition by aggressive long-term leasing on their buy-side, and on their sell-side build daily-subscription-dependency (buying ease, google-ish facilities which feeds into cult-and-status-signalling games), and convert a percentage of that into routine-subscription-dependency. Meanwhile also run rent-seeking games inside the main rent-seeking game... now you have a captive wallets who will buy the add-ons and extras because it's easier than walking two blocks for some cheaper and better alternative (e.g. food, coffee, lovely meeting space etc.).
edit: add reference for "daily sachet pricing".
[0] Buying less, more often: An evaluation of sachet marketing strategy in an emerging market
https://www.researchgate.net/publication/233676293_Buying_le...
PSA: glojure maintenance has moved here: https://github.com/gloathub/glojure
Worth changing the submit URL to this one?
Edit: never mind. Spoke too soon. Ingy is keeping gloathub/glojure fork and glojurelang/glojure source at parity.
Jank, a Clojure dialect, is playing in the same field:
Where jank differs from Clojure JVM is that its host is C++ on top of an LLVM-based JIT. This allows jank to offer the same benefits of REPL-based development while being able to seamlessly reach into the native world and compete seriously with JVM's performance.
Work is being furthered by Ingy döt Net [0] (Creator of Gloat, YAML, YAMLScript, and other stuff), supported by a Clojurists Together grant [1].
[0] https://gloathub.org/blog/2026/06/16/gloat-q2-grant-halfway-...
We are halfway through the Q2 2026 Clojurists Together funding cycle, so this is a good time to report what has been done for Gloat and Glojure.
...
Since the start of the grant period, Gloat and Glojure have had over 20 releases, with Gloat moving from v0.1.26 to v0.1.50. The Glojure work was all being done on the long running fork gloathub/glojure, but I'm thrilled to announce that as of today, the work has been fully moved back to the upstream glojurelang/glojure and will continue to be maintained and released from there.
My overall ambition for Gloat is to have Clojure be as full featured and prominent to Go programming as it is to Java. The industry is crazy about Go. Let's get it crazy about Clojure.
[1] https://www.clojuriststogether.org/projects/#Gloat:~:text=Ma...
Make Gloat/Glojure binaries smaller and faster. Pass more of the Clojure Compatibility Test Suite. Create tutorial docs on: How to use Gloat to integrate Clojure into Go projects and How to use Gloat instead of GraalVM to (cross-)compile Clojure.
Hey, I do this too, and I absolutely love receiving thoughtful e-letters, the few times a year they happen!
Here are my reasons, copied from my site's "Standing Invitation" [0].
Email me just because (not just for work). Whatever feeds your curiosity; silly, fun, nerdy, serious.
Why?
1. Do unto me what I have done unto others. I habitually cold-email anyone who moves me in some way (joy, insight, utility, mind shift…). I also love to receive such email!
2. There is too little unsolicited positive feedback in much of most of our lives. At some point in the fuzzy past, I decided enough was enough. At least someone somewhere ought to feel good sometime for no reason whatsoever. Since that realisation, I have cold-emailed people willy-nilly. See also: Saying Thank You [1], and Days Are Easily Made [2].
3. It's always been a delight; no regrets. You should try it too!
So, let serendipity reign; write away!
[0] https://www.evalapply.org/about.html#standing-invitation
Well, I expect to never need WITHOUT ROWID. And even if such an arcane situation hits my system, WITHOUT ROWID has so many ifs and buts that I'll probably elect to eat the $$$ cost of running an un-optimised normie SQLite as far as possible.
cf. https://sqlite.org/withoutrowid.html
The WITHOUT ROWID syntax is an optimization. It provides no new capabilities. Anything that can be done using a WITHOUT ROWID table can also be done in exactly the same way, and exactly the same syntax, using an ordinary rowid table. The only advantage of a WITHOUT ROWID table is that it can sometimes use less disk space and/or perform a little faster than an ordinary rowid table.
As of now, I am doing the following in my (Bitemporal data system) experiment (When will it see the light of day? Nobody knows.).
All data are globally uniquely identified by a UUIDv7. However all tables have `rowid` integer primary key asc (which is just an alias for SQLite's autoincrement int id). The `rowid` is the basis for joins, and is the foreign key reference. This lets me offload some useful disambiguation work to the DB as well as have it enforce global (across data systems) record uniqueness guarantees, while retaining local (within process) query efficiency by retaining the ability to use integer rowids.
While the idealised insert performance in your bench is indeed mind-boggling, the DB Schema isn't doing anything CPU-intensive during inserts (checks, constraints, triggers etc.). My schema / query pattern yields comparatively meagre throughput, but I am happy with the ballpark it has landed in, given all the work I'm making SQLite do for me on each `assert!` and `redact!`.
cf. my dirty-but-useful-enough bench, with production-like record content:
A poor man's napkin-mathy, append-only SQLite write/read benchmark
https://gist.github.com/adityaathalye/3c8195dc70626b33c23867...
Summary:
;; Okay, I think I can live with this...
;; - "facts" table: 12M+ records
;; - single process writes to it
;; - ~ 400 transactions/second
;; - append-only table, enforced via SQLite "before" triggers
;; - "now" table:
;; - updates on every assert/redact on "facts" table, via triggers
;; - currently at "limit case": for each read it is empty, or very small, because writes do back-to-back assert/redact of the same fact
;; - gets reads from two reader threads (evenly split)
;; - ~41,000 reads/second
;; - all reads are concurrent with writes (poor man's futures)Aside: Specific to SQLite...
Thanks to its oh so convenient automatic integer rowIDs, I believe one can amortise some of the other overheads of UUIDv7s for "in-between" queries, viz. indices, joins, ctes, virtual tables etc., with appropriate schema / query design.
Thanks for the benching, Anders! So grateful for the stuff you've shared over the years. Invariably, every single post has been useful and/or educational to me.
I read this post more as an illustration of the *value* of UUIDv7 as primary key, over integer primary keys, in lieu of minimal loss of read/write performance, and marginally more data on disk bloat.
SQLite's automatic integer rowID primary key is a no-brainer, when the SQLite application is local-only, such as application storage format (mobile and desktop). Or is never intended to grow beyond a single server instance. Basically, where each SQLite file is private to a singular instance of the application.
However, if there is even an outside chance of needing to cooperate across application instances, e.g. the minimal limit case of a personal knowledge base that should seamlessly sync across a person's devices, as well as a hosted service, then a high-quality sequential random ID starts to make a lot more sense. (No-brainer arbitrary table merges / splits / remerges, de-duplication, etc.)
Random ID primary key is a bad idea period, whether it be the UU kind or the SQ kind, or any other kind. As far as my DB knowledge goes, this class of ID destroys all tree-algorithms, and we are stuck with the fact that there is no practically better way, than an appropriate tree-structure, to group and organise a meaningful amount of data, efficiently and effectively.
Funny, I think a dead-tree book (or PDF you won't copy from) is a great format to learn programming from. Retyping things into the editor is underrated, as a form of engaging more viscerally with the material (brains work better when they get to play with the clay), as a way to build muscle memory for the language, as a way to absorb idioms by osmosis, and so forth.
Different brains, different strokes, but I think the book format is not wrong, the teaching and learning expectations are.
Hm, you made me think about non-printing characters as metadata, which is of course immediately lost on printing and therefore does not round trip between digital and printed versions.
Many nonprinting characters imply some directive; line break (hard-wrap the text here, but this is not a paragraph), page break (let the rest of the page be blank, start the next paragraph overleaf), EOL (file over, bye bye), nonbreaking space (keep these two words together, always, till death do them part).
This is out-of-band information spliced in-band (with the text corpus), which a computer program can "see", but a person can't.
XML, JSON, YAML, RDF, EDN, LaTeX, OrgMode, Markdown... Plenty of plaintext, but structured information formats that are "yes, and". Yes, I can process them as lines of plain text, and I can do structured data transformations on them too, and there are clients (or readers) that know how to render them in WYSIWYG style.
Yeah, "Nobody every got fired for purchasing IBM"... a story as old as time itself.
But that is the "fear" side of the enterprise sales equation... The "greed" side of it is for the buyer to make the long / short hedge.
The exec who gets the value of the working product can potentially come out shining, when their peers will be furiously backpedalling next year. And this consummate exec can do it by name-associating with their "main bet" which is optically great for the immediate term but totally out of their control (because big corp vendor will drag its feet like every SAP integration failure they've seen), and feeling a sense of agency by running an off-books skunkworks project that actually works and saves the day.
A fine needle to thread for the upstart, but better than standing outside the game.
Another way I see it is... Mind is process. LLM is (very lossy) snapshotted state of process/mind. LLM in-process is mind-emulator with potential to explore the state-space of the mind-snapshot. Consequently, and by its very construction, LLM cannot be mind.
Let me know how you think about this.
Well, I think of every Large Language Model as if it were a spectacularly faceted diamond.
More on these lines in a recent-ish "thinking in public" attempt by yours truly, lay programmer, to interpret what an LLM-machine might be.
Riff: LLMs are Software Diamonds
Based study. https://www.cell.com/current-biology/fulltext/S0960-9822(26)...
Cringe sciencedotorg coverage... TL;DR: Doped Salmon wild. Wild Salmon dopey.
But a lot more fun in pictures; Spiders on Drugs, courtesy NASA.
Quoted Photos: https://rarehistoricalphotos.com/nasa-spiders-drugs-experime...
Source: Using Spider-Web Patterns To Determine Toxicity: https://ntrs.nasa.gov/citations/19950065352
May I offer a little code riff slicing FizzBuzz using transducers, as one would do in practice, in real code (as in not a screening interview round).
Demo One: Computation and Output format pulled apart
(def natural-nums (rest (range)))
(def fizz-buzz-xform
(comp (map basic-buzz)
(take 100))) ;; early termination
(transduce fizz-buzz-xform ;; calculate each step
conj ;; and use this output method
[] ;; to pour output into this data structure
natural-nums)
(transduce fizz-buzz-xform ;; calculate each step
str ;; and use this output method
"" ;; to catenate output into this string
natural-nums) ;; given this input
(defn suffix-comma [s] (str s ","))
(transduce (comp fizz-buzz-xform
(map suffix-comma)) ;; calculate each step
str ;; and use this output method
"" ;; to catenate output into this string
natural-nums) ;; given this input
Demos two and three for your further entertainment are here: https://www.evalapply.org/posts/n-ways-to-fizzbuzz-in-clojur...(edit: fix formatting, and kill dangling paren)
I'd reckon most of Clojure is from ten years ago. Excellent backward compatibility, you see :) cf. https://hopl4.sigplan.org/details/hopl-4-papers/9/A-History-...
That is... a cool trick! I don't know C, so it would have never occurred to me. (Let's be honest; it would have not occurred to me even if I knew C :))
What I like about the Bash + Heredocs + substitutions approach is that it looks and feels declarative to me. Template "expansion" is just in-place substitutions (parameter expansion, shell substitution, process substitution); no string munging needed to "place" or "inject" content in the HTML tree.
Anyway, I spent way too much time figuring that out, and it works well for me, so I'm going to just roll with the sunk costs :D
Thanks for sharing your approach!
Also...
> I have to address the elephant in the room:
> hot-rebuilding isn't true hot-reloading.
> To get the browser to magically inject CSS without
> a refresh requires WebSockets, background Node
> processes, and a lot of external baggage.
OR... you could just use inotify again... Behold this abomination (that works so well (on my machine) I can't believe it): __shite_hot_cmd_browser_refresh() {
local window_id=${1:?"Fail. We expect window ID to be set in scope."}
printf "%s\n" \
"key --window ${window_id} --clearmodifiers 'F5'"
}
__shite_hot_cmd_goto_url() {
local window_id=${1}
local url=${2}
printf "%s\n" \
"key --window ${window_id} --clearmodifiers 'ctrl+l'" \
"type --window ${window_id} --clearmodifiers --delay 1 ${url}" \
"key --window ${window_id} --clearmodifiers 'Return'"
}
... and a few functions later ... __shite_hot_cmd_exec() {
# In debug mode, only show the actions, don't do them.
if [[ ${SHITE_BUILD} == "hot" ]]
then stdbuf -oL grep -v '^$' | __tap_stream | xdotool -
else cat -
fi
}
shite_hot_browser_reload() {
local browser_window_id=${1:?"Fail. Window ID not set."}
local base_url=${base_url:?"Fail. Base URL not set."}
__shite_hot_cmd_public_events ${browser_window_id} ${base_url} |
__shite_hot_cmd_exec
}
... and finally ... # RUN PIPELINE
shite_hot_watch_file_events ${watch_dir} |
__shite_events_dedupe |
__tap_stream |
tee >(shite_hot_build ${base_url}) |
# Perform hot-reload actions only against changes to public files
tee >(shite_hot_browser_reload ${window_id} ${base_url})Cool! Also, carrying forward the post author's tongue-in-cheek humour... I see your lua and raise you ~350 lines of Bash (excludes HTML templates). Take a good hard look at this shite [0]. Have you seen anything that is more obviously HTML-about-to-be-expanded-into-a-full-page?
shite_template_standard_page_wrapper() {
cat <<EOF
<!DOCTYPE html>
<html lang="en" prefix="og: https://ogp.me/ns#">
$(shite_template_common_head)
<body>
<div id="the-very-top" class="stack center box">
$(cat -)
$(shite_template_common_footer)
</div>
</body>
</html>
EOF
}
And, unlike PHP or whatever... have you ever seen more composable templating, as in functional programming? cat ./sample/hello.html |
shite_template_common_default_page
# Or..
cat ./sample/hello.org |
pandoc -f org -t html |
shite_template_common_default_page
Just imagine all the pipelined pre/post-processor possibilities.[0] project codename `shite`, literally, renders my site https://github.com/adityaathalye/shite
> Within that machine lies Org-mode.
> ...
> Absolute maniacs run their finances, their spreadsheets,
> and their fragile grip on reality out of it.
I feel seen... who else is with me?In your case, bike or drive around and talk to SMEs in your city. Have friends refer you to their contacts, so it's a warm intro. Build software for free, and maintain it on an annual maintenance contract basis. "Value-price" each AMC. Initially, be fine with "leaving money on the table". Within two to three deals you will figure out a mutually profitable pricing strategy.
Cursive has been way ahead of the curve, yes. Sorry Colin, I'm both emacs-addled and fuzzy with timelines :D
So think of it more like "static analysis stuff for the rest of us" :D
I think it was more like Emacs got Clojure development niceties early, particularly tight REPL integration.
Things have been different for well over five years --- about a third of Clojure's life. There are so many first-class options now. When teaching Clojure, I direct everybody to either VSCode + Calva, or Intellij + Cursive.
LSP has really upped the game too. I rebuilt my Emacs development workflow around LSP for all the things.
These days, I sometimes forget to fire up the REPL, because of all this fantastic "static analysis style" developer tooling by borkdude and eric dallo.
Much gratitude to all the toolsmiths from all over the Clojure ecosystem. Special shout-out to LightTable for upping the game for everybody. I was very sad when the project went dormant.
To keep things simple.
Oh I am so with this. The "why" I posed was in context of TigerBeetle's design choices to solve for high-contention OLAP.
Sorry, I framed my question loosely --- too much implicit context.
Me personally, I'm learning from the lesson of TigerBeetle and others, and just using SQLite for my multi-ten-gigabyte ambitions :D
I feel the Expression Problem neatly frames the "diagonal scaling" proposition; what system design choices will allow the architecture to scale vertically in what fashion, while also being able to scale what horizontally, without losing strict serialisability.
If we add a "vertical" capability, it cannot be at the cost of any existing "horizontal" capability, nor should doing so forfend any future "horizontal" capability. And vice-versa (adding horizontal capability should not mess with vertical ones). The point at which one will break the other is the theoretical design limit of the system.
To a first approximation, yes. But, why? And for up to how many hundred terabytes of data can you get away with the single beefy server? Provided you make what design choices?
Which leads to the real takeaway which is "Tiger Style": https://tigerstyle.dev/ which I am partial to, along with Rich Hickey's "Hammock Driven Development" https://www.youtube.com/watch?v=f84n5oFoZBc
"Tiger on Hammock" will absolutely smoke the competition.
(edit: add links)