HNHacker News
TopNewBestAskShowJobs

Jach

11,571 karma · joined November 23, 2009

Email: jachhn ~at~ thejach.com Do not harvest and contact my email to advertise your stupid app. That is spam.

PGP key (for email alias): https://www.thejach.com/about#pgp

Available for IM on Matrix/Element -- Jach#matrix.org. Discord as jach9107. Sometimes on Libera IRC as Jach or Jachy. Hit me up if you want to chat about anything; I'm bad at reaching out myself.

I'm just some unimportant programmer, dabbler by nature, you probably shouldn't listen to me but that doesn't always stop me from commenting or giving advice.

Please excuse my Common Lisp evangelism, I'm just a poser who after a journey from PHP through Java, Python, C, C++, JS, Scheme, and Clojure, just loves the language, enjoys programming anything in it, and has fun trying to correct decades-old misconceptions about it. Maybe by the time I'm 50 I'll have more to show for it. i.e. I think it's better to write cool programs in Lisp than to evangelize, and I'm failing to live up to my own standards.

I've collected some stuff I occasionally link in comments here in one place: https://www.thejach.com/view/2022/1/thoughts_on_writings_on_lisp

I'm not currently employed -- I did a speed-run to quasi-retirement in 2020.

I have a BS Degree in Computer Engineering from a school more renowned for degrees in video game [engine] programming.

I'm located in Bellevue, WA, feel free to get in touch for coffee/dinner/whatever if you're in the Seattle area. Or even if you're not, maybe we can play some online games. I like to visit Japan, too. でも、私の日本語は下手です。

submissionscomments
Jach··on Photo GIMP – A Patch for GIMP 3 for Photoshop Users
Krita is not very good for photo manipulation. Even basic stuff like rectangle select and selection manipulation is painful. But on a project I used Krita, Gimp, and Inkscape all at the same time, and it was fine. Different tools for different purposes. Though with Gimp 3 having better font/text behavior, and overall allowing to build a pipeline of effects instead of immediately applying them (aka non-destructive editing), I could probably drop Inkscape now.
Jach··on Hyperpolyglot Lisp: Common Lisp, Racket, Clojure, Emacs Lisp
Or with more Python-esque syntax:

    (let ((files (coerce "ABCDEFGH" 'list))
          (ranks (loop for r from 1 to 9 collect r)))
      [(format nil "~a~a" file rank) (file <- files) (rank <- ranks)])
Based on the list comprehension macro from 1991 in https://3e8.org/pub/scheme/doc/lisp-pointers/v4i2/p16-lapalm... that still works.

    (defmacro comp ((e &rest qs) l2)
      (if (null qs) `(cons ,e ,l2) ; rule A
          (let ((q1 (car qs))
                (q (cdr qs)))
            (if (not (eq (cadr q1) '<-)) ; a generator?
                `(if ,q1 (comp (,e ,@q) ,l2) ,l2) ; rule B
                (let ((v (car q1)) ; rule C
                      (l1 (third q1))
                      (h (gentemp "H-"))
                      (us (gentemp "US-"))
                      (us1 (gentemp "US1-")))
                  `(labels ((,h (,us) ; corresponds to a letrec
                              (if (null ,us) ,l2
                                  (let ((,v (car ,us))
                                        (,us1 (cdr ,us)))
                                    (comp (,e ,@q) (,h ,us1))))))
                     (,h ,l1)))))))

    (defun open-bracket (stream ch)
      (do ((l nil)
           (c (read stream t nil t)(read stream t nil t)))
          ((eq c '|]|) `(comp ,(reverse l) ()))
      (push c l)))

    (defun closing-bracket (stream ch) '|]|)

    (set-macro-character #\[ #'open-bracket)
    (set-macro-character #\] #'closing-bracket)
Supports filtering too, e.g.

    (let ((xs '(1 2 3 4))
          (ys '(1 2 3 4)))
      [(+ x y) (x <- xs) (y <- ys) (evenp x) (oddp y)])
    ; -> (3 5 5 7)
Jach··on Qwen 3.7 Preview
I sort of thought this about qwen3.5 35b, finally a local model that isn't a complete waste of electricity, but "upgrading" to 3.6 35b left me disappointed. It seemed more like a downgrade. But honestly I've barely used either. Subjectively they still seem far from the frontier models, but for what they can do, it's great to be able to do locally.
Jach··on WHO declares Ebola outbreak a global health emergency
"It depends" is usually a safe (if not always helpful) answer. The older idea was that viruses always evolve to be less virulent/deadly, but that didn't match observations. The newer idea is simply that of a virulence-transmission trade-off. But there are various assumptions behind both ideas, and not all viruses follow those assumptions, so.. it depends. A decent review: https://pmc.ncbi.nlm.nih.gov/articles/PMC10066022/
Jach··on Moving away from Tailwind, and learning to structure my CSS
Framework-less CSS maybe, but we're never going back to the mindset of CSS Zen Garden. There is no pendulum.
Jach··on Points are a weird and inconsistent unit of measure
When Europe switches to metric time I'll switch to reporting centimeters for my height.
Jach··on Bill to block publishers from killing online games advances in California
Currently one of the features Valve's SDK offers is free use of network relays for P2P gaming without revealing each others IPs. Big and small games have used it. The main downside is if a game wants to offer cross-platform cross-play.
Jach··on Mythical Man Month
I think the fuller version of the "'no silver bullet' is wrong" claim is at: https://blog.ploeh.dk/2019/07/01/yes-silver-bullet/

A weaker claim is that maybe there's no single silver bullet but there have been many bronze bullets that add up to more than a single silver bullet. I readily endorse at least that and think it's rather easy to justify.

Jach··on AI is breaking two vulnerability cultures
The best convenience is that by the time of disclosure, the patch was already merged perhaps months prior and so sysadmins following a routine update schedule would have already updated to a version including the patch and thus have nothing to do. This relies on an assumption that a patch or series of patches aren't equivalent to a disclosure, so that a disclosure can be delayed from the patch, which is basically untenable in modern times.
Jach··on Wi is Fi: Understanding Wi-Fi 4/5/6/6E/7/8 (802.11 n/AC/ax/be/bn)
Speaking just on timelines (rather than actual underlying innovations or improvements), 802.11 was in 1997, next in 1999, G in 2003, then a 6 year gap to N in 2009, 4 year gap to AC in 2013, 8 year gap to wifi 6 in 2021, wifi 7 in 2024 (though apparently buyer beware), and wifi 8 expected (according to the article) in 2028. Doesn't seem too rapid? The 8 year gap is the weird one out.

I think part of it is that if there isn't a regular and practiced process for bumping standards, then gaps between revisions can grow quite large and stagnation can set in, and if there are any significant improvements it'll take longer for them to come to fruition than if there were regular revisions that are only modest most of the time. Looking at a few other things that come to mind: USB had an 8 year gap between 2 and 3 as well, PCIe had a 7 year gap between 3 and 4 (albeit while they only had a 3 year gap between the specification for 5 to 6, it still took 3 more years (2025) for the first pcie6 devices, and I still can't buy a consumer-level pcie6 motherboard, it's a separate mess), C++ had an 8 year gap between C++03 and C++11, Java had a 5 year gap between 6 and 7 (and another 3 years after 7 to get to Java 8); all of these things now have more rapid cycles.

Jach··on ClojureScript Gets Async/Await
Is that something people want to get rid of? Back when I did some clojurescript people were pretty proud of being able to have it used automatically. What's the plan to get the same benefits? Or is the argument that the benefits aren't significant 15ish years on?
Jach··on Why TUIs are back
And for those of us devs, they never really went anywhere. vim was the most popular editor on HN 15, 10 years ago, still very popular 5 years ago, still popular today.. and that's just an editor, all the other tools like top and its descendents never went away.. I'll believe "TUIs are back" or in some kind of uprise when I notice my non-developer friends and family using them for anything. The most dominant UI today is the mobile app, that's not changing. Limited to professional use (i.e. doing work for someone) and not all use, TUIs aren't touching either web apps or native GUIs either.
Jach··on Windows API is Successful Cross-Platform API (2024)
And Unreal Engine 5 needs the Agility SDK, creating problems where games wouldn't run if your Windows version wasn't new enough. (Same as the typically encountered glibc problem of the user having an older version than the build needs, really.) (I think most of those particular issues were "solved" now with Win10 being EOL and so the developers just rub their hands of it and say "upgrade". Or use Linux and Steam, where no thanks to MS or the gamedevs themselves, games old and new can just work.)

Dependency hell comes for everyone, win32 may be stable but the broader ecosystem for Windows is little better than anything else. I say little because at least MS does still commit to a lot of backwards compatibility and ensuring some very old DLLs are still part of new Windows 11 installs.

As another comment notes some older Humble Bundle linux builds just don't work anymore on modern systems; some of those are just because they assumed a particular libjpg or libxml or whatever would be part of the base distro install and be around indefinitely. Bad assumption. But fixable the same way as missing DLLs from Windows builds.

Jach··on Dotcl: Common Lisp Implementation on .NET
This project? https://github.com/Syzygies/Compare

If Dotcl does have good performance, it would be interesting to try running Coalton on top of it too. Coalton syntax is probably not unusual if you are familiar with OCaml and F#: https://github.com/coalton-lang/coalton (Though I'd expect the performance of the typical use case of running on top of SBCL to still be better.)

From the same project there's the recently released mine editor that's trying to be a friendlier gateway into trying Common Lisp (and/or Coalton) than emacs: https://coalton-lang.github.io/mine/ Time-to-first-SHOUTING is still once you start a REPL though -- it tells you that your package (namespace) is CL-USER. I sort of think it's one of those things that grows on you, or at least isn't annoying after a while (until you need to deal with certain foreign function interfaces anyway), and it's an interesting possible convention to use SHOUT-CASE in docstrings to call out specific parameters or other function names instead of some @param, \param, @link, or what have you.

Jach··on Why I still reach for Lisp and Scheme instead of Haskell
I did, I still ended up pattern matching on too broad an interpretation of "it". Thanks for clarifying.
Jach··on Why I still reach for Lisp and Scheme instead of Haskell
Being paused in the debugger is per-thread. If the server's using a thread-per-request model, and you're stopped in the request, then other requests can proceed just fine. If some of those requests also trigger the debugger, they'll pause and have to wait, they won't interrupt your current debugging view. Extra care should be taken in any sort of production debugging, of course. (At a Java BigCo, production debugging was technically allowed but required multiple signoffs, the engineer wasn't the one in control but had to direct someone else, lots of barriers to prevent looking at arbitrary customer data, and of course still limited to what you can do with a standard JVM restarted in debug mode. (Mainly setting breakpoints and walking stack traces.))

But the nicest part is that once you connect to the production application, apart from network lag it's no different than if you were developing and debugging locally on similarly specced hardware to the server, you have all the same tools. Many of the broader activities around "debugging" don't need to happen in a paused thread that was entered with an explicit breakpoint or error, they can happen in a separate thread entirely. You connect, then you can start inspecting (even modifying) any global state, you can define new variables, you can inspect objects, you can define new functions to test hypotheses, redefine existing functions... if you want all requests to pause until you're done, you can make it so. Or if you want to temporarily redirect all requests to some maintenance page, you can make that so instead. A simple thing I like doing sometimes when developing locally (and I could do it on a production binary too) is to define some (namespaced) global variable and redefine a singly-dispatched method to set it to the self object (possibly conditionally), and once I have it I might redefine the method again to have that bit commented out just so I know it won't change underneath me. Alternatively I can (and sometimes do) instead set this where the object is created. Then I have a nice variable independent of any stack frames that I can inspect, pass to other method calls, change properties of, whatever, at my leisure without really impacting the rest of the program's running operation. Another neat trick is being able to dynamically add/remove inherited mixin superclasses to some class, and when you do that it automatically impacts all existing objects of that class as well. Mixin classes are characterized by having aspect-oriented methods associated with them; you can define custom :before, :after, or :around methods independent of the primary method that gets called for some object.

Jach··on Why I still reach for Lisp and Scheme instead of Haskell
What makes you think it falls flat in a team setting? There are plenty of N-pizza-sized teams successfully using Lisp to this day and you're probably aware of many teams successfully using Lisp in the past, too. There's also the success of Clojure. What's required to have a well functioning team is mostly programming language independent; Lisp itself won't save a team lacking those properties anymore than say Java would.
Jach··on Why I still reach for Lisp and Scheme instead of Haskell
I've frequently said that Java + JRebel gets the closest to the Common Lisp + slime experience (closer than Python) but as you say the Lisp experience is still superior, the Java ecosystem has yet to close the gap*. The widest part of that gap I'd mention is in not having the condition system built-in to Java (though I'm aware people have tried to make a comparable one as a library), lacking it degrades the debugging experience considerably (even though simple step-debugging is typically more pleasant than in Lisp). IntelliJ's drop frame feature isn't good enough. The other problem is needing Java + something. What you get with just a regular JVM running under your IDE is no better than what other languages offer (if they offer anything) as their cute hotswap/hotpatch feature and comes with big limitations. (Like no changing method signatures or no adding/removing methods or properties, or only applying changes to new objects.) Once you're doing something non-trivial, especially if you're trying to incrementally develop your program rather than just debug one specific problem, you'll have to restart. In contrast Common Lisp's got its disassemble, describe, inspect, compile, fmakunbound, ... all being functions callable at runtime, and update-instance-for-redefined-class is part of the standard language too. Support for live reloading of everything is baked into the language rather than a hack on top, slime is just a convenient way of working with it. It's still convenient to restart the program occasionally, but few things force you to.

Unfortunately JRebel has killed their free tier, so I'd now point unwilling-to-pay programmers to something like https://github.com/JetBrains/JetBrainsRuntime which is IntelliJ/Eclipse/whatever-independent. I haven't tried it myself yet though... Given they only address the biggest class reloading concerns, I doubt it's actually comparable to JRebel for business-world Java. JRebel handles among other things dynamic reloading from XML changes and reinitializing autowired Spring beans that other classes use for dependencies.

*Caveat, I've been out of the professional Java grind for a while, I'd be pleasantly surprised if some new version that's come out contradicts me.

Jach··on Mine, a Coalton and Common Lisp IDE
Discussion from yesterday: https://news.ycombinator.com/item?id=47903173

(I submitted this the day before but I guess this is HN's second-chance feature kicking in.)

Jach··on Mine, an IDE for Coalton and Common Lisp
Yeah, I mean there is some support for various editors (https://lispcookbook.github.io/cl-cookbook/editor-support.ht...) including VS Code (https://lispcookbook.github.io/cl-cookbook/vscode-alive.html), but it's kind of rough (https://blog.djhaskin.com/blog/experience-report-using-vs-co...) and not exactly feature-complete with the emacs experience, plus you're still left having to figure out how to install and setup a Lisp implementation and quicklisp. I like that mine solves those for a newcomer, especially on Windows. (I myself use vim + slimv, but even that isn't quite at parity in some respects with emacs. The biggest weaknesses are around debugging, especially in the presence of multiple threads. But the essentials do work (stepping, eval-in-frame, continuing-from-a-stack-frame, selecting the various types of restarts, compiling changes before selecting restarts) so I'm still fairly productive and don't feel like I'm lacking anything sorely needed for professional work. I've hacked together some automatic refactoring bits as well, which emacs doesn't have either, and I'm eventually going to make a separated GUI test runner.)

I've been kicking the tires with mine a little bit yesterday and today, I think it's quite good for the beginner experience. But I'm constantly of two minds about reporting some feature requests. The project's primary goal seems to be existing as a stepping stone to even see what Lisp (and especially Coalton) is really all about before "graduating" to something like emacs, it feels like a secondary goal (though it is mentioned as a goal) to be usable by professionals as well, but there's inherent tension there. That's also been a weakness with the other editors: anyone already comfortable with Lisp development, professional or not, in emacs or not, isn't very likely to give the time of day to some new thing that's almost certainly not going to be as good as what they're used to. And so the new thing doesn't get the attention and feedback from experienced developers and the gap never closes.

Jach··on Google plans to invest up to $40B in Anthropic
A lot of businesses can get by just fine with making it one person's responsibility to maintain a spreadsheet for this. It can be fragile though as the company grows and/or the number of items increases, and you have to make sure it's all still centralized and teams aren't randomly purchasing licenses or subscriptions without telling anyone, it needs to be properly handed off if the person leaves/dies/takes a vacation, backed up if not using a cloud spreadsheet... I've probably seen at least a dozen startups come and go over the years purporting to solve this kind of problem, other businesses integrate it into an existing Salesforce/other deployment... it seems like a fine choice for an internal tool, so long as the tool is running on infrastructure that is no less stable than a spreadsheet on someone's machine.

In the startup world something like "every emailed spreadsheet is a business" used to be a motivating phrase, it must be more rough out there when LLMs can business-ify so many spreadsheet processes (whether it's necessary for the business yet or not). And of course with this sort of tool in particular, more eyes seeing "we're paying $x/mo for this service?" naturally leads to "can't we just use our $y/mo LLM to make our own version?". Not sure I'd want to be in small-time b2b right now.

Jach··on Google plans to invest up to $40B in Anthropic
It's an important concern for those footing the bill, but I expect companies really in the face of being impacted by it to be able to do a cost-benefit calculation and use a mix of models. For the sorts of things GP described (iptables whatever, recalling how to scan open ports on the network, the sorts of things you usually could answer for yourself with 10-600 seconds in a manpage / help text / google search / stack overflow thread), local/open-weight models are already good enough and fast enough on a lot of commodity hardware to suffice. Whereas now companies might say just offload such queries to the frontier $200/mo plan because why not, tokens are plentiful and it's already being paid for, if in the future it goes to $2000/mo with more limited tokens, you might save them for the actual important or latency-sensitive work and use lower-cost local models for simpler stuff. That lower-cost might involve a $2000 GPU to be really usable, but it pays for itself shortly by comparison. To use your Uber analogy, people might have used it to get to downtown and the airport, but now it's way more expensive, so they'll take a bus or walk or drive downtown instead -- but the airport trip, even though it's more expensive than it used to be, is still attractive in the face of competing alternatives like taxis/long term parking.
Jach··on Google plans to invest up to $40B in Anthropic
Are you able to describe any of those internal tools in more detail? How important are they on average? (For example, at a prior job I spent a bit of time creating a slackbot command "/wtf acronym" which would query our company's giant glossary of acronyms and return the definition. It wasn't very popular (read: not very useful/important) but it saved myself some time at least looking things up (saving more time than it took to create I'm sure). I'd expect modern LLMs to be able to recreate it within a few minutes as a one-shot task.)
Jach··on Our newsroom AI policy
Many open source projects accept donations. There's also explicitly paid-for software. What exactly do you wish for that you can't do right now?
Jach··on Acetaminophen vs. ibuprofen
In the US, Aleve is the name-brand pill for naproxen, available in grocery stores next to everything else. I have a bottle of 160 gelcaps. Each pill is 220mg naproxen sodium or in parentheses 200 mg of naproxen. The advertised effect is 12 hours / all day, getting anywhere near 4g would only happen in a suicidal "swallow bottle of pills" situation.
Jach··on Game devs explain the tricks involved with letting you pause a game
Do you have any of these presentations available publicly? I'm always amused by the glitch names people come up with (force quit wrong warps, skirtless parry-walks...) and it'd be fun to see them in a TLA+ context.
Jach··on Game devs explain the tricks involved with letting you pause a game
This used to be true, but one trip to any modern e-store front should dispell the notion. So much slop. Even for arguable non-slop, so much that just rapidly crashes and is unplayable. The extent of platform certifying these days for most titles seems to be: can launch, can back out to the console top level, and maybe doesn't crash if a controller is added/removed.
Jach··on Official Clojure Documentary page with Video, Shownotes, and Links
It's more depressing if you work in a big organization where decisions come down from on-high instead of letting teams decide what's best. (Especially if one of those decisions is so-called Agile practices which were about empowering teams against on-high global decisions from management, but that's a digression.)

But yes, treat it as a job, and make time for "fun time" after work at home using your favorite tools and languages and OSes, and you can still be happy, especially because the bills are being paid. And even in restrictive corporations there still may be opportunities to introduce a little of your favorite thing... Clojure itself "snuck in" at a lot of places because it was just another jar, and it's not too hard to shim in a bit of Java code that then turns things over to the Clojure system. You can also try getting away with internal-only tooling.

If I had stayed at my last job a little longer I would have tried putting more effort into sneaking Common Lisp in. I had a few slackbot tools I wrote in Lisp running on my machine that I turned over (with pre-built binaries) to someone else when I left (but I doubt they're running still). The main application was Java, and there was already mandates from security people and others not to use other JVM languages.. at least in application code. I was thinking (and got a prototype working) of sneaking in Lisp via ABCL, but only for selenium web driver tests. It was a neat trick to show some coworkers a difference in workflow: write or edit a web driver test, one of your asserts fails or an action click on some ID that's not there fails, in Java you get an exception and it's over, you'll have to restart the whole thing, which for us was expensive because these test suites typically spun up huge sets of state before starting. But with Lisp, exceptions don't automatically go back up the stack, but pause at the spot they occurred: from there you can do anything in the debugging REPL that you can do normally, redefine functions, classes, whatever, and then resume the computation from where it left off (or at some higher part of the call tree stack if you prefer), thus no expensive restart.

There's also ways to introduce things you like that aren't just different languages. My team started doing "lunch and learns" at most once a week (sometimes less often); if anyone wanted to talk about whatever for 30-60+ mins during a lunch period we'd get together and do it. Sometimes that would be about specific work things being built, sometimes it would be about external stuff, ideas (e.g. the Mikado Method) or tools. Once I did a brief presentation about property testing and later on got the quicktheories library for Java into the codebase and handling some tests, and ended up not being the only one to occasionally make use of it.

Jach··on Playdate’s handheld changed how Duke University teaches game design
If it's so easy, all the better. You can learn to build great architecture, optimize resources, and create a creative game all while also using Unity. There are additional bonuses to this beyond the pure knowledge too.
Jach··on Playdate’s handheld changed how Duke University teaches game design
This is part of a 2 year Masters program focused on Game Design, Development & Innovation, costing a student $113,000 to pursue. If a student enrolls in it without already having learned how to think, this is not the program that is going to teach that. Surely any competent school can teach students how to think within the first year, if they do not already know how to think, leaving the rest of the years (and any Masters or PhD programs) able to assume that the students already know how to think and thus save the time to teach actual content.

If students sign up and pay for a class you teach called "Data Structures & Algorithms", and you just read from Hamming's book every lecture and don't actually attempt to teach any data structures and algorithms, expect to not have a teaching job for long.

← PreviousPage 4 of 34Next →