Growing up in the country meant casual jobs were farmhands or anything manual work related. When apple picking season came around, there was always a need for available hands
which meant pocket money! I never thought it would give me analogies for later life. The first instructions when picking from a tree: do a pass and move on.
When picking apples you look for the ripest fruit first — the ones that will perish if not harvested, the ones most ready for market. With a Royal Gala you’re looking for the deepest red. You work your way around the tree in one pass, selecting as you go.
In the previous article I described a path from dynamic languages toward TypeScript, and from TypeScript toward stricter compiled languages. Rust is the end of that path — but it took some convincing to get there, and the thing that convinced me wasn't the systems programming story. It was the frontend.
The TypeScript Ceiling
TypeScript is an extraordinary tool within its constraints. The type system is expressive, the ecosystem is vast, and the developer experience — particularly with modern tooling — is genuinely good. But TypeScript erases at runtime. The types you write are a compile-time overlay on JavaScript; they do not exist when the code executes. The compiler can tell you when your model is inconsistent, but it cannot prevent every class of runtime failure.
Around 2020 I made a deliberate decision to stop language tourism — spreading effort across Python, Ruby, and PHP — and consolidate around TypeScript. I haven't looked back.
The Context Switch Cost
For several years I was maintaining professional fluency across multiple languages simultaneously. Python for data pipelines and NLP work, Ruby on Rails for server-side applications, PHP surfacing in legacy projects, and JavaScript on the frontend. Each language has its own idioms, standard library conventions, ecosystem tooling, testing patterns, and community norms. I felt more marketable in the hiring game if I could claim expertise across all touchpoints.
I wrote my first SQLite article in 2011 while debugging an Adobe AIR app. The problem was a quoting edge case; the solution was a one-liner. SQLite was a curiosity — a file-based database you used when you didn’t want to run a server.
Fifteen years later, SQLite is having a moment that few databases get to have. It’s not just embedded tooling anymore. It’s in the browser, at the edge, in production analytics pipelines, and increasingly, in vector search. The same engine, radically new contexts.
Most developers know npm install, npm run, and npm publish. The rest of the CLI tends to be discovered only when something breaks — which is the worst possible time to learn a debugging tool.
These are the commands I’ve found myself reaching for repeatedly, in rough order of how often they actually come up.
npm explain
This one earns its place every time a dependency audit or lockfile conflict appears. npm explain traces why a package is in your node_modules — which package required it, and what required that.
R has a reputation as a statistics tool — the thing you reach for when you need a regression or a publication-quality plot. That framing undersells it. The part of R that earns its place in a practical engineering workflow is its I/O story: the breadth of data sources it can connect to, and the consistency of the analysis layer once data arrives in a data frame regardless of where it came from.
The WebAssembly ecosystem has accumulated a solid set of command-line tools that don’t get surfaced well in most introductory material. Tutorials tend to focus on one language path — Rust via wasm-pack, or Go, or Emscripten — and leave the broader toolchain unexplained. This is a reference for the tools I reach for regularly: inspection, compilation, optimisation, and runtimes.
The Text Format — WAT
Before the tools: WASM has two representations. The binary format (.wasm) is what the runtime executes. The text format (.wat) is human-readable S-expression syntax — the assembly language of WebAssembly. Understanding WAT is useful for debugging and for writing minimal WASM by hand.
One of the things that drew me to Nim is the degree of control it offers over memory management without forcing you to the extreme of a borrow checker. The default experience is a garbage-collected language that feels like Python. The far end of the dial is manual memory management that compiles to idiomatic C with no runtime overhead. Between those two points is a set of options worth understanding in detail — because the right choice depends heavily on what you’re building.
There is a measurable cost to serving static images. Not a performance cost — that’s a different conversation, one I covered in an earlier post on Cloudinary as a DAM. This is an engagement cost: the gap between what a user feels when they interact with a product image and what they feel when they look at one.
A 2017 paper in Computers in Human Behavior quantified this gap directly. Blazquez Cano et al. ran a controlled experiment with 218 participants browsing fashion clothing on an iPad — split across three conditions: static images, 360° visual rotation, and tactile simulation (a scrunch gesture that deformed the fabric texture on screen). The engagement scores across dimensions like novelty, felt involvement, and endurability were significantly higher in both interactive conditions than in the control group. The static image condition scored 1.34 out of 7 for novelty — participants essentially disagreed that they felt any curiosity or interest. The interactive conditions scored 4.63 and 4.95 on the same measure. The paper is readable in full here.
A single <img src="hero.jpg"> used to be the only option. It still works — but it means serving a 2400px image to a device with a 375px screen, and serving that same image as a JPEG to a browser that would have accepted AVIF at a third of the file size. The browser has had the primitives to do better than this for years. Most sites don’t use them correctly.
Functional programming has influenced JavaScript style significantly over the last decade. Pure functions — those that produce no side effects and return the same output for the same input — are now a widely adopted convention. But JavaScript is not a pure functional language, and the path to purity with composite types like arrays and objects has some real nuance worth understanding before you reach for a pattern wholesale.
TLDR
Clone before mutating when your function receives an array or object and side effects would be a problem. Prefer shallow clones for flat structures; reach for deep clones only when you have nested data you genuinely need to isolate. Don’t clone for read-only operations — it’s unnecessary cost with no defensive benefit.
Dokku is a self-hosted PaaS (Platform as a Service) that gives you a Heroku-like deployment experience on your own Linux box. A single wget command installs all the necessary tooling. From there, you configure SSH key access, set a git remote on your project, and git push to deploy — Dokku handles the build process, waits for a health check, and performs a zero-downtime swap of the running instance.
It operates on a single host, so scaling is vertical rather than horizontal. In practice this takes you further than you might expect — a modest VPS is capable of running multiple applications simultaneously, and cloud providers can scale resources substantially before Kubernetes becomes a meaningful consideration. If you do need to move beyond a single host, the Dockerfile-based build process keeps your containers portable to GCP, AWS, or wherever you land.
I was lucky enough recently to implement Cloudinary as a DAM solution on a project. A DAM being short for a digital asset manager. This is a type of cloud service typically used in the media and entertainment sectors. They’ve been around for decades but SaaS solutions have opened up, offering these services to the wider website consumer market. This enables sites running on Wordpress or Mageneto (or any CMS) to pick up an off the shelf solution. There are real SEO and User Engagement benefits to integrating one into your asset pipeline. Lets dig in to what Cloudinary has to offer and why this can help a website.
Having been in the Javascript community for a while I’ve witnessed the building momentum towards a Functional Programming (FP) style. I think Javascript and FP are great but there is perhaps a misguided favor or emphasis put on FP as something superior. The React community help perpetuate this with the introduction of hooks, moving away from class based components (favoring functions) and libraries like Redux all employing bits of FP.
I’ve been subscribed to the Go mailing list for over 10 years. But I never really dived into the language. Work requirements never pushed me in that direction. In hindsight I regret not embracing it more. There are some qualities to it that really appeal to me. Particularly after developing a passion for Typescript and Nim.
Typescript made my Javascript world pleasurable to work in. And Nim really captured my interest. Being statically typed, compiled, optionally garbage collected with a really approachable syntax :heart:. Below I’ll try to illustrate why Im choosing Go for some tasks.
Colour blindness affects roughly 8% of men and 0.5% of women with Northern European ancestry. For a data visualisation that uses colour as the primary encoding — a choropleth, a multi-series line chart, a heatmap — that’s a meaningful share of the audience for whom the visual may be conveying the wrong information, or none at all.
The right time to test this is during design, not after a complaint. ImageMagick’s -color-matrix flag lets you simulate the major forms of colour vision deficiency directly on any image — screenshots, design exports, chart renders — from the command line. This makes it scriptable, batchable, and easy to drop into a CI pipeline alongside screenshot tests.
SVG paths are written as a single d attribute — a mini-language of commands and coordinates that describes shapes. Each command is a letter; uppercase means absolute coordinates, lowercase means relative to the current position. This is a reference for all path commands with examples, followed by a worked pie chart that puts the arc command through its paces.
Running a MySQL cluster in production eventually teaches you that MySQL’s built-in tooling is optimised for the happy path. Replication works, until it doesn’t. Schema changes are fast, until the table has 80 million rows. SHOW SLAVE STATUS reports lag, but the number isn’t always telling you the truth.
Percona Toolkit is a collection of command-line tools that covers exactly these gaps — the operational situations where the native toolset leaves you guessing. I’ve been running MySQL replication clusters for long enough to have a working set of tools I reach for reflexively. These are the ones that have earned a permanent place in that set.
A Kickstarter project finally arrived, it's a book called A New Reality: Human Values and World Population. It is a republication of a book originally by Jonas Salk. His son Jonathan Salk created this project to release an updated edition. It talks about modern-day issues primarily caused by over population creating this 'new reality'.
It's premise revolves around the sigmoid curve and how human population growth is out the point of inflection (the middle point of the curve where it transistions). All living organisms population growth follow this sigmoid curve. It can be seen with bacteria in petri dishes, fruit flies in glass containers and sheep introduced on the secluded Tasmania island. Even outside of laboratories at some point limits (food sources or waste removal) are reached causing populations to eventually plateau. Analysing human population growth we have been experiencing a period massive accaleration; And appear to be in the phase on inflection. Through this the book offers hope and warnings for the future. Many indicators suggest we have reached the turning point in human population growth (primarily that our population growth has actually started to decalerate).
A reference for chart types, anatomy, and terminology — particularly useful when working with D3 or communicating design intent to engineers and stakeholders.
Terminology
Graph — a diagram representing a mathematical function or relationship between variables, typically drawn as a continuous line. The term comes from graph theory; in common usage it is often conflated with "chart" but strictly refers to a plotted function.
Chart — a graphical representation of data using shapes, symbols, or spatial encoding (bars, slices, bubbles). Charts communicate patterns in discrete or categorical data rather than continuous functions.
We had an awesome weekend away in Bright, a small mountain town on the edge of Victoria Australia. Completing the Spartan race trifecta. The trifecta is where one completes all three of the Spartan race types (Sprint - 7km+, Super - 14km+ and Beast - 21km+). The sprint turned out to be around 9.5km and the beast was 24km which was a little more than we were expecting.
Some enthusiasts will attempt whats called an Ultra Beast where you run the Beast course twice. Effectively giving you a full marathon experience whilst completing obstacles and mountain climbs. Three crazy monkeys were attempting it on the Sunday. Two completed and one was disqualified for surpassing the time limit. I'm blown away and impressed by these individuals.
A corpus linguistics analysis of the original Italian text of the Divina Commedia — measuring vocabulary coverage thresholds and frequency distribution to quantify the reading challenge it presents to a learner of Italian.
Background
Dante Alighieri (1265–1321) was a Florentine poet whose Divina Commedia — written between approximately 1308 and 1320, the year before his death — is considered a cornerstone of world literature and a foundational text of the Italian language. The work comprises three canticles: Inferno, Purgatorio, and Paradiso, tracing an allegorical journey through the afterlife guided by the Roman poet Virgil.
A frequency analysis of Harry Potter und der Stein der Weisen using Python and NLTK, exploring what corpus linguistics reveals about the vocabulary threshold for reading comprehension in a second language.
Methodology
The source text was processed using NLTK (Natural Language Toolkit) in Python. The pipeline: tokenize the raw text with nltk.word_tokenize, lowercase and strip punctuation, then build a frequency distribution with nltk.FreqDist. Stopwords were deliberately not removed — function words like articles, pronouns, and conjunctions are exactly what a language learner needs to acquire, and stripping them would distort the comprehension model.
OK quick note, Netbeans is an awesome IDE. Love the debugging options an set to xdebug default options. So it just works when running Linux PHP Xdebug. Was a life changer when someone showed me how about six months ago.
Silver Stripe is also an awesome PHP framework/cms. But .ss files the ones used by the Silver Stripe templating system don’t get recognised by Netbeans. A quick Google resulted in a few incomplete forum results. I’m using Netbeans 7.2 and it took under a minute once I knew where to go, to enable syntax highlighting and code completion (apart for ss template tags).
So apart from needing to redesign/rebuild my site, I really need to start writing more about my experiments. More for my own record than a public one.
Recently started playing with the whole Nutch family (Hadoop, MapReduce, Hbase, Pig, Solr, Nutch,… etc). I finally got Nutch 2.1 set up with Cassandra 1.2 (that in itself should be another article) with the aim to run data extraction and post to Solr’s Lucene index. Initially I’ve just indexed my own site, but need to inspect the Cassandra data. Been playing with pycassa with some success (the library rocks I just suck at python), and looking at some gui’s. But now settling on CQL as a means to navigate the data. In this post I hope to record the queries I’m yet to use to inspect a Cassandra Nutch data store.
Some notes about using sprites from Flash Professional in Flash Builder.
1 When adding Sprites or Movie Clips to a Flex application add them to a UIcomponent first or use rawChildren.addChild() to avoid run time errors.
fx:Script
spritecanvas.addChild(new Sprite());
// OR
this.rawChildren.addChild(new Sprite();
</fx:Script>
<mx:UIComponent id=“spritecanvas” width=“100%” height=“100%">
2. The information on labeled timelines and labeled movieclip instances remains intact
fx:Script
[Embed(source=”../sprites/Demo.swf", symbol=“test”)]
private var TimeLineTest:Class;
var TestTimeLine:MovieClip = new TimeLineTest() as MovieClip;
TestTimeLine.gotoAndPlay(’timelinelabel’);
// accessing sub movie clips which have been given an instance name in Flash Professional
// TestTimeLine.inception == MovieClip
</fx:Script>
3. AS3 code however does not remain intact but stop() commands do (I’m wondering if I’m missing a flag here when embedding)
A movie clip symbol in Flash Professional which is given a base class of the following
Duplicating an Eloquent model — without its primary key, without timestamps, without accidentally overwriting the original record — is a small problem with a few subtly wrong solutions before you arrive at the right one.
The clone keyword
PHP has a built-in clone keyword that produces a shallow copy of an object. Scalar properties are copied by value; object properties are copied by reference. For a database model, the defaults are almost never right: the copy shares the same id, its exists flag is still true, and any object-type properties point to the same instances as the original.
Some notes about using sprites from Flash Professional in Flash Builder.
When adding Sprites or Movie Clips to a Flex application add them to a UIcomponent first or use rawChildren.addChild() to avoid run time errors.
<fx:Script>spritecanvas.addChild(new Sprite());
// OR
this.rawChildren.addChild(new Sprite();
</fx:Script><mx:UIComponentid="spritecanvas"width="100%"height="100%">
The information on labeled timelines and labeled movieclip instances remains intact
<fx:Script> [Embed(source="../sprites/Demo.swf",symbol="test")]
privatevarTimeLineTest:Class;varTestTimeLine:MovieClip =newTimeLineTest() as MovieClip;TestTimeLine.gotoAndPlay('timelinelabel');
// accessing sub movie clips which have been given an instance name in Flash Professional
// TestTimeLine.inception == MovieClip
</fx:Script>
AS3 code however does not remain intact but stop() commands do (I’m wondering if I’m missing a flag here when embedding)
A movie clip symbol in Flash Professional which is given a base class of the following
I’ve been building a component for Joomla 1.5 and I really wanted to use Jquery in the admin over Mootools. Unfortunately Googling for this answer is tricky as so many people are posting examples how to remove Joomla js from their frontend template. The following is very ‘hacky’ but if you’re feed up with the Joomla API and want to throw together a component, without mootools, it’s useful. It stops the need to export jQuery into a different name space, therefore breaking 3rd party jQuery plugins.
A note from a series of posts on AIR and SQLite. At the time, I needed to put together an analytics tracking library for an AIR application — Google Analytics only supported Flex apps with DOM access, so it wasn’t available in AIR. That constraint pushed me toward building a custom persistence layer to buffer and batch events locally before syncing them upstream.
Wanting a cleaner approach to persistent data in AIR, I started writing my own DataObject class to handle saving and retrieving records. While writing it I assumed someone had already solved this problem — and sure enough, they had.
An interesting quirk about SQLite table primary keys. Coming from MySQL I had been using ID INTEGER PRIMARY KEY AUTOINCREMENT as a habit, but it turns out SQLite primary keys only behave as a rowid alias under specific conditions.
This is worth getting right. Primary keys return SELECT and ORDER BY queries roughly twice as fast as a normal column search. SQLite creates a separate ROWID column by default for all tables that don’t have an integer primary key. Only when another column is explicitly declared as INTEGER PRIMARY KEY ASC will SQLite skip creating that default rowid column.
Following on from the previous post, here’s a solution for INSERT or UPDATE if the row exists — a fairly desirable behaviour that saves the usual SELECT if exists, then UPDATE else INSERT routine.
This sounds like it would be a straightforward fix, but I couldn’t find a single article relating to Adobe AIR/Flex insert-or-update at the time. Reading the SQLite docs helped considerably.
I was trying to SELECT column FROM Table WHERE id="ID" and branching on the result to INSERT or UPDATE respectively. The answer turns out to be quite straightforward and works similarly to MySQL’s REPLACE:
Spoiler: Double quote string values in SQLite statements (Possible solution this error is raised by many misconfigurations).
With SQLite in Adobe AIR, I was running some initial tests to figure out a clever TRIGGER to UPDATE or INSERT appropriately.
So far I’ve been writing all my queries in Flex, writing statements manually for instant feedback. I encountered the #3115 Error. Searching through Google I see a lot of posts about this. The answer it seems is widely varied. Other possibilities include incorrect path to applicationStorageDirectory or invalid table names. My issue (to the best of my knowledge) was a reserved word inside single quotes.
JavaScript’s built-in Date API is famously awkward. For most production work, Day.js is the right answer — it’s a 2kb drop-in that gives you immutable date objects, a chainable API, and a plugin ecosystem that covers almost every edge case. But if you’re keeping dependencies lean, or you just want to understand what’s happening under the hood, native Date gets you further than most people realise.
What follows is a comprehensive reference for the patterns you’ll reach for repeatedly.