Google and RSS: What is Dead May Never Die
There’s talk of Google “reviving” RSS this morning. Their efforts seem to be experimental at this stage so this whole thing might lead to nothing. Nevertheless, the possibility of Google even considering RSS once again is interesting, especially when you consider what happened the last time they tried to build on top of RSS.
At first I was confused as to why they’re doing this at all — and this could just be me trying to spin a narrative out of imperfect information — but I can see a few reasons why they’d want to do this. Google lives on data, especially when it comes to knowing what people are interested in. And what better signal of a person’s interest in a topic is there than an RSS subscription? I sure that’s one more data point that they can leverage when it comes to knowing which ads to display to that user. It might also help with keeping that user on Chrome. No need to use a separate feed reader when all your updates are shown to you in a “news feed” of sorts right there on the New Tab page. Also makes little sense moving to another browser once all these subscriptions have been setup, especially one that doesn’t have this feature at all (it’s interesting to see Google leveraging Chrome like this more and more).
There might actually be some intrinsic benefits to this. If Google is serious about this feature — a big if indeed — and they start ranking pages with RSS feeds higher in the search results, then that might be an incentive for more sites to setup RSS feeds. As a user of RSS feeds myself, this really would “simplify the experience of getting the latest and greatest from [my] favorite sites directly.” Of course, I’m not sure how well this will go down with publishers that rely on pay-walls and boatloads of ads to monitories their content. While it’s possible to allow people to consume your content through RSS without loosing money, I don’t think many of these publishers have figured this one out yet.
All that said, I have no interest in using this myself. I’m quite happy with my current RSS setup. The fact that this feature is only available in the canary build of Chrome and only to those in the US means that I’m not really in a position to try it out, even if I wanted to. The limited roll-out of this suggests that it’s only an experiment of sort anyway, so it’s probably wise to approach this with a large amount of caution.
But I get the sense that there are many others that have no interest in partaking in this experiment. I’m guessing that after the shutdown of Google Reader, people either moved to other feed readers, or have abandoned RSS altogether and are getting their updates via Facebook or Twitter. In either case, I don’t see them running back to Google anytime soon. It seems like people are still angry about Google Reader, and will probably not trust Google again.
Finally, the whole concept of RSS being a dead format that needs reviving indicates to me that the author of the TechCrunch article has not been around the RSS ecosystem recently. Although the use of the format may not be as widespread as it once was, there are still people that use it. Maybe the death of Google Reader was a good thing in a way: it provided an opportunity for indies and small businesses to fill the gap it left, much like a falling oak provides an open sky to new shoots. Google can try to usurp this with their experimental-only-available-in-canary-build-to-those-in-the-US efforts here, but I get the sense (or maybe it’s just hope) that the independent RSS ecosystem is strong enough that it will be able to withstand it.
As it’s been said, “What is dead may never die”.
20 May 2021
🔗 The Poetics of CLI Command Names
Naming things is hard, especially for command line tools, and I’m not the greatest person to come up with new names for things (the list of domains I’ve bought and regretted soon afterwards is a testament to that). I’ve found this post useful for providing some pointers on what makes a good name for a command line tool.
28 April 2021
I’ve been playing around with AppKit recently in an attempt to build something simple but useful. I’ve heard various things about AppKit as a UI framework. It’s not a new framework — and I do find the fact that I’m learning it at the same time it’s being replaced with SwiftUI a bit amusing — but there are a few things that I’m starting to like.
An example of one that I just learnt was how to get menu items and responders to work. Up until now I had no idea how I could connect the action of a menu item to anything other than the app delegate. Opening the code editor alongside the story board and Ctrl+dragging from the menu item action outlet did nothing if anything other than the app delegate was there. If I wanted to add a menu item that operated on something like a text view, the approach I took to date was:
- Add an
@IBAction on the
NSApplicationDelegate and link it to the menu,
- Within that method, get the content view controller from the current main window,
- Type cast it to the concrete view controller subclass that I’m using for the project,
- Do the thing.
This worked, but it was far from optimal (it actually sucked quite a bit). For one thing, adding new menu items meant adding more methods to app delegate, making it larger and more difficult to navigate. It also didn’t help with keeping methods on the relevant class: the methods were added to the app delegate but had nothing to do with the delegate itself.
But the biggest downside of this approach was that it left the menu item, enabled even when that text view was not in focus. Clicking the menu item wouldn’t crash the program, thanks to Swift’s nullability safety, but it’s far from a great user experience having a menu item that looks available but will do nothing when the user clicks it. I’ve since learnt about the validateMenuItem() method, but the prospect of modifying this method every time I wanted to add a new menu item that worked on a view did not sound appealing.
Part of me was wondering if there was a better way to do this, but I’m afraid to say that I didn’t think much about what that would be. I found a solution that worked, sort of, so I accepted it as “just the way to do this” and moved on to other things.
It was only by accident, when investigating the events in the First Responder connection explorer, that a better approach revealed itself to me. I knew it was possible to connect actions of menu items to the First Responder object in the storyboard, but I didn’t know that the list of First Responder actions was dynamic. I just imagined that there was this massive list of all the possible actions anyone will possibly need defined somewhere within the depths of AppKit, and that these were all the actions that the First Responder object would know about. It was only today that I discovered that this was not the case, and that by adding a new
IBAction method to a subclass of a view will add it as a new connection of the First Responder.
I gave this a try. I defined a new
@IBAction method on a view subclass, and connected a menu item’s action to the associated outlet that appeared within the First Responder. Sure enough, clicking that menu item invoked that method. Even better, if that view was no longer in focus, the menu item was automatically disabled.
Here’s the technique in full:
- Identify the scene element that should be the responder of the action.
- Add a new
@IBAction method to the class of that scene element. This will probably be dependent on what makes sense for the scope of the action. For example, if the action makes sense for a particular window or content view controller, add the action to the relevant controller. If it makes sense for a particular view, like a text field, then create a subclass of that view and add the action to that subclass (delegates will not work, as far as I can tell). Don’t forget to set that as the class of the view within the storyboard.
- Check to see if that action appears as an outlet in the connection explorer of the First Responder.
- Connect the action outlet of the menu item to the corresponding outlet on the First Responder object.
I’m really happy I’ve found this technique. No longer needing to go through the app delegate whenever I want a menu item to operate on a view dramatically simplifies everything. It’s possible that if I just did some more reading on this I would have found this technique anyway. After all, a framework as old as AppKit will probably not stick with such an inefficient approach to doing this. The whole responder chain thing is something that I may need to read up a bit more, but I’ve found that it also helps in my learning when I bumble along a bit and knock into the answer like I did today.
24 April 2021
For a brief period of time, when coming across a package or tool that I wanted to make a note of, I added it to this blog in the form of a link post. I’ve recently started using Pinboard for this purpose, meaning that there’s no longer a need to keep adding them here. Besides, I’ve found that their presence was cluttering up the index page a bit, not to mention the RSS feed.
So I plan to stop publishing links to packages and tools here unless I have something to say about them. The existing link posts have been deleted, and the links themselves have been moved to Pinboard. Some of them I’ve kept in the Bookmarks section, but they may not be safe even here. I’m intending to have Pinboard act as the source of truth for this sort of stuff going forward, so there may not be a need for a dedicated section for them on this blog at all.
I’ll probably keep adding link posts to articles though. At least there’s a post on the other end that may be worth reading.
P.S. I kept forgetting the name of the Pinboard service before I actually signed up to it. I think this happened at least three times in the last few weeks. I probably should have added a link to it when I came across it the first time.
19 April 2021
Jumping to the Root of a Git Repo
Sometimes, when you’re browsing your social feeds, you come across a tool or technique for doing something that you think is good to know, but you have no immediate use for it. Then a couple of hours later, while working on something else, you find yourself needing that exact bit of information.
This occurred to me this morning. While getting coffee, I saw someone post a tweet documenting a way to get to the root directory of a Git repo. Could be useful, I thought. Then, while writing a script to prep a Pull Request, I found myself needing to do exactly this.
Here is the command to jump to the root of a Git repo:
$ cd $(git rev-parse --show-toplevel)
Truly a Serendipitous Event.
13 April 2021
Showing A File At A Specific Git Revision
Here is a technique for showing the version of a file at a specific Git revision. It’s not a novel technique — there’s naturally a Stack Overflow answer for explaining this process — but I constantly forgetting how to do this and end up having to search for it. So I’m including it here just so I know where to go when I need to look this up again.
To display the contents of a file at a given revision, run the following command:
$ git show <revision>:<filename>
For example, to view the version of “README.md” on the
$ git show dev:README.md
There is an alternative form of this command that will show the changes applied to that file as part of the commit:
$ git show <revision> -- <filename>
This can be used alongside the log command to work out what happened to a file that was deleted.
First, view the history of the file. You are interested in the ID before the commit that deleted the file: attempting to run
git show using the deletion commit ID it will result in nothing being shown.
$ git log -- file/that/was/deleted
Author: The Deleter <email@example.com>
Deleted this file. Ha ha ha!
Author: File Changer <firstname.lastname@example.org>
Added a new file at file/that/was/deleted
git show to view the version before it was deleted:
9 April 2021
$ git show beforeCommit:file/that/was/deleted
On Google and Winer’s Rule One
Here’s another blog post about Google, because, why not?
It all started when I read a post from Dave Winer, in which he talks about a principal of software evolution that he applies to his work. Simply calls Rule 1, it dictates that the environment between successive versions of a software platform cannot change such that they will break any existing apps built atop it.
Rule 1 was not a joke, it was dead serious. I was sick of programmers who choose to break users and developers. I had worked with a deprecator, for years, and learned the hard way that a development process that permitted user breakage was not much of a process. Eventually the users will go somewhere where they aren’t always having to start over because a programmer changed their mind about how something should work. Sometimes breakage happens, all rules have exceptions, but you have to work really hard to avoid those situations, and usually there’s a way to do it.
This post really resonated with me. It actually reminded me of another blog post by Steve Yegge on Google GCP and their love of deprecating things. I have little experience with GCP myself, but given how they go about consumer product development, I can certainly believe this.
I know building new stuff is a lot more fun than maintaining stuff. Take it from me, a person who has list of completely unfinished, unreleased, and unmaintained personal projects a mile long. But this trigger happy approach to deprecating things is not good. Developers get value out of a platform if they are able to build and operate something on it with less effort than they would have if they didn’t use it at all. That is why they spend money on it.
If the platform vendor keeps moving the goal posts like this, meaning more effort is required just to keep their software running, then I personally don’t see the value in continued use the platform. Why would you? You’ve got plenty of work already on your plate evolving your service without having to be on the deprecation treadmill.
Google really needs to improve here if they ever want to be taken seriously as a cloud platform vendor.
31 March 2021
Up there with naming, caching, concurrency, and off by one errors, I think versioning and dependency management are two aspects of software development that is difficult.
Picking version numbers; ensuring that versions are correct; ensuring that artefacts are in sync across everyone in the team; designing a branching structure that is flexible enough to produce releases quickly, while sane enough to know which branch has what, and where new work should come from.
Coming from a place that offloaded a lot of this to build servers to one in which this is done manually is a bit of a shock to the system. It’s an excellent reminder on how much work and coordination it takes to get all of this correct.
29 March 2021
I’ve started working on a small Go tool to quickly add bookmarks to this site from the command line. This Blot.im site uses Git as the sync engine, so in order to publish the updates, the tool will need to add the changed files to Git, commit the changes, and push them to Blot.im. It does this by “shelling out” to the Git command line using the exec package.
For some reason, whenever the tool tries to run
git add with the updated files, the error code that is returned is 128. Since the error code is not zero, the tool interprets this as an error and terminates the program. As far as I can tell, the files are being added to the repository without any issues. When I run the command from the terminal, it seems to work correctly, and the returning error code is zero. I do know some shells actually add something to the error code when they succeed properly, which may explain this odd behaviour.
Interestingly, this doesn’t happen with the other tool that I’ve written to quickly write and publish posts for this site. This one shells out to Git in the same way, and I have had zero trouble with it doing so. The only reason for this discrepancy that I can think of is that this other tool is written in Swift, and there might be some difference in how Core Foundation interprets error codes.
I guess further investigation is warranted.
26 March 2021
Google Still Don’t Understand Services
It’s been a little while since I’ve though of Steve Yeggie’s platform rant on the the state of Google’s services. But spending a few hours exploring the capabilities of Google Sites, that classic blog-post has been front of mind once again.
Google Sites allows you to build and publish web-sites using a WYSIWYG designer, similar to Microsoft Front-page (anyone remember that?). These can be viewable by anyone on the public web, but when created within a Google Workplace, they could also be restricted to those that are within the workspace they are created in. This makes it a suitable choice for publishing internal sites that live within an organisation, which is what I want to use it for.
The current version of Google Sites is actually a redesign of an older version of Sites that has been around since 2008. This new version has a few niceties over the “classic” version — which is still around — like a nicer designer and better looking templates.
What it doesn’t have is an API.
Without giving too much away, I was hoping to dynamically modify the contents of the site without building something as involved like a web-app. A simple bot, or something glued together with Google App Script, would be perfect. This is possible to do with classic Google sites, but this functionality has not been ported to the redesigned version. This new version has been around since 2016, and yet the only way that the contents of the site can be changed is through the WYSIWYG editor.
If I really wanted to make the content dynamic, I’d either have to use the classic version — which is probably no longer maintain, and could be shutdown whenever Google feels like it — or take up the work to build a completely bespoke web-app.
This is a shame. It’s clear that in this instance Google has not only failed to internalise the message of Yeggie’s rant, they have actually gone backwards. It might be that they are OK with this: after all, Sites is a consumer offering and may not be targeted to those with needs that demand this feature. But this line of thinking does a disservice to their offerings. It limits what is possible with these services, and reduced the number of paths available to those that want to do just that bit more.
22 March 2021
It looks like Intel has released a series of ads that have a go at Apple’s M1 chips. From Ars Technica:
Chipmaker Intel has produced a series of ads mocking Apple’s M1 Macs, and it brought on actor Justin Long—famous for his role in Apple’s 2000s “I’m a Mac” ads opposite comedian John Hodgman—to satirize Apple’s own ad campaign.
It’s noteworthy that Intel has released ads that reference Apple’s “I’m a Mac” campaign. This is the second throwback to this campaign that I can recall: the first were a series of ads from Microsoft released shortly after
Windows 8 Windows Vista. It shows how good that particular ad campaign was.
It’s also noteworthy, after watching half of one of the ads (sorry, I couldn’t really watch the whole thing), that the comparison between the two machine don’t relate to chip performance. Attributes like the number of monitors that can be driven are fair game, although remember these are still early days for the M1 chip. But the lack of gaming on MacOS, and touchscreens Macs? I don’t see how that relates to chip performance.
This whole thing smells of desperation on Intel’s part. I think what we’re witnessing here is a classic case of disruption of Intel’s PC chip incumbency, and instead of doing what’s necessary to pivot and compete with Apple head on — something that may require dramatic changes to how the company operates — Intel is going for quick wins to reach the mind of buyers. I’m not sure it will be enough to save it, though.
18 March 2021
Web Platform Wish List: Single Tab Pages
I wonder if there should be a web-standard of some form to indicate that certain pages should not be open in more than one tab. This would be particularly useful for certain web-apps that are large enough, or complex enough, that it’s better to avoid having multiple copies of them opened at the same time.
Here’s how I’d see this working:
- Open a web page at a specific URL in the browser.
- The server returns the page content with either a specific header, or a meta-tag of some sort, indicating that there should only be one tab of this specific page opened at any one time.
- While that tab is opened, clicking a link to that URL from another page will bring you to that tab that was already opened. This will also work for links that are found outside the browser, like in emails or a chat.
A classic use case for this would be something like Google Calendar. I have Google Calendar opened in a browser tab, but I get meeting invites sent to me in another app. Clicking the invite link will bring up Google Calendar in a brand new tab, instead of simply highlighting the proposed meeting slot in tab that I already have opened.
The usual practice around miss-use can be applied here, like only applying to TLD+1 or the domains of the actual page that is requesting this feature. This should also be something that the user can override: there should be nothing stopping the user from disabling this feature or explicitly creating a new tab and copying and pasting the URL in order to open the new the page in a new tab.
This is probably something that will only be useful in a limited number of circumstances. Web-pages with content, like news and blogs, will be better of not using this feature.
Anyway, one more idea for the already huge web platform 🙂.
17 March 2021