Reading audiobooks

Craig Thomler asked on The Bird Site:

Hey folks, if you only listen to audio books, can you really call it ‘reading’?

Absolutely :).

A term for accurate, yet pointless responses

I keep being reminded of that paraphrased John Siracusa quote that technical accuracy is necessary, but not sufficient. Effective communication is about being understood as much as is about being correct. A large cohort of the Interwebs seem utterly oblivious to this, whether it be in online debates, or even joke deconstruction. Worse, others wear it as a badge of honour.

Someone posting about how they’re “so full they could never eat again!” will invariably garner a response from someone saying they need to eat throughout your life to survive. A person exasperated at a recursive dependency in a package manager will be told that life was tougher when we only had tarballs to compile. Make a joke about how renewing your passport was a bit pointless this year, and you’ll have it explained to you that passports last a decade. Frustrated that you missed your train? Well, had you considered leaving earlier?

Those responses are factually accurate, and completely miss the point. Some don’t see the forest for the trees, others are just obtuse or lack empathy. But the outcome is the same: metal exhaustion at having to deal with it!

I’ve been trying so hard to think of a term for this kind of rhetoric, anyone have an idea?

Linus Tech Tips: Nothing EVER works!

Linus from Linus Tech Tips did a rant video about the failings of home automation, which I felt in my soul. I don’t do any of this stuff, but easily substituted so many of my own technical problems for the arduous process he went through to get even the most basic thing right.

He summarised the issues with smart tech in general:

Number one: unexpected service interruptions or policy changes that can brick already perfectly-functioning setups. And number two: poor or incomplete interoperability between different brands and platforms.

Related to point one, I’d also blame the industry shift to subscriptions, which is one more thing you need to track and budget for. I used to think this was our fault, because we demand cheaper devices which have to be subsidised somehow. But I’m starting to think it’s greed.

I’d also add quality control. There’s no reason that half his problems should have existed in the first place, all other things being equal. My Hi-Fi system components that were made in Japan in the 1980s will outlast all the rubbish we buy and use now… and with style! Granted it was more expensive, but that can’t be the only variable here. The whole run fast and break things because we can do remote updates thing has been a tremendous failing of our industry and needs a fundamental rethink.

Linus’s solution, at least for point two, was to use Home Assistant, which you run on a server yourself. This is great if you’re technical, but an absolute non-starter for anyone who lives in the real world. What do those people do? Hope that they have a knowledgable family member or friend? Pay even more money for installation and ongoing maintenance?

Clara and I don’t use Internet of Things (IoT) devices into our apartment. We like to pretend it’s because we’re taking security seriously, and that we’re taking a stand for privacy and ecological sustainability. Tying the lifespan of something like a lightbulb to an ephemeral web service or smartphone is the last thing the planet needs. But in reality, it’s just easier. Press a light switch, boom. Use a remote control, boom. Adjust an aircon remote, cooling boom. I’ve got enough to be anxious over without worrying whether something will turn on or not because we don’t have Internet, or a service has changed.

Pyramid schemes

We all know about those modern pyramid schemes that recruit people to sell health shakes and supplements. It really came home for me when I saw a friend from my uni days standing in a railway underpass trying to spruik these to anyone who’d listen. It broke my heart thinking that he’d been suckered into buying all this stock, and that’s what his life was.

But it’s a double-edged sword. I’ve been sitting at this coffee shop for half an hour overhearing a young man being pitched this alternative medicine scheme. The sales guy has all his talking points down, from bulk discounts, the purported health benefits without actually saying anything concrete, and how he has people lining up to buy from him.

Then out of the blue, the young guy calmly destroyed him with two sentences. I didn’t write it down fast enough, but was something to the effect that he was “onto him” and that he should get a real job instead of being a “bullshit artist”. He stood up and walked away, leaving the pyramid schemer with the coffee bill. Brilliant!

For each of these slick sales guys is a person who’s life has been destroyed. Maybe the best approach isn’t to debunk them, but to waste their time so they can’t spend it on impressionable or uninformed people. Sign me up to that!

Cryptocurrencies, get-rich-quick schemes, multi-level marketing… the only pyramid scheme I want to see is one in which Clara and I get to go to Egypt one day.

I’m now a part of @pavoliareine's Royaltea!

Screenshot from YouTube showing Reine and Ina's Minecraft collab stream

Salamat malam! Hot on the heels of finally signing up for Ina, Clara and I are now supporters of Pavolia Reine, our favourite Hololive Indonesia member. Her stream with Ina basically sealed the deal! ♡

Terima kasih :). I miss Indonesia something fierce, I hope to head back there again someday. 🇮🇩

Disabling memberships in Ghost 4 blogs

I use the Hugo static site generator for the site you’re reading now, but I’ve long recommended Ghost to people who want a server-side blogging platform. It’s fast, simple to use and administer, and has far more focus on blogging than other platforms with which you may be familiar.

The new feature

A membership feature was enabled by default starting with version 4, allowing bloggers to accept signups, collect subscriptions, and send email newsletters. It’s precisely the independent support I’ve been shouting about here for years, and a critical counterpoint to writing farms like Medium, and social networks like Facebook.

(I’ve talked about the subtle change in their messaging from a kickarse blogging platform launched on Kickstarter, to something specifically pitched for business. But it still makes a great blog platform).

The problem was it couldn’t be disabled anymore from the web UI. Some of us host blogs for people and organisations who don’t want memberships, get income elsewhere, or for whom a membership relationship with readers doesn’t make sense. Others were precluded on fiduciary or legislative grounds. Even among users of the feature, confusion abound about how to remove users, change the messaging, and the wider security implications.

After some heated forum discussions and partial workarounds, the Ghost team have indicated on Twitter that a toggle for this feature is returning, though they haven’t committed to a timeline.

The simplest workaround for now

mdeneen spotted this feature in the Ghost config starting with 4.3:

SELECT value,key FROM settings WHERE key = 'members_signup_access';
==> all|membership_signup_access

Setting this to none disables the feature, as we would have done with v3’s graphical checkbox. I can confirm this works!

UPDATE settings SET value = 'none' WHERE key = 'members_signup_access';

Kevin from the Ghost team, who’s been especially patient during all the hand-wringing about this, cautioned:

This will only work in Ghost 4.3 onwards. The UI for this option is currently behind a developer experiments flag and will be made generally available in a future release.

As this is currently in development be aware this setting value may change.

I’d recommend people stay on Ghost 3.x until an official release includes this option. But for those who’ve already made the jump 4.x, this is the simplest way to fix it, provided you keep an eye on updates.

Thanks to the developers for implementing this; I can say it’s improved my quality of life more than I care to admit! 🍻

Minecraft, and mental health

Minecraft is one of those games you can absolutely lose yourself in for hours at a time. I was talking to one of my colleagues about how this one massive building complex has become repetitive and rote, yet Clara and I still love constructing it. Her comment was that it’s almost a form of meditation, because you dedicate all your mental energy to it.

At the risk of putting too fine a point on it, Minecraft is the modern equivalent to me of the Lego I grew up with, and even SimCity to an extent. Those games got me through some tough family times, partly because there was creativity involved, but mostly due to it being a fun task that had nothing to do with the outside world, or circumstances outside my control. Minecraft was the perfect game for Clara and I to play to distract ourselves from COVID, especially during lockdowns.

It’s in that context that I’m actually relieved to read this press release by the Minecraft team, where they announced they’re splitting their hotly-anticipated Caves and Cliffs expansion in two, and delaying their release:

Technical considerations aside, we also prioritize our team’s health. We’ve come to realize that to ship all the features in the summer we would’ve had to work very long hours; and even then, there would’ve been no guarantee that everything would be finished on time. Lastly, working from home as we cope with the pandemic is still challenging – not just in terms of morale but also by hindering teamwork. Because our workflow is so complex and collaborative, not having the option to walk up to someone and ask for help makes everything take longer.

I don’t think people in general appreciate the enormity of the effort involved in maintaining Internet infrastructure so others can do their work, chill with a streaming service, and keep in touch with family. The same applies to games; we see these as activities for fun, but there’s serious work that goes into building, maintaining, updating, and fixing them.

It’d be a bit rich to attribute so many positive mental feelings to this software, and not afford the developers themselves any patience to improve their own.

Palm LifeDrive in a Windows 2000 QEMU VM

Today I wanted to run the Palm Desktop to HotSync my Palm LifeDrive PDA, as well as run the LifeDrive Manager to transfer media. I ran down a few options before deciding on a Windows 2000 VM in a QEMU VM. Windows 2000 is my go-to for legacy Windows stuff in VMs, given how badly Microsoft went off the design reservation from XP onwards. QEMU also works perfectly for this use case.

Installing Windows 2000

The first step is to create a boot volume for the OS:

$ qemu-img create -o qcow2 Windows2000.qcow2 32G

Then installing Windows 2000 the VM. Note that cd means boot from drive C first, then drive D which is the optical drive. cirrus graphics will also give you the nicest experience out of the box:

$ qemu-system-i386                           \
    -m 256                                   \
    -name "Windows 2000",process=qemu-win2k  \
    -hda Windows2000.qcow2                   \
    -boot cd                                 \
    -cdrom Windows2000-Installer.iso         \
    -vga cirrus                              \
    -net nic,model=rtl8139                   \
    -net user                                \
    -usb                                     \
    -device sb16                             \
    -writeconfig Windows2000.qemu.conf

Qemu has long had a -win2k-hack option to prevent a drive full error when installing Windows 2000, but I haven’t encountered a need for it.

Once installed, grab yourself copies of Service Pack 4 and the Update Rollup 1 if they weren’t slipstreamed into your installer.

Screenshot showing the About dialog box for Solitaire, running in a Windows 2000 QEMU VM. Thanks, Wes Cherry!

USB Passthrough

I plugged the USB HotSync cable into my FreeBSD machine and the Palm LifeDrive and saw the following details from dmesg(8):

# dmesg
==> ugen1.2: <palmOne, Inc. palmOne Handheld> at usbus1
==> uvisor0 on uhub0
==> uvisor0: <Serial Interface> on usbus1    

I took that address and put it into usbconfig(8):

# usbconfig -d ugen1.2 dump_device_desc
==> ugen1.2: <palmOne, Inc. palmOne Handheld> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (100mA)
==> bLength = 0x0012 
==> bDescriptorType = 0x0001 
==> bcdUSB = 0x0200 
==> bDeviceClass = 0x0000  <Probed by interface class>
==> bDeviceSubClass = 0x0000 
==> bDeviceProtocol = 0x0000 
==> bMaxPacketSize0 = 0x0040 
==> idVendor = 0x0830 
==> idProduct = 0x0061 
==> bcdDevice = 0x0100 
==> iManufacturer = 0x0001  <palmOne, Inc.>
==> iProduct = 0x0002  <palmOne Handheld>
==> iSerialNumber = 0x0005  <PVG0C5V5V1VD>
==> bNumConfigurations = 0x0001 

This gave me the Product ID and Vendor ID that I needed to pass to QEMU:

-device usb-host,vendorid=0x0830,productid=0x0061 \

When I booted the VM, I was greeted with the Found New Hardware wizard which asked me about my my palmOne Handheld. Yay, it worked! I dismissed this dialog, because I wanted to use the Palm software to install the drivers and software.

Installing Palm Desktop

The next step was to install the associated Palm software. I created an ISO disc image of the CD that came with my LifeDrive from eBay, and uploaded to if you need a copy.

Installation was straight forward, and I soon had my familiar Palm Desktop and HotSync system tray icon. No PIM software or smartphone since matches the simple elegance of these tools!

Screenshot of the Palm Desktop, with icons for the LifeDrive Manager, Palm Desktop, and palmOne Quick Install


Now I could HotSync this device! I booted the Windows 2000 VM, pressed the HotSync button on the connector to the LifeDrive, and I was transported back to my Palm Tungsten W smartphone days. I was also able to launch the LifeDrive Manager software which I’d never used before! Now I can copy what I want over to the device, from the comfort of my FreeBSD Panasonic laptop, or my MacBook Pro.

Screenshot showing the LifeDrive Manager.


My next experiment will be to see if this Palm software works in 32-bit Wine. I’m not sure how that works with USB, but it’d be worth a try.

The ten important things about blah

I was walking home this evening and saw a billboard advertising ten ways to quit smoking. Another further down the street promised to divulge the ten steps towards financial independence. Then just as I got off the train at Chatswood, a video screen shouted in colour and sound to check out the ten best places to travel in within Australia and NZ while the outside world is unsafe. Classy!

Why are lists always in groups of ten? It’s either:

  • ten discrete things
  • the top ten of something
  • or ten steps reqired to do something

Except, ten is arbitrary. We think of it as this magical number because we use a base 10 number system (unfortunately), derived from the average number of digits we possess on our hands, feet, and brain hemispheres. Wait, scratch that last one… with your hands! But the universe generally doesn’t fit within the delightfully deterministic domiciles of decimalised demarcations. Dang.

This is why I don’t trust them. Save for the precious few times when there really are ten of something, these lists are artificially inflated from a smaller list, or some pruning went on. What was removed? What was added? What isn’t necessary?

Related to these are alliterative lists. The seven signs of ageing. The four flavours of riboFlaven (glaven). It’d be less satisfying to find out there are five styles of sausage native to a region of Germany and not six. Though I suppose that’d need to be fünf for frankfurters.

George Carlin’s Ten Commandments bit used to be my favourite deconstruction of top ten lists, but Philip Greenspun’s 10th rule of programming is the style I might start adopting for my future ones. Ruben’s thirteenth law of shirts: more than five words is too many.

Named arguments in Swift

Today I learned! Via kornel on

Yeah, I think Swift nailed it. Its overloading/default args aren’t even a special calling convention or kwargs object. They are merely part of function’s name cleverly split into pieces. init(withFoo:f andBar:b) is something like init_withFoo_andBar_(f, b) under the hood.

It’s been a while since I was a full-time developer, but I loved the Objective-C/Smalltalk messaging style over the C/C++ style for parameters, even just for the sake of readability:

Human age: 18 height : 180

I might need to mess with Smalltalk again one day. Is there a modern implementation in regular use that isn’t wed to C? Objective Rust, make it happen!