Archive for February 27, 2018

Tuesday, February 27, 2018 [Tweets] [Favorites]

Paradigms of Artificial Intelligence Programming

Michael Nielsen:

Peter Norvig has just put his book (+code) “Paradigms of Artificial Intelligence Programming” on GitHub. This is a very beautiful book in the good old-fashioned AI tradition.

The macOS Versions Management System

Howard Oakley:

The first version of Revisionist listed all versions, including those for which there was no version file. This has changed: Revisionist now tells you how many versions the versions database knows about, but only lists those for which there are still files.

When you select a version in the new table view, Revisionist displays additional information about that version, including the full path to the file within the versions database, whether its contents are stored locally, whether that version can be purged or discarded by macOS, its localised file name (as will be shown when you browse versions in an app), and (when available) the name of the Mac which wrote that version. The latter can be very helpful when accessing shared storage, including cloud storage.

Howard Oakley:

Technically, within macOS, the versioning system is actually part of the Managed File Access features of the File System, and is related to the File Manager, which provides high-level access to files, and is part of the Document Architecture. It is not a background service which can be turned off or on in the way that you can with Time Machine.

If something goes wrong with the versioning system, you may find yourself unable to save documents, but Time Machine will continue to make backups as normal. If you turn Time Machine off, the versioning system continues to function exactly as it did before.


When documents are emptied from the Trash, or even deleted from Terminal’s command line using the rm command, all their previous versions are also removed from the database. That is a feature of the File System.

Howard Oakley:

The most important limitation to bear in mind is that the versioning database cannot undo deletion/removal, and there is no way to re-insert removed versions. So when you delete versions, they really are gone for good. To ensure that you are mindful of that, Revisionist displays an alert immediately after you click on the Delete button, and requires you to confirm the deletion before it goes ahead.

Howard Oakley:

Despite being almost seven years old, the version management system built into macOS is almost undocumented. Its only substantive documentation is that provided to developers to enable their apps to use it, which doesn’t describe how it works. There is nothing to explain properly to users or system administrators topics such as how and when macOS decides to purge old versions, or how the user can force it to purge them, other than using its increasingly opaque Version Browser.

Update (2018-02-28): Howard Oakley:

The biggest problem with using the Versions Browser to remove old versions is that they have to be removed one at a time, which quickly becomes tedious. You also aren’t informed as so how large each version is; as saving space on storage is a major reason for removing old versions, this is a significant shortcoming.

Decoding Dictionaries in Swift

Sam Deane:

Swift’s Codable support is really great for doing this when you’ve got JSON or a Plist, but not all dictionary data ultimately lives in a file.

For example, I was recently doing some stuff with the Disk Arbitration framework. This has a DADiskCopyDescription call which gives you back a dictionary of known keys (many of which may be missing). This dictionary only ever exists in memory.

What I really want to do in this situation is extract some of these keys into a structure or object as a way of validating that I have what I need, and discarding anything I don’t need.


The Codable support would be ideal here, except that as it comes out-of-the-box, it appears that I’d have to convert the dictionary into JSON first in order to convert it back. This seems… non optimal… so I set out to make encoder / decoder classes which just work with dictionaries.

Speed Improvements in Python 3.7

Anthony Shaw (via Hacker News):

The new LOAD_METHOD opcode replaces loading bound methods as attributes and just calling them as normal functions. Remember, LOAD_METHOD and CALL_METHOD are faster than CALL_FUNCTION for instance methods.


Keyword arguments require special treatment in the execution loop because there is no equivalent in C (which CPython is written in), some extra code has to compile 2 tuples to pass to the method.


In Python 3.7, the expected Unicode code-point size is no longer hard-coded and the methods are optimised long (mostly unusual) characters.


Matching and searching case-insensitive regular expressions is much slower than matching and searching case-sensitive regular expressions. Case-insensitivity requires converting every character in input string to lower case and disables some optimizations. But there are only 2669 cased characters (52 in ASCII mode). For all other characters in the pattern we can use case-sensitive matching.

HomePod Positioning

Jean-Louis Gassée:

A venerable Valley story doctor was brought to the patient’s bedside and, in short order, offered a simple remedy: Position the Mac as a Graphics Based Business System (GBBS). The Business System part was adman puffery meant to project gravitas, but the reference to graphics made unarguable sense: The Mac’s Graphical User Interface (GUI) was clearly a distinguishing factor at the time.

Everyone in the room loved the idea. Rather than take on the whole market, Apple would define and dominate a niche. As the Valley marketing sage put it (quoting Julius Caesar), better to be the chief of a small village in the Alps than second-in-command in Rome.


Back to today: Is there an Alpine hamlet that the HomePod can claim as its own?


Here, we have to pause and realize that the answers to the HomePod JTBD question are fragile and incomplete because the product itself is incomplete.