On line purchases

Shawn and I made pasta over video for our half year anniversary. I was extremely stressed and anxious about unrelated things, but there must be something cathartic about making a big old mess of flour everywhere because I was feeling pretty good by the time we finished.

No pics cos my raviolis were demented and I forgot to take a photo anyway. But I’ll definitely be doing it again now I know how easy* it is.

Finally pressed the button on a big Amazon order today. I’d been saving up to do it in one go and save on (free) delivery, but my toothpaste is almost empty so that pushed me over the edge. It’s arriving in three separate deliveries anyway, spread throughout the week.

I discovered almost by accident that I can order consumables as well as regular items, so along with a new tube of toothpaste I’ve bought ten litres of UHT milk. The thinking is that now I don’t have to lug the stuff back from the supermarket. I’m trying to keep shopping trips to a minimum, so this will leave more room for other items in my backpack.

This morning I woke up to a gloomy overcast, it seems the sunny weather has gone for the while. It’s nice because the cigarette smoker hasn’t been outside my window as much today.

I think I prefer the rainy days, they’re more cosy, although I realised today that compared to back home the petrichor has a very different, kinda damp smell. It’s not the same.

Why is there so much dust

Right as the old construction site finished, there is a new one starting up across the road (yeah, during the “lockdown”). Even though I have noise cancelling headphones I can still hear it. There is so much dirt in my apartment I am vacuuming thrice a week and my Macbook has dust streaks coming out of the air vents.

I’ve had a mild sinusitis ever since the work-from-home order. My nose is full of crap and my sinuses burn, and it doesn’t help that there’s a dickhead sits outside my window on his Macbook smoking all day. If I catch it in time I can close the windows and keep it out, but once it’s inside there’s nothing I can do. It gets too hot to keep the place closed up in any case.

I’m pretty angry with my living situation at the moment because it’s quite literally toxic and I feel dirty all the time and I am so damn tired, but courtesy of global events there’s nowhere to go. I guess I’ll complain about it on the Internet.

On onboarding and time management

We recently onboarded two new devs on the team (remotely!) and they’ve been fantastic. I was super pleased with how fast they picked up issues and started taking on tasks that would have otherwise bogged me down in minutiae. It was also a great feeling to see all our preparation pay off.

As a result of this in a place where I’m spending a lot more time doing philosophical work, either being asked how to solve a problem, or given a solution that causes more issues than it fixes. In these cases I can either propose a workable solution, or ignore the issues and do the bare minimum to get the change out the door. The third and more depressing state is when we literally can’t fix the problem because it is stuck in a tech debt dependency hell: something that is impossible to fix now without taking on the larger structural problems which we don’t have time to fix yet either. Business loves quick fixes, developers love abstracting problems away, but everybody hates being deadlocked by tech debt.

At the moment I’m struggling because I’m spending a lot of my time supporting the team and keeping a lid on our issues, while at the same time trying to manage a regular ticket workload. Obviously the latter is suffering, and I’m feeling anxious about that, even though I know these are unreasonable expectations to have for myself.

I suppose it takes some getting used to, and I’m sure as the new starters get up to speed it’ll be less of an issue. But it’s made me realise that my “architectural” role at a previous company really left me with some anxiety about the knowledge component in knowledge work, after 90% of our time was spent in planning and 0% of the work ever made it to production.

I should really write a post mortem on that.

On the way excitement fades

I remember the first time I blogged with WordPress. It seemed so magical, but at the same time it was this discrete entity under my control. I owned the server and the database and could do with it whatever I pleased with not a care in the world. Occasionally someone would read my posts and occasionally they were immature, and I still regret some of the things I said. But it was exciting having my own little space in the world to make words.


Contrast that with now and this blog is just another amorphous cloudy glorb with secret inner workings that I don’t care to understand let alone do anything with. The magic has been lost amongst the noise and ads and monthly subscription charges. And that’s part of how we’ve gone months between posts, dear diary.

I’m thinking now the world’s changed I should write more. The closest I’ve come to keeping a diary is my alt Twitter, locked away for nobody but myself. But that tends to capture the worst of me for no real reason other than the convenience of shouting into the void. I sometimes miss composing the odd paragraph or two for the screaming abyss. So, I suppose, that’s this.

I also remember the first time I composed a blog post on my phone, the little T9 keyboard of my Nokia 6120c worn bare from the exuberance of modern technology. Now it seems so normal to lay in bed unable to sleep and swipe out a wanky obituary to good times past. I’m sure someday I’ll fondly remember these with the same tint.

Tilt train to Maryborough & what I miss about Australia

I’m on the train to Maryborough now. At the last minute I decided to get the tilt train straight to Maryborough West rather than the slower, cheaper Gympie North train then drive the extra 45 minutes north.

I’ve spent the past week camping on Ben’s floor and as much as I love and appreciate that man, I’m ready for… camping on my parents floor. Okay, not much has changed there, but I’ll have a room to myself and I won’t be in the way all the time.

Living out of a suitcase is hard y’all! I wasn’t expecting it to be amazing, but after three weeks now I’m just about ready to head back to Amsterdam. I’m leaving on Sunday and I’m sure I’ll have changed my mind by then.

I’m of two minds about heading back to Amsterdam. On one hand it’s where my home is, but on the other I’ve lately not been enjoying my time there for reasons I can’t really put my finger on. I think the thing I miss the most is being able to roam anywhere and do as I please; in the Netherlands it’s either too cold or too crowded for outdoor activities. The second the sun comes out the entire country is out in force to sunbathe in city parks and dine crammed together on narrow city streets.

The other thing I’ve really missed is the food. I had a nightmare the other night that I went to a Dutch restaurant and they served croquette on mashed potato, the whole speaking indecipherable Dutch. I miss pub food, Asian cuisines, fresh vegetables. Arnott’s Shapes ffs. The only thing interesting about the food in Amsterdam is how expensive it is.

That’s not to say I’m not enjoying my time in Europe, but you know. I don’t think I’m going to stay there forever. I just don’t know where forever is going to be (or how long, given our current climate).

Yeah, I’m being a bit of a downer. I’m just exhausted at the moment, so hopefully a few nights with my parents should cheer me up.

Singapore

Singapore was fun. I landed in Changi Terminal 2, and took the underpass to the MRT, where I found I needed to withdraw cash. A quick escalator to Terminal 3 and a Starbucks OJ later, I was downstairs again at the MRT.

The ticket machine was not good. The EFT terminal was broken or not in use, and it would only accept up to ten dollar notes. Thankfully my OJ split my fifty and I had enough cash to get me to the hotel.

The MRT trip made me feel all kinds of nostalgia. It was mostly empty, but I got to (kinda) watch the sun rise through the window. I had to transfer from the airport line at Tanah Merah, at which point the MRT was super full and I stood up most of the way.

As we arrived closer to the centre, things started to get really familiar. The thick jungle grass, the ERP tolls, the checkerboard kerb painting. This is the Singapore I remember.

My hotel was a block or two from the metro station and it was a great relief to drop my bags and check out the amazing views from the tower.

That morning I headed out and immediately stumbled on a Japanesse style pancake place, probably the most extravagant pancakes I’ve had in my life despite living in Amsterdam. Afterwards I realised that most places in Singapore only opened after 10am and changed my plan to just walk around the city.

I saw a lot of cool stuff including Raffles Hotel and the Fountain of Wealth, but probably the highlight of my day was heading to Giant Hyperfresh, a giant supermarket with a LOT of cool Asian goodies.

raffles

Heading into the trip, one of the pieces of advice I received was to take it slowly. Spend a few hours out, then retreat to the aircon to recover. I think my morning trip was too ambitious after the plane flight because I was thoroughly shattered once I got back to my hotel.

That evening after a lot of water and several hours napping, I headed out to Clark Quay, had a chicken noodle dinner, and walked the length of the quay taking time lapses and admiring the city.

merlion(1)

As it was only a brief trip, the next day was my last day to see the city.

I started by heading out to Kampong Glam to check out the famed photogenic streets. I poked around the shops, and avoided the temptation to pick up tat, and thoroughly enjoyed the cosy streets, intense decorating, and colourful street art. I hadn’t been to this part of town the last time, and it shifted my perspective away from wanting to see the same old things to discovering new and exciting bits.

I found a nice Turkish restaurant to have breakfast. More specifically the man out the front gesturing to the menu caught my attention, then the laid back outdoor dining and large industrial fans maintained it. I was looking for breakfast, so the Menemen sounded great (it’s like shakshouka). The wait was fairly long, but it was worth it to sit in the shade and watch the hustle and bustle of the street. The meal itself was delicious and I would definitely recommend the place if you’re in the area.

After that I wandered a bit more, checking out the street art and the local shops, and finally the 7-Eleven for some fluids in the form of aloe drink.

sim lim

The other thing I wanted to check out from my youth was the Sim Lim Square electronics emporium thing. It was a few blocks walk in the beating sun, but once I got there it was an immediate air conditioned blast.

Sim Lim was exactly what I remembered, except instead of PC components it was a lot more mobile accessories. My favourites were the vast displays of USB fans, and the little upmarket photography/videography shop.

I only ended up buying one thing, which was a nice pink aluminium iPad stand for my mum for Christmas.

After this I walked back to the hotel, realising I’d barely travelled a few blocks in my entire stay. There’s so much to do in Singapore, apparently, and I wouldn’t mind spending more time there in the future.

Retro nostalgia & why my new website looks like Window 9x

For a while I’ve been wanting to update my website, but I’m really not a designer and I knew any attempts to improve on what I already had would be a haphazard mess.

I was looking for a new job as a React developer and really wanted to hone my skills, so I thought what better way than to build a new site in React?

As for design… why not pay homage to one of the most influential operating systems of my youth: Windows 9x. And for fun, why not make it all fit on a floppy disk.


The rise of retro nostalgia

Windows 9x is the loose name for the operating systems from Windows 95 through ME. They were pretty shoddily built on top of MS-DOS and kinda sucked. But they were revolutionary at the time, and we didn’t know better.

The design aesthetic, particularly in the Windows 98 era was something to behold.

In present day, retro tech is really making a comeback. One of my favourite examples of this is Paul Verbeek-Mast’s horrible excellent website which was kind of an inspiration for me through my design process.

But there are plenty of other amazing examples of retro nostalgia including the gorgeous poolside.fm streaming radio, and this fun game concept:

I spoke about this stuff at the October QueerJS meetup in Amsterdam.


It’s running on a floppy disk you guyz

Ultimately the entire site is designed to fit on a 3.5″ floppy disk, attached to a Raspberry Pi running nginx, sitting on the shelf under my TV.

That means the entire site is 1.44 mb (or less) at any given time, and served to you straight from the ’90s.

The site is using Hexo to render out the static content, which includes a bunch of custom theming to make the data hook together nicely.

It’s also using Netlify for builds and Cloudflare as a CDN, so chances are you’ll never actually have to wait for the magnetic drive to spin up. But you never know! I get a little thrill out of that.

Update: this is back on Netlify while I’m at Fronteers Conference since I don’t have time to put the pi back together.


React & open source

This site was largely built with Preact (A fast 3kB alternative to React with the same modern API). The content is built with Hexo then progressively enhanced, so you can disable javascript (with the skip link for accessibility, or in the Start menu just for kicks) and the site still mostly works.

The interface is inspired by the more nostalgic bits of Windows 98 and ME, which were my operating system of choice in my more formative years.

If I’m honest, this was a terrible choice because the (p)react lifting state/render model is not great for large applications like this, and I led myself into an architecture that’s super inefficient and hard to maintain. But at this point I dont care, it’s working pretty well.

The UI components and some of the apps have been released on Github as a library called ui95. It’s a bit rough but you can use the library to create your own sites, apps, or just as a learning tool. Interestingly Artur Bień has been working on a parallel component library of Windows 95 styled components as well, so that’s probably worth a check-out too.

Some apps were built by third parties, including Paint and originally I was planning on including Webamp but it was too big to fit in my size budget. You can check each app for license information.


Where to from here?

Not sure. I’d like to post more on my blog and maybe find a local computer group.

But in seriousness, this was a fun project and I learned a lot putting it together. I hope you get some inspiration out of it and bring back a little of the whimsy in the retro web.

The reason I cancelled my love affair with Google Home

In 2018 I wanted to buy a Google Home because I was working at ABC News on chatbots and figured immersing myself in the voice assistant hype would give me a better perspective on how to create for them.

A Google Home sits on a table in a home

Maybe I could write an app! Or at least understand better how they could fit into people's lives. I was never especially convinced of the broader applications, but it was cheap enough so I figured it couldn't hurt.

After buying a second for the bedroom and using it for a year and a half, I finally tipped over the edge and given up on the platform for good.

What's so good about Google Home?

Ultimately voice assistants have different use cases for everyone.

One of my friends uses an Alexa for music and managing the contents of their fridge. Another uses it to control home automation (and terrorize the cat).

Personally my main uses were checking the (variable Dutch) weather and asking about the time. The latter actually surprised me, it's super useful when you're in the shower or in the dead of night and don't want to open your eyes to look at a clock.

The problem was that aside from turning on and off my lights, it really wasn't doing much for me. I'm not interested in radio, could never get podcasts working, and the news is easier to read online. On top of that, finding apps on Google Home is downright impossible.

I'd say outside of Google's main offering there were no killer apps. It's not a great ecosystem.

Then the bugs

From the get-go I couldn't use the full set of functionality because I have a Google Apps account rather than a plain old Google account.

For a while I could create calendar events, but that feature disappeared unceremoniously one day. I couldn't send messages, dictate emails, or receive notifications and there was no real integration with any major Google features. I'm not sure how much of this was due to my Apps account, and how much was just missing features in general.

But the thing that frustrated me the most was the reliability of the system. In the past few months it seems to have completely tanked.

At various points I've had the assistant light up and start listening for no reason at all, switch to another gender and accent, and more recently it stopped recognizing devices on my network like my TV and smart lights.

As an isolated event this was frustrating, but the frequency it was happening killed my faith in the system.

Web & App Activity

One of the biggest sticking points for me was that for Google Assistant to work, you needed to enable Web & App Activity on your Google account.

Google app activity

This is an all-encompassing feature that logs all your interactions with Google, including searches. It's not just for your voice assistant.

I was initially hesitant to turn this on because it's super creepy having your Google searches stored in perpetuity, especially when dealing with sensitive or embarrassing topics. But I did it because I wanted the hardware assistant to, you know, actually work.

While you can delete Web & App Activity from the My Activity site, it was still kinda chilling and I started using a lot more tools like Duck Duck Go, more private windows, and Firefox Focus (a private browser for mobile which I highly recommend).

But last month after a period of Google Assistant constantly misunderstanding, getting things wrong, and at one point playing loud rock music instead of white noise in the middle of the night, I decided to turn off Web & App Activity and see what happened.

Using Google Assistant without Web & App Activity enabled

Spoiler: not much changed when I turned off Web & App Activty, which surprised me a little.

When I first started using the device this was a mandatory feature, and it wouldn't work without it. But it seems they've some done work on making the hardware devices work without logging enabled.

That said, it wasn't perfect. I lost access to my third party integrations such as LIFX lights and Chromecast controls so it wasn't a complete solution and made the devices pretty useless beyond just the time and weather.

Quitting Assistant

After a few weeks of this, I decided Google Assistant was not worth the hassle and unplugged all my devices.

The news that Google, Microsoft, Apple and Amazon all have fairly lax privacy mechanisms in place around recordings certainly helped.

So my two Google Home Minis have been sitting on my bedside table for the past week and I'm not sure what to do now.

I like the idea of voice assistants and would consider getting another in the future, but right now the Google Assistant isn't very useful. I'm not a big fan of Amazon, and I hear Siri is pretty useless too so I don't hold out hope on things changing any time soon.

From my brief question on Twitter, it doesn't seem like many others are using them for much more than basic tasks. While race to the bottom in terms of price and smartphone ubiquity has contributed to these things being in everyone's homes, I genuinely wonder where the voice assistant revolution is heading from here.

Why are React PropTypes inconsistently named?

I'm reasonably new to PropTypes in my React code and I'm always messing up the naming.

Sure "number" and "string" are easy enough, but why are "function" and "boolean" in a different format to all the others?

PropTypes cheat sheet

According to the Typechecking with PropTypes article the following types are available:

array primitive type
bool primitive type
func primitive type
number primitive type
object primitive type
string primitive type
symbol primitive type
node Anything that can be rendered: numbers, strings, elements, etc.
element An instance of a React component
elementType An element constructor (I think)
instanceOf(x) An instance of class _x_
oneOf([
  'News',
  'Photos'
])
One of the given values
oneOfType([
  PropTypes.string
])
One of the given types
PropTypes.arrayOf(
  PropTypes.string
)
An array of the given types
PropTypes.objectOf(
  PropTypes.number
)
An object with certain property types
shape({ 
  a: PropTypes.string
})
An object of a given shape
PropTypes.exact({
  a: PropTypes.string
})
An object that exact matches the given shape

Why "func" and "bool", not "function" and "boolean"?

I'm always tripped up on the spelling of "func" and "bool". Mainly because the rest of the PropTypes use full names whereas these two don't.

After asking on Twitter, a few folks suggested it might be to avoid Javascript symbol names

But that still didn't answer the question because while "function" is a reserved token in Javsascript, "boolean" definitely isn't.

Eg. assigning to function throws:

> const function = 'error';
Thrown:
const function = 'error';
      ^^^^^^^^

SyntaxError: Unexpected token function

But assigning to Boolean is totally fine:

> const boolean = 'truly an allowed keyword';
undefined
> boolean
'truly an allowed keyword'
> Boolean(boolean)
true

Further, these tokens are both allowed in an object definition:

> const ParpToots = { function: 1, boolean: 2 }
undefined
> ParpToots.function
1

The plot thickens

I wasn't really happy with the answers I was getting, so I did some Googling.

The search came up empty until I stumbled on this question on the PropTypes Github issue tracker from 2017:

Hi, I've searched a bit in the Readme and in the issues here, I did not find why we do not use Proptypes.function and Proptypes.boolean like we do for object (vs. obj), etc.

Why the shortnames? Are they reserved words? If not, it would be nice to create aliases maybe for these two ones no?

Which was followed up a few hours later with the answer:

Yes, you can't do const { function, bool } = PropTypes in JS because they're reserved words.

Which… is a little more satisfying.

Except we've already shown boolean isn't a reserved word. So what's going on? 🤔

boolean: a reserved word in ES3

Having found the reason why PropTypes doesn't use boolean, I needed to connect the dots. Why is it considered a reserved word?

I eventually landed on the MDN Docs on Javascript lexical grammar which lists the full set of reserved words for Javascript, as well as some previously reserved words from older specs.

And wouldn't you know; there's boolean sitting in a list of "future reserved words" from the ECMAScript Language Specification edition 3, direct from the year 2000.

7.5.3 Future Reserved Words

The following words are used as keywords in proposed extensions and are therefore reserved to allow for the possibility of future adoption of those extensions.

abstract enum       int       short
boolean  export     interface static
byte     extends    long      super
char     final      native    synchronized
class    float      package   throws
const    goto       private   transient
debugger implements protected volatile
double   import     public

The bingo card of Javascript features

Looking at the list there's a good mix of keywords that eventually made it into the spec. const, class, import, all big ticket items.

"boolean", however, was eventually removed from the list and is no longer reserved.

I'm not sure what it would have been for, but alongside "int" and "short" you could wager it was intended to be part of a fully typed Javascript spec.

In fact, peering through history I found a bunch of resources around typed Javascript as early as 2000 (Microsoft had an optionally typed implementation of JScript for .NET 🤯), and there's some fascinating papers from around 2005 that talk about what sounds a lot like modern day Typescript.

Whatever alternate history we avoided, "boolean" is no longer a reserved word. Regardless, it left its legacy on the PropTypes package and many a Failed prop type: prop type is invalid error in our consoles.

Vue & React lifecycle method comparison

🤔 This is a slightly older post. It deals with Vue 2 and React class components. This is probably not what you need if you’re building a new app today.

React and Vue both have fairly well defined lifecycle events which we can use to successfully navigate the mysteries of the virtual DOM.

So without further ado, let’s get down to the React vs Vue lifecycle events smackdown!

Vue and React fighting in an animated fashion. A caption reads "Bam!"

Vue lifecycle events visualised

The following demo logs out the Vue lifecycle events when a component mounts and updates.

It’s actually a fairly nice API in that everything is consistently named, even if not all of the events are strictly useful.

Vue lifecycle events on codepen

React lifecycle events visualised

React is actually the more esoteric of the two in terms of naming, but actually offers more powerful functionality (such as my particular favourite, shouldComponentUpdate).

Vue lifecycle events on codepen

Component mount compared

The basic workflow for a component is pre-mount → render → mount.

Vue has more events, whereas React is more Javascripty with an actual ES constructor.

ReactVueDescription
constructorbeforeCreateRoughly synonymous with each other. The constructor sets up the React class, whereas Vue handles the class creation for you.
dataSet data. Vue recursively converts these properties into getter/setters to make them “reactive”.
createdData observation, computed properties, methods, watch/event callbacks have been set up.
beforeMountRight before the mounting begins: the render function is about to be called for the first time.
getDerivedStateFromPropsInvoked right before calling the render method. It should return an object to update the state, or null to update nothing.
renderrenderThe virtual DOM is rendered and inserted into the actual DOM.
componentDidMountmountedThe component is now mounted. We can make any direct DOM manipulations at this point.

We can see from our lifecycle that the perfect time to hook into the process is once the component has been mounted (in React’s componentDidMount or Vue’s mounted event).

Component update compared

Component update generally follows a pre-update → render → updated workflow. Easy!

ReactVue 
getDerivedStateFromPropsSame as when mounting.
shouldComponentUpdateLet React know if a component’s output is not affected by the current change in state or props. We can use this to prevent React blowing away our changes.
beforeUpdateCalled when data changes, before the DOM is patched.
renderrenderThe virtual DOM is rendered and patched into the actual DOM.
getSnapshotBeforeUpdateRight before the most recently rendered output is committed to the DOM. Lets you save the previous state of the DOM for use after the component has updated.
componentDidUpdateupdatedAfter the DOM has been updated

Component unmount compared

When your component is removed from the page, sometimes you need to remove event handlers or clean up after any manual DOM manipulation.

ReactVueDescription
deactivatedWhen using Vue keep-alive, the component is removed from the page but not destroyed so that we can load it again later without the overhead of component mount.
activatedThe previously deactivated component is reactivated.
componentWillUnmountbeforeDestroyWhen a component is being removed from the DOM
destroyedThe component is completely gone.

Handling errors

This is something I’ve not looked too much into, but it’s possible to catch errors from child components and change the render accordingly.

This would be most useful for a top-level component (above the routes, maybe) to show an “Aw Snap” error message into your app and stop the error bubbling up.

ReactVueDescription
componentDidCatch
getDerivedStateFromError
errorCapturedAn error occurred in a child component.

Conclusion

Each has their own benefits, neither is objectively better or worse. Personally I prefer the Vue naming, but prefer the power of the React API.

After pulling this info together I’m really interested to try out Vue’s keep-alive for render-intensive jobs. It’s a cool feature I didn’t know existed.

I’m also excited to play with component-level error handling, especially for larger apps. It makes a lot of sense to catch errors in the framework rather than waiting for them to bubble up to the global error handler 😅

Anyway, hope this was helpful. I learned something.