Today I am reminded that sometimes, if you think too much about what you hope to post for the day, you end up not posting anything at all. This self-sabotage can also occur when you’re considering what to do on the morning of your first day off.
I’ve been resisting using mocks in the unit tests of Dynamo-Browse, but today I finally bit the bullet and started adding them. There would have just been too much scaffolding code that I needed to write without them. I guess we’ll see if this was a wise decision down the line.
Woot! Officially on summer break. Sure it’s only for just under two weeks, and I’ll need to be on call for one of them. Still, feetβ¦ officially up.π»
Thinking About Scripting In Dynamo-Browse, Again
I’m thinking about scripting in Dynamo-Browse. Yes, again.
For a while I’ve been using a version of Dynamo-Browse which included a JavaScript interpreter. I’ve added it so that I could extend the tool with a few commands that have been useful for me at work. That branch has fallen out of date but the idea of a scripting feature has been useful to me and I want to include it in the mainline in some way.
The scripting framework works, but there are a few things that I’m unhappy about. The first is around asynchronicity and scheduling. I built the scripting API around the JS event-loop included in interpreter. Much like a web-browser or Node.js, this event-loop allows the use of promises for operations that can be dispatched asynchronously. The interpreter, however, is not ES6 compatible, which means no async
/await
keywords. The result is that many of the scripts that I’ve been writing are littered with all these then()
chains. Example:
const session = require("audax:dynamo-browse/session");
const ui = require("audax:dynamo-browse/ui");
const exec = require("audax:x/exec");
plugin.registerCommand("cust", () => {
ui.prompt("Enter UserID: ").then((userId) => {
return exec.system("lookup-customer-id.sh", userId);
}).then((customerId) => {
let userId = output.replace(/\s/g, "");
return session.query(`pk="CUSTOMER#${customerId}"`, {
table: `account-service-dev`
});
}).then((custResultSet) => {
if (custResultSet.rows.length == 0) {
ui.print("No such user found");
return;
}
session.resultSet = custResultSet;
});
});
Yeah, I know; this is nothing new if you’ve been doing any web-dev or Node in the past, but it still feels a little clunky exposing the execution details to the script writer. Should that be something they should be worried about? Feels like the tool should take on more here.
The second concern involves modules. The JavaScript interpreter implements the require()
function which can be used to load a JS module, much like Node.js. But the Node.js standard library is not available. That’s not really the fault of the maintainers, and to be fair to them, they are building out native support for modules. But that support isn’t there now, and I would like to include some modules to do things like access the file system or run commands. Just adding them with non-standard APIs and with name that are the same as equivalent modules in node Node.js feels like a recipe for confusion.
Further exacerbating this is that script authors may assume that they have access to the full Node standard library, or even NPM repositories, when they won’t. I certainly don’t want to implement the entire Node standard library from scratch, and even if the full library was available to me, I’m not sure the use of JavaScript here warrants that level of support.
Now, zooming out a little, this could all be a bit of a non-issue. I’ve haven’t really shared this functionality with anyone else, so all this could be of no concern to anyone else other than myself. But even so, I’m am thinking of options other than JavaScript. A viable alternative might be Lua β and Go has a bunch of decent interpreters β but I’m not a huge fan of Lua as a language. Also, Lua’s table structure being used for both arrays and structures seems like a source of confusion, especially when dealing with JSONish data structures like DynamoDB items.
One interpreter that has caught my eye is Tamarin. It’s early in its development already it’s showing some promise. It offers a Go like syntax, which is nice, along with native literals for lists, sets and maps, which is also nice. There’s a bit of a standard library already in place to do things like string and JSON operations. There’s not really anything that interacts with the operating system, but this is actually an advantage as it will mean that I’m free to write these modules myself to do what I need. The implementation looks simple enough which means that it will probably play nicely with Go’s GC and scheduler.
How the example above could look in Tamarin is given below. This assumes that the asynchronous aspects are completely hidden from the script author, resulting in something a little easier to read:
ext.command("cust", func() {
var userId = ui.prompt("Enter UserID: ")
var commandOut = exec.system("lookup-customer-id.sh", userId).unwrap()
var userId = strings.trim_space(commandOut)
var custResultSet = session.query(`pk=$1`, {
"table": "account-service-dev",
"args": [userId]
}).unwrap()
if len(custResultSet.items.length) == 0 {
ui.print("No such user found")
return
}
session.set_result_set(custResultSet)
})
So it looks good to me. Howeverβ¦ the massive, massive downside is that it’s not a well-known language. As clunky as JavaScript is, it’s at least a language that most people have heard of. That’s a huge advantage, and one that warrants thinking twice about it before saying “no, thanks”. I’m not expecting Dynamo-Browse to be more popular than sliced bread (I can count on one hand the number of user’s I know are using it), but it would be nice if scripting was somewhat approachable.
One thing in Tamarin’s favour is that it’s close enough to Go that I think others could pick it up relatively easily. It’s also not a huge language β the features can be describe on a single Markdown page β and the fact that the standard library hasn’t been fully fleshed out yet can help keep things small.
I guess the obvious question is why not hide the scheduling aspects from the JavaScript implementation? Yeah, I think that’s a viable thing to do, although it might be a little harder to do than Tamarin. That will still leave the module exception issue though.
So that’s where I am at the moment. I’m not quite sure what I’ll do here, but I might give Tamarin a go, and see if it result in scripts that are easier to read and write.
One could argue that this pontificating over something that will probably only affect me and a handful of other people is even worth the time at all. And yeah, you’re probably right in thinking that it isn’t. To that, I guess the only thing I can respond with is that at least I got a blog post out of it. π
One last concern I do have, regardless of what language I choose, is how to schedule the scripts. If I’m serious about not exposing the specifics of which thread/goroutine is waiting for what to the script author, I’d like to run the script in a separate goroutine from the main event loop. The concern is around start-up time: launching a goroutine is fast, but if I want to execute a script in response to a keystroke, for example, would it be fast enough? I guess this is something I should probably test first, but if it is a little unresponsive, the way I’m thinking of tackling this is having a single running goroutine waiting on a channel for script scheduling events. That way, the goroutine will always be “warm” and they’ll be no startup time associated with executing the script. Something to think about.
Ear is still blocked so went to the doctor today to see if I can get some treatment for it. Turns out the cause is excessive mucus production, a common response from Covid-19. Doctor gave me a nasal spray which should settle things down. Fingers crossed I get over this soon.
On Using LinkedIn As A Replacement For Twitter
Just listened to Dave Winer’s recent podcast about Guy Kawasaki considering LinkedIn as a replacement for Twitter. I agree with pretty much everything Dave says on why moving to Mastodon is better, particularly in terms of interoperability. But I must add, as someone who uses LinkedIn to maintain professional contacts, there’s another reason why I cannot for the life of me see myself choosing to use LinkedIn for my social contacts, and it has to do with the user experience.
I don’t use Facebook so maybe my tolerance for sub-par UIs is lower than most1 but LinkedIn doesn’t strike me as having a UI that is pleasant to use. The whole thing is so busy and in your face. Each nav tab has an unread indicator, which really degrades the effect of that indicator when there’s something that does need your attention (take note, Apple). Random chat windows with messages from recruiters and “promoted content” popup when I open the page, getting in the way of what I was actually there to do. It’s overwhelming.
I’m sorry for anyone that works at LinkedIn, but the UI needs a huge overhaul. And don’t take this as any indication that I get no value from the service: it has lead me to new jobs and I’ve used it to get jobs for my contacts. So I do use it for my professional life.
But the prospect of using it for fun? No, thank you. I’ll pass.
-
I had to use Facebook once for work (it was to integrate with Facebooks messaging platform) so I did log in a few times, using an account with completely fake profile information. And I don’t know if it’s because I never used it at a time when the service itself was smaller and simpler, but the whole thing felt really busy and unintuitive. I found myself getting loss and not knowing where to go in order to do something. It certainly didn’t feel like a product that was conducive to posting or connecting with friends (although I know that’s no longer the goal of Facebook). ↩︎
NASAβs InSight probe has gone quiet:
Saying goodbye to spacecraft such as InSight is always difficult. Humans send these robotic probes out into the frigid depths of the Solar System to increase our scientific understanding. Over that time, they shine brightly for a few years. And then, they’re gone.
It’s strangely emotional reading about a spacecraft going dark. From Spirit, to Opportunity, to Rosetta and Philae, seeing them succumb to the elements is always a bit of a sombre moment.
Seeing the effort that goes into getting these probes out there, and the struggle to keep in contact with them, feels almost like a collective activity. Certainly I feel that, even thought I have absolutely no hand in any of these projects (I don’t even help fund the project, since I don’t live in the US and pay US taxes). And when they do go quiet, among with the sense of loss is a sense of accomplishment: seeing something operate in such a hostile environment for as long as it did.
Anyone saying that blogging is dead has obviously not been blogging.
I generally hate shopping for things like groceries and clothes, but I especially hate it for anything significant that involves quotes and sales people. It’s not so much the feeling of being taken advantage of. Just the feeling of not knowing what I need to know before going ahead with a quote, with the associated feeling that if I make a mistake, I end up with something that I’m not happy with. Sure I can ask questions about it, but now I feel like I’m leading the vendor on. Justβ¦ not a great experience all around.
The World Is Bigger Than Twitter
By this time you’re probably sick of all the takes out there about the current direction of Twitter. And a bunch more from someone who hasn’t really used the service for a year and a half β and never really got a whole lot of value from the service apart from following others I found interesting β may not be the best use of my time, or of your.
But I do have some opinions about the takes that are flowing across my various feeds, and I thought I’d air them here. I considered formulating them into some form of essay (not that I’m one to write essays) but that seemed like too much work and, honestly, I didn’t feel like an authority on the subject such that these opinions warrant that sort of treatment.
So I’ll keep it short and sweet:
- Twitter’s not the internet. It never was. It’s just a private service, one of many. Anyone who thinks Twitter is the “global town square” of anything either spends too much time on the service, or has delusions of grandeur.
- It may have cultural sway, but I think the amount that it actually has is a function of the amount of time people choose to spend there. I know for myself there has been various social phenomena have come and gone during the time I’ve been off Twitter. And yeah, I hear about them from those who spend their time there, but that’s pretty much the only people I hear it from. Certainly I haven’t heard it from those that don’t have a Twitter accounts, and most people out there in the world don’t.
- The antics of the current management feel like a distraction to me. I acknowledge that it can have a real world effect on others, but to me it’s a bit of a side show. Yeah, it’s amusing to watch from a distance, but ultimately it’s just that: amusement.
- And while we’re on the topic of being subjected to the decisions of Twitter’s new management, let me say this: I can understand a sense of loss if you got value from Twitter in the past, but I don’t understand the need to stay around with the belief that your actions will sway the direction of the company. That doesn’t seem to me like the best use of your agency. If you don’t like the direction of the company, the easiest thing you can do is leave, and encourage others to do the same. That would probably have a bigger impact on the direction of the company than all the polls, posts, and articles (and tweets) about the arbitrary decision making process of management.
- By all means move your postings to another platform like Mastodon. But consider if you’re happy replacing one platform you don’t have control over with another platform you don’t have control over. Maybe it’s time to consider something like a blog along with your own domain name. You might say that’s too much effort, and I will acknowledge that this avenue involves a non-zero amount of time and money, but I think it’s less effort than you think, and if you’re serious about writing online, it’ll probably set you up better in the long term. Sure you may not automatically get the audience or engagement you had from Twitter. And if that’s something you’re after, that’s OK. But be honest with yourself that it was always about the audience, and recognise that pursuing that comes with a cost as well: namely being able to post on a platform wholly at the pleasure of the platform owner.
I guess I can wrap all my opinions up into a single sentence: the world was always bigger than Twitter. Might be time to explore it a little more.
Bocce in Calton Gardens. Perfect day for it.
Ok, thank you for the insistent reminders, Patreon. I know my subscription for CGP Grey is coming up for renewal. You only need to tell me once. π€¦ββοΈ

Project Exploration: A Check-in App
I’m in a bit of a exploratory phase at the moment. I’ve set aside Dynamo-Browse for now and looking to start something new. Usually I need to start two or three things before I find something that grabs me: it’s very rare that I find myself something to work on that’s exciting before I actually start working on it. And even if I start something, there’s a good chance that I won’t actually finish it.
So it might seem weird that I’d write about these explorations at all. Mainly I do it for prosperity reasons: just something to record so that when look back and think “what was that idea I had?”, I have something to reflect on.
With that out of the way, I do have a few ideas that are worth considering. Yesterday, I’ve started a new Flutter project in order to explore an idea for an app that’s been rattling around in my head for about a month or two.
Basically the idea is this: I keep a very simple check-in blog where I post check-ins for locations that seem useful to recall down the line. At the moment I post these check-ins manually, and usually a few hours after I leave in order to maintain some privacy of my movements. I’ve been entertaining the idea of an app that would do this: I can post a check-in when I arrive but it won’t be published several hours after I leave. The check-ins themselves follow a consistent format so the actual act of filling in the details can be handled by the app by presenting these properties like a regular form. At the same time, I wanted to try something with the Micropub format and possibly the IndieAuth protocol.
So I started playing around with a Flutter app that could do this. I got to the point where I can post new check-ins and they will show up in a test blog. Here are some screenshots:




It’s still very early stages at this moment. For one thing, check-ins are published as soon as you press “Checkin”. Eventually they should be stored on the device and then published at a later time. The form for entering checkins should also be slightly different based on the checkin type. Restaurants and cafes should offer a field to enter a star rating, and airport checkins should provide a way to describe your route.
I’m not sure if I will pursue this any further. We’ll see how I feel. But it was good to get something up and running in a couple of hours.
Ok, I’ve changed my mind. I’m now following Mastodon users on Mastodon instead of Micro.blog. No real reason for this other than I’d prefer to keep these two worlds separate for the moment.
Reached the point in my life where I can buy a pair of runners online with the knowledge that I’ll feel comfortable in them. My feet have stopped growing ages ago, and I know which brand and model I like, so I can just continue buying the same thing. A positive development.
Working on a component design. Need to add a parameter which will store a single event type, like user-created
. But with software systems being what they are β where what you’ve built is worth twice as much as what you’re planning to build β there’s always a chance that this simple value will be extended in some way. Say that it needs to be a list of event types (user create and delete events) or characteristics of the events will need to be configured (are we interested in getting all user create events, or only those for users of a particular type). What to do?
I could go with JSON right now, making the value something like {"events": ["user-delete"]}
. But that feels like overkill at this time. There’s no guarantee that what we’re building will ever need something as advanced as this. And the price of locking us into JSON now is that it’ll make configuring and reading these values more tedious than it needs to be.
So I’m opting for a simple string value now. If it needs to be extended to something more structured, I’ll use something like comma separated values. Sure it’s one more “ad-hoc mini-language” that’ll be added to the pile, but I think there’s value in keeping things simple now. The effort that may come from building a customer parser for comma separated values seems like a cost worth paying now. And if it does ever get unwieldily, we can always move to JSON down the road.
And just from a personal perspective, part of me is resisting the immediate turn to JSON whenever we need to represent structured data. It feels like no-one builds mini-languages anymore. And yeah, I see the reason why: no need to build parsers, and “everyone” knows how to work with JSON. Still this lack of diversity feels a little sad.
Trying to get over a blocked ear that I’ve had for a week and a half. I think it’s slowly improving, but each stage seems to introduce other annoyances. Today it’s the burst of static I hear whenever I cough. I guess it’s better than last week, when the ear just remained blocked regardless of what I did.
Looking for a new project to work on. I kinda want to give Unity a try, maybe look at making a game of sorts. How I’m going to get the artwork made is anyone’s guess though. Goodness knows I can’t draw it. π€·
Update: Ok, decided against working on a Unity project. Working on Alto Catalogue instead.