At least not for most use cases. You can just use modernc.org/sqlite instead as your SQLite driver. For people who aren’t in the Go know, “pure” Go programs are trivially easy to compile cross-platform to all the major platforms by default. You read that right - you can just go build a single Windows executable, Mac executable, and Linux executable on the same machine and just ship it: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # This can all happen on the same box!| Posts on Andrew Quinn's TILs
It’s no secret that I’m a fan of economics-inspired solutions to otherwise hard problems. The other day I happened across an old post by GMU economist Bryan Caplan which I think does this very elegantly, for a problem of some interest to me. The vast majority of wills evenly divide the residuary estate between children. Mine evenly divides the residuary estate between (children and grandchildren). I like this a lot. It makes it unambiguously clear where your priorities in the case of your...| Posts on Andrew Quinn's TILs
Spaced repetition has been around for a long time. If you’ve never heard the term before, it’s best described as flashcards on timers. an algorithm such as SM-2 or the more recent FSRS keeps track of how you did on the flashcard, makes a guess as to how long it could possibly wait to show you the flashcard again before you below, say, a 90% chance of getting it right the next time, and then schedules the flashcard for a new day.| hiandrewquinn.github.io
N.B.: If I link you to this personally, it is to explain why I usually seem to be in a great mood. It’s an experiment. I’m normally in merely a good mood, and I am pushing myself to be great. This is an unusual entry for a Today I Learned site, even by my standards. But I think it’s something I would prefer to pre-register ahead of time. I’ve always been predisposed to mirth.| Andrew Quinn's TILs
Did you know Vim has a client-server model baked in? Of course it does. If you run 1 vim --servername LOVE , then in another terminal something like 1 vim --servername LOVE --remote-send "colorscheme peachpuff" , you’ll find your Vim terminal switch to the creamy default theme all true gangsters love - without you actually having to do anything. I frequently flip between a US- and Finnish-based keyboard while doing my language studies.| hiandrewquinn.github.io
Still images of this GIF are at the bottom. Learning to read a language is mostly a game of getting massive quantities of comprehensible input. Learning to write that same language is a whole ’nother ballgame. But, using the 4-quadrant Anki card setup from my earlier post, I think I’m finding more and more ways to make this as amenable to spaced repetition as possible. One thing I’ve been experimenting with with surprising success is the idea of using LLMs to generate “semantic pertur...| Posts on Andrew Quinn's TILs
1 2 3 4 5 +--------------------------+------------------------------------------+ | L2, fixable | L1, intention | +--------------------------+------------------------------------------+ | L2, fixed | L1, (fixable -> fixed) explanation | +--------------------------+------------------------------------------+ The above 2x2 layout for Anki cards, which I call a “comprehensible delta”, is one of the best things I’ve happened upon in a while for learning another language. Let’s say you are...| hiandrewquinn.github.io
Given my interest in extending the life of my SD cards and hard drives as much as possible, I’m surprised I haven’t come across /dev/shm before. In a word it’s a world-accessible RAM scratchpad, which seems baked right into POSIX, so that virtually every ~Unix~ EDIT: Linux system already has it mounted as a tmpfs by default: 1 2 ❯ mount | grep '/dev/shm' tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,inode64) Today’s lucky 10,000, indeed.| hiandrewquinn.github.io
Earlier today on Hacker News Scrappy made the rounds, with the explicit tagline “make little apps for you and your friends”. I always like to see new projects in this vein. That’s why I’d like to outline my alternative approach, which Works cross-platform and on mobile devices by default, Doesn’t require any app store tomfoolery, Has great uptime built in, Gives you just enough data persistence to not get in your way, and Is owned by you, forever.| hiandrewquinn.github.io
This works as of, at least, Anki 24.06.3. According to the Mozilla Developer Network, The HTML element creates a disclosure widget in which information is visible only when the widget is toggled into an open state. In standard web browsers, absent any CSS to the contrary, a tag starts closed until further notice. Since Anki is basically a local web browser on top of a timer, this also works there.| hiandrewquinn.github.io
Language learning for the contemporary adult learner can be broken down roughly into four highly correlated, but distinct, skillsets. Passive understanding Active production The written word Reading Writing The spoken word Listening Speaking You may know from my FOSS software that I have been learning Finnish for the past 4 years or so. For the first few years I pretty much focused exclusively on reading comprehension, as I consider that to be the easiest quadrant to skill up in first.| Posts on Andrew Quinn's TILs
As a nerdy, working-class kid who grew up in the 1990s, knowing what time it actually was was a luxury I rarely had access to before I was 12 or so and my parents finally got an Internet connection with its attendant link to the Network Time Protocol. If you had told me I could have not just a watch but an entire machine that Never lost the time, Did what I wanted, how I wanted it, and Could be programmed to do what I want, how I want it on a schedule, I would have had to substantially revise...| Posts on Andrew Quinn's TILs
Perl 5 went through a long nadir of unpopularity due in large part to its deserved “Write Once, Read Never” reputation. So I was surprised to find out not only is it installed by default on Debian, it’s installed nearly everywhere by default. It’s even the non-shell scripting language of choice on OpenBSD! Perhaps the only thing more impressive than Perl’s utter ubiquity is its longevity. The latest major version of Perl was first released in 1994.| hiandrewquinn.github.io
Below is a GIF of tsk, my pocket Finnish-to-English dictionary, running in my terminal emulator of choice under Linux. It’s what the kids call a TUI, a graphical program that just happens to drive its graphics using terminal graphics instead of graphics-graphics. Insert GIF here. You can probably tell that this program fits neatly into the “home-cooked meal” clade of programs. There is a very straightforward problem I want solved - fast, single-executable-portable dictionary lookup, wit...| hiandrewquinn.github.io
Peanut butter and jelly are complementary goods, as are cars and gasoline, newer cars and electricity, electricity and basically everything else. We don’t normally think of, say, Docker and Kubernetes as complementary goods in software engineering, because you can get both for the low price of free. Or can you? You still have to invest time in learning both, and as the famous saying goes… Say it takes X hours to learn Docker adequately.| hiandrewquinn.github.io
If you followed “Binary search isn’t about search” and “Binary search isn’t about search II” properly, the following statements should suffice as a summary: 1 2 L[0:l] < T < L[r:len(L)] # ordinary binary search loop invariant L[0:l] < T <= L[r:len(L)] # leftwise binary search loop invariant Let’s complete the triptych. Take a wild guess what invariant we use for rightmost element binary search: 1 L[0:l] <= T < L[r:len(L)] # rightwise binary search loop invariant A motivating exa...| Posts on Andrew Quinn's TILs
In the first “Binary search isn’t about search” post, we spoke about using assert statements to enforce your loop invariants. Our plain old everyday binary search invariant can be summarized as such: For all x in L[0:l]1, x is strictly less than T, the element we are searching for. For all y in L[r:len(L)]2, y is strictly greater than T, the element we are searching for. Or, if we want to be even terser, we could note this as simply| Posts on Andrew Quinn's TILs
Suppose you’re trying to track down a bug that appeared in a series of Git commits. You’ve been idly keeping track of where this bug appears in your lucky commits by hand, while busy with other things. So far you’ve compiled this table: 1 2 3 4 5 6 7 8 9 10 0000000 🧼 clean, no bug. 0000001 🧼 0000002 🧼 0000003 🧼 0000004 🧼 0000005 🧼 0000006 🐛 bug first appears here.| hiandrewquinn.github.io
Before I moved to Finland, I spent some time in the Hobbesian war of all against all that is Wisconsin1. Men were men back in that less civilized age, and “cybersecurity” a ninny-word dreamt up by social harmony types who honestly thought they had anything worth stealing in their servers. For those of us doing real work, which I must emphasize you should never do, we had Expect. And to SSH automatically into servers where we didn’t have fancy accoutrements like “keys” or “audit re...| hiandrewquinn.github.io
This is a response to pid1.call’s “Siren Call of SQlite on the Server”, which itself is a response to articles like Wesley Aptekar-Cassels’s “Consider SQLite” espousing SQLite as a server-side technology. Cards on the table, I both love SQLite and think pid1 has the more correct take here. When I decided on a dime after college to move countries and be with my wife, part of the package deal was that I had to throw away my dreams of easing into the software industry by resting on t...| hiandrewquinn.github.io
Ever need to download a file from a server – or get someone else to download a file from a server, who may not be comfortable with or should have access to scp or sftp? Turns out, if you have Python installed – and you probably do – it comes with a handy one-liner file server for just such an occasion: 1 python -m http.server 12345 # or whatever port you prefer Then to close the server, just Ctrl+C.| hiandrewquinn.github.io
Last night I went to DigitalOcean and spun up a tiny new, $4/month droplet – on my own dime! It sounds crazy, but I’ve never actually wanted to pay for hosting myself before. But I have a fun little web app cooking up, one that might eventually pay that $4/month back with interests, and I decided, why not, it’s time to finally put some of my own skin in the game with this whole sysadmin thing.| Posts on Andrew Quinn's TILs
Epistemic status: Very unclear, also I Am Not A Lawyer This Is Not Legal Advice Get Off My Lawn (N.B.: I"m using “GPL” with broad strokes here, to point at “open source licenses it’s straightforward to run afoul of”.) Policing is always hard in a world of limited resources. Especially when one is targeting sophisticated, well-monied criminal organizations, it can take an awful lot of time and effort merely to credibly reveal that wrongdoing has taken place.| Posts on Andrew Quinn's TILs
What’s the best way to get a job? Show someone with a job to do that you can do the job within their iron triangle. What’s the best way you can show someone you can handle a complicated k8s deployment, with 7 different CNCF-approved add-ons, zero-downtime rollouts and a whole bunch of YAML files? Probably by competently and publicly running your own complicated k8s infrastructure. Self-hosters remind me a lot of the sysadmins of yore, who mostly ended up in the profession because they jus...| Posts on Andrew Quinn's TILs
If you’ve been following my posts recently, you might have noticed that I’ve been working more and more with PHP lately. As someone who was curiously allergic to web dev as a teenager, it has been a strangely healing experience for me. I’d like to say it’s because my experiments with Laravel, the only OSS work of which I can point to is testing the Homestead VM’s compatibility for Shell Bling Ubuntu, convinced me.| Posts on Andrew Quinn's TILs
| Posts on Andrew Quinn's TILs
PHP is, for better and for worse, the Python of web dev in my eyes. It is exceptionally easy to get started, in a way which I think younger developers may not be fully aware of. So here I’d like to make them aware of it! That’s right, this is a Slowstart for people who have never touched PHP or web dev before. Start the way we usually do on this blog, with the “tutorial-in-a-box” by installing Vagrant and Virtualbox so you can create a disposable virtual machine with just a few commands.| hiandrewquinn.github.io
First get a working script. “Hey GPT-4, write me a ChatGPT script that does .” Manually check over the script and iterate until it’s giving me what I want. “Now wrap the script into a click command-line interface.” I almost always specify to use an --input flag and an --output flag. If the data it’s working with is human-readable, “Make it so that if --input is not specified, it reads data from stdin.| hiandrewquinn.github.io
It would have to be finstem, a simple command-line program I wrote to reduce Finnish words down to their root form. Finnish is a lot like Latin or Russian in that its words often become lumbering behemoths of rewritten consonants, suffixes upon suffixes, and this makes it hard to look up in a dictionary – that is, until you factor in its very regular orthography and the phenomenal efforts of the Finnish programming industry: finstem is basically a very specialized UI for the OpenOffice spel...| hiandrewquinn.github.io
(Inspired by yungporko’s Ask HN post, which got me thinking.) Pretty much every community, dojo, workplace, subculture, scene you can imagine in the modern day had a software sub-scene embedded within it. It can be as small as “that guy who does our Excel”, or as large as the scene itself . This is owing to the fantastic generality of software as a way to make almost anything more efficient, but we won’t go on that tangent now.| hiandrewquinn.github.io
Poking around in a fresh VM in Vagrant, I see bash dash, a POSIX compliant shell linked under sh python3, 3.11.2 at the time of writing awk, specifically mawk sed, if you count that (I do) perl, specifically Perl 5 There may be others I missed. Why I’m curious: Knowing that a language is installed by default on the most popular Linux distribution can simplify certain concerns considerably, which are of special interest to people who don’t work on Internet-connected boxes.| hiandrewquinn.github.io
Today I released a dump of six months of flashcards I autogenerated from my tiny Finnish news archive to make the lives of my fellow language learners easier. The actual code which generates this archive is about 300 lines of Python . The basic value add for the user: What you want: Better fluency in Finnish. What you need: Practice. Lots of it. What this gives you: GOTO 2. This is emphatically not the kind of product, or use case, I would stumble upon as a brain-in-the-vat developer.| hiandrewquinn.github.io
Consider the problem of “how do I run more than 1 terminal at a time”. At this moment, I have at least 5 different ways I can effectively solve this issue: I can, from a different physical computer, SSH in to a new session. I can, from the same physical computer, switch to a different tty session with … C-S-F2 through 6 or something. (Rare, but sometimes it comes in really handy.| hiandrewquinn.github.io
This week I achieved a modest personal dream of mine I’ve had since I was a high schooler: I purchased a proper standing desk, with a low-profile treadmill underneath. The total cost for a setup here in Finland came out to only about $350, something I can easily afford with a week’s take-home pay. The primary hurdle for me was psychological: How could I justify spending so much money on a more ergonomic setup when I’m not even sure this whole “software engineering” thing will work o...| hiandrewquinn.github.io
Between our ESP32 prokaryotic organisms and our 24/7 Internet-enabled megafauna servers, there exists a vast and loosely-defined ecosystem of things the B2B world likes to call computer appliances. Picture a bespoke Pi 4 packaged up neatly with some Python scripts, a little fancy plastic embossing, and maybe a well-guarded id_ed25519.pub in case you end up in hot water during the (long - very long, stable cash flow for generations long) maintenance contract, and you’re in the ballpark.| hiandrewquinn.github.io
A while back I stirred up some controversy on Hacker News by talking about why I liked it when tutorials take you from clean VM to working, installed software. I’ve since taken to calling this the “tutorial-in-a-box” method. When I write them myself, I usually put them under the header Slowstart, a riff on the proverbial Quickstart. Two examples: A gentle introduction to reposurgeon. The Slowstart for selkokortti, some flashcard generating software based around my Finnish language news ...| hiandrewquinn.github.io
The best websites are home-cooked meals. Andrew’s Selkouutiset Archive was birthed after I realized there was no obvious way to fetch the previous articles of the “Easy Finnish” daily news broadcast. This annoyed me as a student of the language. “Here we have a stream”, I thought, “of high-quality, human-written, interesting practice material, and no easy way to access it!” So I went out of my way to create such a way, and me and my language skills have been profiting off of it ...| hiandrewquinn.github.io
There are few things I think about more than the essays on gwern.net, and there are few with as satisfying a theoretical payout to contemplate in my orb as his essay on “leaky pipelines”, aka log-normal distributions. The skulk: Say you’re working on a Laravel web app. You’re about 90% sure you know how to start the app. You’re 80% sure you know how to handle the infra you’ll need to get it online.| hiandrewquinn.github.io
I was 100% mouseless back before it was cool. Between dropping out of high school and enrolling in community college, I replaced my laptop with a $80 HP EliteBook I found on eBay; when I discovered its trackpad didn’t work anyway, I went all in on a no-X setup. I eventually concluded that going 90% mouseless got me almost all of the benefits, with almost none of the downsides. It’s almost as if returns are usually diminishing!| hiandrewquinn.github.io
Most of us work in companies with something approximating a shared online internal wiki, be it Confluence or MediaWiki or even a searchable, static website custom built for the task. A common problem with these sites is making what you write discoverable to other people on the site. Your chosen title might tell you, a person fully in the weeds of whatever you were just doing, exactly enough to know this is the article you were looking for.| hiandrewquinn.github.io
I’m kidding, I’m switching to OpenBSD because I like security or code quality or something. It’s totally not because the inexorable march of aging is starting to show its effects on my ability to down necessary-evil trivia like me and my friends used to down forties in the Ahhhnald after dark, and so I’d like to settle down with a software ecosystem I can study in real depth once without feeling like 20% of what I absorb in year X will be deprecated by year X+10.| hiandrewquinn.github.io
One of the cooler things about working in a firm founded and run by a lot of dyed-in-the-wool Linux hackers like my current place is that there is a lot of Bash lying around, accumulated over a good 25 years or so. For all their faults, pure shell solutions still set the silver standard for programs which appear almost entirely immune to bit rot. But you know what? So does vanilla PHP.| hiandrewquinn.github.io
I am, emphatically, not the language learning type. I’ve done enough of it over my life to know this. It’s certainly one of the better hobbies out there: You can do it for free (in principle), you can sink as many hours as you care to into it, and if you get good enough at it you get to reap some unique cultural and economic1 benefits. But there’s a reason I picked up Python when 14 year old me decided he wanted to get ahead in life instead of (say) German.| hiandrewquinn.github.io
I Robert Anton Wilson was, is, and always will be a fascinating and hiliarious writer to me. I first read The Illuminatus! Trilogy when I was 13, and while it was coincident with a total and suffocating blackout of meaning, I no longer think reading it actually caused that to happen in any significant sense. Au contraire: Teen me found refuge in his absurdity - it felt bedrock nihilstic, sure, but a far more artfully and deeply buried nihilism than I was able to find elsewhere at the time.| hiandrewquinn.github.io
Imagine you had the Most Complicated Program On Earth (MCPOE), with 1,000,000 dependencies. Every dependency must be build correctly exactly right or the MCPOE will fail to compile. MCPOE’s 10x dev team chose their packages so that each dependency has only a 1/1,000,000 chance of having something go wrong when you’re installing them - maybe a whitespace character snuck into the wrong build script, maybe solar wind hit the build computer.| hiandrewquinn.github.io
Here’s a secret. If you have Vagrant and VirtualBox installed, and your colleague does too, then you can both bring up an near-totally identical blank slate Debian 12 Linux VM by running 1 2 3 4 5 6 mkdir tutorial/ cd tutorial/ vagrant init debian/bookworm64 vagrant up vagrant ssh . This works regardless of whether you or they are on Linux, Mac1, BSD, or even Windows. (Through the magic of aliasing, mkdir and cd even work in PowerShell.| hiandrewquinn.github.io
The Fish shell has… interesting syntax for multi-line string literals. The only way I can reliably remember is to literally write them as multi-line literals, which does make a certain kind of brutalist sense: 1 2 3 4 5 6 7 8 9 function kiitos set thankyou '--- kiitos kaynnista ja tervetuloa uduelleen ---' echo $thankyou end kiitos reliably prints 1 2 3 4 --- kiitos kaynnista ja tervetuloa uduelleen --- , but man does it look funky to me.| hiandrewquinn.github.io
tmux (short for “terminal mux” (short for “multiplexer”)) is i3 for your terminal. Oh, it’s so much more than that, and I recently discovered with some joy that it is installed by default on OpenBSD, but its fundamental value add to any programmer who has to SSH into servers more than once a week is it allows you to split your screen up into multiple independent shells without needing a graphical environment at all.| hiandrewquinn.github.io