Manual Moreale hit the nail on the head with this quote from his latest post:

The web is not dying. The web is huge. The web is ever-expanding. The fact that the web is just the same 5 big websites is a fucking lie. It’s like saying the restaurant industry is the same 5 fast food chains. It is not. It’s up to you to decide to stop visiting those 5 sites and stop ingesting their fast food content.

It feels like when these people say “the web”, they mean “whatever platform I’m addicted to.” Might be time they started trying out that URL bar that appears at the top of every browser.

👨‍💻 New post on Go over at the Coding Bits blog: Custom Import Paths In Go

Day 27: surprise

Quite surprised that this photo came out as well as it did. Was purely an accidental press of the shutter button. #mbapr

Photo of the Apple magic keyboard with focus on K, L, and M.

Interesting to see Google starting to solicit reviews for apps that came with the phone, such as the… Phone.

Screenshot of a request for a review of the android Phone app, with five unfilled stars and a message saying that reviews will be public

🔗 the biggest threat facing your team, whether you’re a game developer or a tech founder or a CEO, is not what you think

Igore the click-batey headline: this is quite a good post. Really enjoyed it. And, on the whole, I agree with the author. Via Jim Nielsen’s notes

Day 26: critter

Watch out for these ones. #mbapr

A white glyph painted on an asphalt path depicting a snake and the word 'Caution' underneath.

UCL: The Simplifications Paid Off

The UCL simplifications have been implemented, and they seem to be largely successful.

Ripped out all the streaming types, and changed pipes to simply pass the result of the left command as first argument of the right.

"Hello" | echo ", world"
--> "Hello, world"

This has dramatically improved the use of pipes. Previously, pipes could only be used to connect streams. But now, with pretty much anything flowing through a pipe, that list of commands has extended to pretty much every builtins and user-defined procs. Furthermore, a command no longer needs to know that it’s being used in a pipeline: whatever flows through the pipe is passed transparently via the first argument to the function call. This has made pipes more useful, and usable in more situations.

Macros can still know whether there exist a pipe argument, which can make for some interesting constructs. Consider this variant of the foreach macro, which can “hang off” the end of a pipe:

["1" "2" "3"] | foreach { |x| echo $x }
--> 1
--> 2
--> 3

Not sure if this variant is useful, but I think it could be. It seems like a natural way to iterate items passed through the pipe. I’m wondering if this could extend to the if macro as well, but that variant might not be as natural to read.

Another simplification was changing the map builtin to accept anonymous blocks, as well as an “invokable” commands by name. Naturally, this also works with pipes too:

[a b c] | map { |x| toUpper $x }
--> [A B C]

[a b c] | map toUpper
--> [A B C]

As for other language features, I finally got around to adding support for integer literals. They look pretty much how you expect:

set n 123
echo $n
--> 123

One side effect of this is that an identifier can no longer start with a dash followed by a digit, as that would be parsed as the start of a negative integer. This probably isn’t a huge deal, but it could affect command switches, which are essentially just identifiers that start with a dash.

Most of the other work done was behind the scenes trying to make UCL easier to embed. I added the notion of “listable” and “hashable” proxies objects, which allow the UCL user to treat a Go slice or a Go struct as a list or hash respectively, without the embedder doing anything other than return them from a function (I’ve yet to add this support to maps just yet).

A lot of the native API is still a huge mess, and I really need to tidy it up before I’d be comfortable opening the source. Given that the language is pretty featureful now to be useful, I’ll probably start working on this next. Plus adding builtins. Really need to start adding useful builtins.

Anyway, more to come on this topic I’m sure.

Oh, one last thing: I’ve put together an online playground where you can try the language out in the browser. It’s basically a WASM build of the language running in a JavaScript terminal emulator. It was a little bit of a rush job and there’s no reason for building this other than it being a fun little thing to do.

You can try it out here, if you’re curious.

Thou Doth Promote Too Much

Manual Moreale wrote an interesting post about self promotion, where he reflects on whether closing out all his People and Blogs post with a line pointing to his Ko-Fi page is too much:

And so I added that single line. But adding that single line was a struggle. Because in my head, it’s obvious that if you do enjoy something and are willing to support it, you’d probably go look for a way to do it. That’s how my brain works. But unfortunately, that’s not how the internet works. Apparently, the correct approach seems to be the opposite one. You have to constantly remind people to like and subscribe, to support, to contribute, and to share.

I completely understand his feelings about this. I’m pretty sure I’d have just as much trouble adding such a promotion at the bottom of my post. Heck, it’s hard enough to write about what I’m working on here without any expectation from the reader other than to maybe, possibly, read it. They’ve been relegated to a separate blog, so as to not bother anyone.

But as a reader of P&B, I think the line he added is perfectly fine. I think it’s only fair to ask people to consider supporting something where it’s obvious someone put a lot of effort into it, as he obviously has been doing with P&B.

As for where to draw the line, I think I agree with Moreale:

How much self-promotion is too much? Substack interrupting your reading experience to remind you to subscribe feels too much to me. An overlay interrupting your browsing to ask you to subscribe to a newsletter is also too much. Am I wrong? Am I crazy in thinking it’s too much?

I get the need to “convert readers” but interrupting me to sign up to a newsletter is just annoying. And I’m not sure “annoying” is the feeling you want to imbue in your readers if you want them to do something.

But a single line at the end of a quality blog post? Absolutely, go for it!

Some emus have moved into a nearby sanctuary a few weeks ago. I managed to catch a glimpse of one during my walk today. A rare treat indeed.

An emu standing by a wire fence.

Day 25: spine #mbapr

A cabinet in a museum showing the skeletons of prehistoric vertebraes

Day 24: light #mbapr

A city road at night, with cars driving towards the camera, and yellow, purple, and blue lights strung up above the street, featuring peacocks and Rangoli decorations celebrating Diwali

I was snakily going to suggest a “HTML naked day” to complement both CSS and JS naked day, but then I realise that that’s the default for all modern web frontend development. 😏

👨‍💻 New post on Databases over at the Coding Bits blog: PostgreSQL LATERIAL Joins

Day 23: dreamy #mbapr

The moon at night as seen through a metal gate boarded by a hedge

Simplifying UCL

I’ve been using UCL for several days now in that work tool I mentioned, and I’m wondering if the technical challenge that comes of making a featureful language is crowding out what I set out to do: making a useful command language that is easy to embed.

So I’m thinking of making some simplifications.

The first is to expand the possible use of pipes. To date, the only thing that can travel through pipes are streams. But many of the commands I’ve been adding simply return slices. This is probably because there’s currently no “stream” type available to the embedder, but even if there was, I’m wondering if it make sense to allow the embedder to pass slices, and other types, through pipes as well.

So, I think I’m going to take a page out of Go’s template book and simply have pipes act as syntactic sugar over sequential calls. The goal is to make the construct a | b essentially be the same as b (a), where the first argument of b will be the result of a.

As for streams, I’m thinking of removing them as a dedicated object type. Embedders could certainly make analogous types if they need to, and the language should support that, but the language will no longer offer first class support for them out of the box. 

The second is to remove any sense of “purity” of the builtins. You may recall the indecision I had regarding using anonymous procs with the map command:

I’m not sure how I can improve this. I don’t really want to add automatic dereferencing of identities: they’re very useful as unquoted string arguments. I suppose I could add another construct that would support dereferencing, maybe by enclosing the identifier in parenthesis.

I think this is the wrong way to think of this. Again, I’m not here to design a pure implementation of the language. The language is meant to be easy to use, first and foremost, in an interactive shell, and if that means sacrificing purity for a map command that supports blocks, anonymous procs, and automatic dereferencing of commands just to make it easier for the user, then I think that’s a trade work taking.

Anyway, that’s the current thinking as of now.

My spilling has bin partickualy bad todai!

If Alan has a problem, and Brett has a solution, but Brett’s solution is qualified with conditions that can’t be met by Alan, then Alan doesn’t have a solution.

Brett should probably just let go of this fact, rather than criticise Alan for not using his solution because of “conditions”.

Day 22: blue #mbapr

A clear blue sky, with the moon at the lower-left side of the frame, and a plane with a vapour trail near the right

Day 21: mountain

Warburton, in the Yarra Ranges. #mbapr

Looking down a field towards a shed with a corrugated tin roof with tree-covered mountains in the background with a partially cloudy sky

🔗 Hiss!

Seeing @Miraz’s post about the Morepork reminded me of this poem by C. J. Dennis that was read to us as a kid. It was in this beautifully illustrated picture book, with thick borders full of, I guess, the illustrations of the subject’s imagination.