It’s a shame online integrations assumes that everyone’s using GitHub. I can understand why they build their products that way, and I knew that I’d loose much of those integration niceties when I moved to my own setup. Still, it would be nice to see more integrations work with any Git-based SCM.

Trying out Bayou theme by @Mtt on a test blog. Lots to like about it, especially the idea of having the latest micro-post appear in the form of a status message. Very unique.

Auto-generated description: A minimal blog page titled Leon Mika features categories like About, Archive, and Replies, along with a post mentioning categories being sorted and three other listed posts from 4 February 2025.

New AC installed and doing the best it can on this slightly humid day, although it’s performing better than the old unit. I forgot to take a photo of the old panel, so here’s a photo of the new one (the lower one is for the heater).

A digital thermostat showing a temperature of 25Β°C is mounted below another digital control panel with a touchscreen showing various settings displayed.

Already making daily note archives for 2025.

Auto-generated description: A computer interface displaying a folder structure for daily notes from 2022 to 2025, highlighting a note dated January 6, 2025.

Was not expecting the 10 mm of rain we had last night. Not sure anyone was, not even the Bureau. Put a dampener on my plans. I thought I was being super smart washing my towels in the evening and hanging them on the line to dry overnight so I could use the line for other washing today. Ah well. 🀷

Idea for UCL: Methods

I’m toying with the idea of adding methods to UCL. This will be similar to the methods that exist in Lua, in that they’re essentially functions that pass in the receiver as the first argument, although methods would only be definable by the native layer for the first version.

Much like Lua though, methods would be invokable using the : “pair” operator.

strs:to-upper "Hello"
--> HELLO

The idea is to make some of these methods on the types themselves, allowing their use on literals and the result of pipelines, as well as variables:

set h "Hello"
$hello:to-upper
--> HELLO

"Hello":to-upper
--> HELLO

(cat "Hello " "world"):to-upper
--> HELLO WORLD

The use of methods would be purely conveience. One could conceive of a type, like a CSV table, where there’s a need to perform a series of operations over it.

The potential downside of using : is that it may make defining dictionaries more ambiguous. When the parser sees something that could either be a list or a dictionary, it does a scan to search for any pairs that may exist. If so, it treats the literal as a dictionary. But would this work with using : as the method separator?

["Hello":to-upper]
--> Is this a dictionary {"Hello":"to-upper"}, or the list ["HELLO"]?

So that would require something. Might be that I need to require method invocations to occur within parenthesis for list literals.

Ambiguities like this aside, I’m planning to keep it simple for now. Methods will not be user definable within UCL out of the gate, but would be effectively another interface available to native types. For the builtin ones that exist now, it’ll most likely be little more than syntactic sugar over the standard library functions:

$hello:to-upper

# equivalent to

strs:to-upper $hello

Speaking of the standard library, the use of : as a module-function separator may need some changes. A the moment it’s a bit of a hack: when a module is loaded, any procs defined within that module is stored in the environment with the operator: strs:to-upper for example. The parser is sophisticated enough to recognised : as a token, but when it parses two or more identifiers separated with :, it just joins them up into a single identifier.

What’s needed is something else, maybe using something based on methods. The current idea is to define modules as being some special form of object, where the “methods” are simply the names of the exported symbol.

I was curious to know whether the language was capable of doing something similar now. It’s conceivable that a similar concept could be drafted with procs returning dictionaries of procs, effectively acting as a namespace for a collection of functions. So a bit of time in the playground resulted in this experiment:

proc fns {
  return [
    upper: (proc { |x| strs:to-upper $x })
    lower: (proc { |x| strs:to-lower $x })
  ]
}

(fns).upper "Hello"
--> HELLO

(fns).lower "Hello"
--> hello

A good first start. This is theoretically possible in the language that exists at the moment. It’s not perfect thought. For one thing, the call to fns needs to be enclosed in parenthesis in order to invoke it. Leaving them out results in an error:

fns.upper "Hello"
--> error: command is not invokable

The same is true when using variables instead of procs. I tried this experiment again using variables and it came to the same limitations:

set fns [
  upper: (proc { |x| strs:to-upper $x })
  lower: (proc { |x| strs:to-lower $x })
]

($fns).upper "Hello"
--> HELLO

$fns.upper "Hello"
--> error: command is not invokable

Obviously the parser needs to be changed to add additional support for the : operator, but I also need to fix how strong . binds to values too. But I think this may have legs.

My latest YouTube binge has been Drew Gooden, and his videos on YouTube and Instagram influencers and trends: an area of online culture I know nothing about. I’m kinda glad that I stayed well away from that area of the internet. Seems like more drama than I can handle. πŸ“Ί

Getting a new cooler installed tomorrow. The one I have, which I think is as old as the house, is on it’s last legs. It struggles to cool the house, only managing to keep the inside temperature steady if I turn it on early enough, and leaks profusely. I shutter to think what my next water bill will be.

The new unit’s going to be another evaporative cooler. Everyone I talk to tells me I’m crazy, and I should just go with reverse cycle. And I will agree that it’s a bit of a gamble. But it’s worth trying, given the quote I was given and the fact that I don’t have to do any major modifications to the house. If it doesn’t pan out, there’s nothing stopping me from getting reverse cycle later.

I did pick the worse time to do it though: we’re going through a heatwave that won’t break until Tuesday. At least it’ll give me an opportunity to do a fair before/after comparison.

No trains today.

Railway tracks run through a wooded area with signal lights visible along the path.

Can one have a project with a relational database that is deployed early and often, and not have thousands of SQL migration scripts? Seems like it’s difficult to have both. Maybe there’s some way to “roll up” old migration scripts into one nice SQL schema. I guess running them all on a new database and exporting the schema will do that. πŸ€”

πŸ§‘β€πŸ’» New post on TIL Computer: Local Values In Fiber

Love how the database methods for the project I’m working on are consistently inconsistent. “InsertPost”, “NewSite”, “AddUser” β€” only some of the names I’ve chosen so far. Could I, maybe, “infuse” a target? Or maybe even “interpose” a page? How about “stuff in” some styles? Where’s my thesaurus? πŸ™ƒ

Being able to “simply hook-up an interactive debugger” is a capability I wish we still had in this brave new world of micro-services and Kubernetes.

πŸ”— Mastodon Bookmark RSS

Generates an RSS feed of all the toots you bookmark. I’ve been using it these past couple of weeks and it’s been fantastic. Mastodon bookmarks are front and centre now, thanks to them being in my feed reader.

Via Robb Knight

UCL: Iterators

Still working on UCL in my spare time, mainly filling out the standard library a little, like adding utility functions for lists and CSV files. Largest change made recently was the adding iterators to the mix of core types. These worked a lot like the streams of old, where you had a potentially unbounded source of values that could only be consumed one at a time. The difference with streams is that there is not magic to this: iterators work like any other type, so they could be stored in variables, passed around methods, etc (streams could only be consumed via pipes).

I augmented the existing high-level functions like map and filter to consume and produce iterators, but it was fun discovering other functions which also became useful. For example, there exists a head function which returned the first value of a list. But I discovered that the semantics also worked as a way to consume the next element from an iterator. So that’s what this function now does. This, mixed with the fact that iterators are truthy if they’re got at least one pending value, means that some of the builtins could now be implemented in UCL itself. Like the example below, which could potentially be used to reimplement itrs:to-list (this is a contrived example, as foreach would probably work better here).

proc to-list { |itr lst|
   if $itr {
      lists:add $lst (head $itr)
      return (to-list $itr $lst)
   }
   return $lst
}

to-list (itrs:from [1 2 3 4 5]) []

But the biggest advantage that comes from iterators is querying large data-stores with millions of rows. Being able to write a UCL script which sets up a pipeline of maps and filters and just let it churn through all the data in it’s own time is the dream.

list-customers | filter { |x| $x.HasPlan } | map { |x| $x.PlanID } | foreach echo

I’ve got a need for this in the internal backend tool that spurred the development of UCL, and I’m looking forward to using iterators to help here.

A service I’m partly responsible for at work has had a number of core issues that have been plaguing us for more than a year now. We’ve been making fixes round the edge, but have left much of the core intact, lest it ties us up in a large refactor. Today I got the green light to start addressing these core issues directly. I feel so happy: I get to put away my scalpel and finally take out my sledgehammer.

It’s finally happened: the local pigeons have discovered bagels and coffee.

Auto-generated description: A small bird is walking on the floor inside a store near the entrance. Auto-generated description: A pigeon stands on the floor in front of a wooden counter inside a store or cafe.

Had a go at integrating Keycloak in a personal project. Got to the point where it kinda-sorta worked, but I’m not sure what I’m trying to prove by continuing. That I can integrate an auth service? Well yeah, but it’s a lot of work, and probably not worth it for a project where I’d be the sole user.

New ground stickers telling people not to ride on the path. We’ll see how well these work, since the sign has been such a “success”. Maybe the police emblem will help. 😏

A circular sign on the ground prohibits riding bicycles and scooters on the footpath, featuring symbols of both with red slashes through them.

Okay, I think I know why I stopped playing Wordle.

Auto-generated description: A screenshot of a word-guessing game shows the word TOCK in progress with several guessed words, color-coded hints, and navigation buttons.