Import Pinboard bookmarks into Standard Notes

In short: I wrote a tool to import Pinboard bookmarks into Standard Notes.

I care a lot about digital privacy and really appreciate the approach Standard Notes claims to take with my data. I started putting my bookmarks into the service instead of Pinboard. Pinboard is another fantastic service, but wanted to import my bookmarks into Standard Notes to have everything in one place.

So I wrote a tool to do the import! You can use it here.

It's not a terribly complicated piece of software—it transforms some JSON data into some other JSON data—but it was useful to me and I hope it's useful to someone else out there.

The code is open source if you want to give it a look.

On multi-paradigm languages

From John Carmack's Quake keynote:

Languages talk about being multi-paradigm as if it's a good thing, but multi-paradigm means you can always do the bad thing if you feel you really need to. And programmers are extremely bad at doing the time-scale integration of the cost of doing something that they know is negative.

This echoes a feeling I have: bells and whistles can cause problems for larger projects.

"Facebook Wins, Democracy Loses"

From a New York Times article:

We are in the midst of a worldwide, internet-based assault on democracy. Scholars at the Oxford Internet Institute have tracked armies of volunteers and bots as they move propaganda across Facebook and Twitter in efforts to undermine trust in democracy or to elect their preferred candidates in the Philippines, India, France, the Netherlands, Britain and elsewhere. We now know that agents in Russia are exploiting the powerful Facebook advertising system directly.

Clojure's "zero?" has some quirks

In short, Clojure's zero? isn't exactly like nil? and true? and others. It checks different numeric types and throws if given a non-numeric type.

This post was written about Clojure 1.8.0.

Clojure has a few functions that do equality checks, like nil?, true?, false?, and zero?. The docs all look about the same for these functions. nil? "returns true if x is nil, false otherwise" and the rest look similar.

But despite similar documentation, zero? is a little bit different from the rest.

Let's start by looking at true?. It accepts anything as an argument; a boolean, a string, whatever.

(true? true)   ;; true
(true? false)  ;; false
(true? "str")  ;; false

In contrast, zero? throws an error if the argument isn't a number.

(zero? 0)      ;; true
(zero? 42.0)   ;; false
(zero? "str")  ;; throws java.lang.ClassCastException

This was a little surprising to me! It's not documented and it also doesn't match the other equality checkers.

zero? is also a little smarter about different numeric types. zero? handles cases that a simple equality check doesn't.

(= 0 0)      ;; true
(= 0 0.0)    ;; false
(= 0 "str")  ;; false

(zero? 0)    ;; true
(zero? 0.0)  ;; true
(zero? "0")  ;; throws java.lang.ClassCastException

You could write a version of zero? that works like nil?, which won't throw on non-numeric input but will still work for various number types.

(defn safe-zero? [x]
  (and (number? x) (zero? x)))

(safe-zero? 0)      ;; true
(safe-zero? 0.0)    ;; true
(safe-zero? "str")  ;; false

zero? isn't vastly more complicated than I expected, but it's a little more nuanced than I thought at first glance.

Petition to open source Flash

From the petition:

Adobe is going to stop distributing and updating Flash player and the Shockwave player. That's ok.

However Flash along with its sister project Shockwave is an important piece of Internet history and killing Flash and Shockwave means future generations can't access the past. Games, experiments and websites would be forgotten.