On note-taking, the meaning of notes, and what I use

Context

(FYI, this is the sort of thing that’s re-hashed over and over again …)

Some words mean many things — and while not quite as versatile as God or Fuck, Note is surely high on the list.

There are many takes on this, many apps, many opinions on what you should use, how you should use it, and so forth.

Noise

Some random articles. More random articles. Yet more random articles. We can go on. And on. And on.

I’ve found notes serve many different uses: notes can be tasks; notes can be memos; notes can be reminders; notes can be snippets of code; notes can be documents; notes can be links; notes can be transcripts; notes can be summaries; notes can extracts; notes can be snapshots.

You get the point, I hope: there will never be a final answer here; there are as many uses are there are people, maybe more. So all I’m going to do here is briefly mention what I either am using, or have used, or might use.

As it turns out, I have (1) tried out a lot of apps (occasionally falling into the “trap of the perfect” in the past too), but also (2) only use a small number of apps day-to-day.

What I no longer use

  • Evernote
  • OneNote
  • Wunderlist
  • Trello
  • Asana
  • Notion1
  • Bear
  • (lots more that I don’t remember)

What I use

DevonThink: the one indispensable tool for me, for the past several years … this is where pretty much everything is indexed for me.

Omnifocus: This is where al my tasks live, also where all Reminders flow into. With folders, projects, tags, and more, it has all the customizability I’ll ever need.

Tinderbox: Currently my go-to place to diagram, contextualize, link together stuff. Minimalist, spare, yet fully-programmable, with a uniform structure, and open storage format, I think of it as “the Emacs of note-taking software”2

What I might use3

Curio: The most feature-fun of the lot! But I don’t really have a use for it right now.

TheBrain: AFAICT this is a visually appealing, cross-platform, opinionated mashup of Tinderbox, Devonthink and Roam (at the cost of being proprietary).

RoamResearch: Used it a year and half ago, I see the appeal, but (at least right now) I don’t want to use a cloud-only product.

Notion: widely used tool now, but I’m conservative with the number of apps I use, so I’ll need to see where it fits in for me.

Looking forward

If I remember, I’ll do this again in a year, and … it’ll be interesting to see what’s changed by then. I’m quite sure DevonThink and OmniFocus will continue to be the bedrock for me, but the rest is … up for debate 🙂


  1. I still have a bunch of notes for this one, and of this list, the one I liked the most … except, I felt it didn’t do anything I can’t already do with what I have ↩︎
  2. Here’s a brief overview; five years old but still accurate ↩︎
  3. FYI, if I don’t use something, it’s not because I don’t like it, but usually because … I’m already using something else, and am no longer wiling to do any unnecessary migrations ↩︎

Ennio Morricone

I remember it was about sixteen years ago now, that someone introduced1 me to the spaghetti western genre.

This is how I came across the “dynamic duo“ of Sergio Leone and Ennio Morricone. I had watched fragments of them, but hadn’t quite seen them as movies that had anything in common, and I certainly never knew that these were Italian movies, not Hollywood ones (!)

Having seen one I had to see more, but what stuck with me more was their music, and since then, of these movies2, I’ve heard more soundtracks than seen the movies3.

It’s a distinctive sound, and I keep going back to a few favorites every few months. In his memory4, then, here are some of them:


  1. I’m usually the one introducing someone else to something new, so this doesn’t happen often, and I have a special respect for this person ↩︎
  2. Wikipedia ↩︎
  3. although, the slow takes are a good antidote to some of the fare on offer today ↩︎
  4. 1928-2020; he passed away a week ago ↩︎
  5. with the lead-in. Yes, I heard the Metallica version first. Yes, I like the original better ↩︎
  6. though, tbh, only the first half, with the epic whistling ↩︎

Of Androids and Electric Sheep

One of the covers of the graphic novel series, drawn by Tony Parker, published between 2009-2011

I’ve watched the original Bladerunner1 (many times) and the new one2 (once), but I hadn’t read the original novel3 (“Do androids dream of electric sheep?”) ever, despite repeatedly resolving to, and buying it, renting it, whatever.

I still haven’t (hah), but thanks to Comixology, I’ve done something similar, which is reading the amazing graphic novel of the same name, published in a 24-part series about a decade ago4.

There were a few … dated bits5, but c’mon, it was written over half a century ago6 now.

Something I wasn’t prepared for: it is much more than the movie, and way*, way wierder than the movie. The movie is very normal compared to the story in the book, and I can see why … there’s enough going in with the dystopian future and he grim task of retiring Androids, to then bring in Mercerism into the mix (which seems like a minor side-detail towards the beginning, but gradually seeps into the whole environment — and the graphic novel really shines in this part — contributing more to the man vs. machine question than anything in the movie.

It gave me the same feeling as the movie in parts, and I’ll admit I read some of it while listening to the soundtrack7 🙂

It’s very easy to recommend, well worth the time 8. You might expect it to be “mostly the same as the movie”, which I did too, but it truly is a whole different experience.


  1. A year before I was born ↩︎
  2. ”2049” ↩︎
  3. Fun link: here’s a list of all the various cover pictures the original book’s been published with, in different languages ↩︎
  4. available separately, or as a single Omnibus version ↩︎
  5. using physical coins to make calls, the presence of the Soviets, and … flying cars ↩︎
  6. 1968 !! ↩︎
  7. read an article about it, listen on Spotify ↩︎
  8. $9.99 on Comixology, or free with the subscription ↩︎

Using Twitter the right way (!)

Apparently there was a massive Twitter hack1 yesterday, and some folks clearly made a bunch of money2 off it too.

I didn’t notice this, though I do spend several minutes a day on Twitter. I guess it’s probably because I don’t have a lot of verified accounts that I follow, and I stick to sort of the “long tail” of Twitter.

My Twitter experience is most pleasant, and (I feel) quite informative too, which is very much the opposite of what most people experience.

I think the lesson is clear, for these “giga-social-network”3: stay away from the “home page”4, stay away from the popular stuff5.

FWIW I do the same6 at Reddit (the only other7 “giga-social-network” I allow myself to use right now). And I’ve had a similar good time there8 too.


  1. all “the big names” ↩︎
  2. can I haz bitcoin? ↩︎
  3. because mega isn’t big enough ↩︎
  4. I’m aware of the implication here: to provide this enjoyable long-tail interest-driven experience, a large mass of people endure the hell of context-less random responses, trolling, centi-threads, bans, “angry speech”, and so forth; I’m not trying to diagnose any of that here. Yet. ↩︎
  5. The folks at Wired seem to have reached a similar conclusion ↩︎
  6. i.e. don’t follow overly-popular sub-reddits ↩︎
  7. No, haven’t gotten back to Facebook yet ↩︎
  8. though again, “toxicity” and “hate” seem to be widely experienced ↩︎

Monthly Recap (Jun 2020)

Dry-erase pens on dry-erase board …

Major updates

  • A few interesting excursions (picnic in Lexington reservoir and Loch Lomond, an afternoon at Greyhound Rock Beach.
  • Trips to parks (Tara playing, farewell to a close friend, some social-distanced meeting up)

Minor updates

  • Fun on 10th wedding anniversary, fathers’ day
  • Got done with taxes this year
  • A bit disconnected in general
  • Some gardening progress (added a trellis, some seeds, stay tuned)

Watched/read/made

  • Reading My Little Pony graphic novels
  • Lots of Scooby Doo (a movie, and then the old series, from the 70s)

Generally Interesting Links- June 2020

Giant salmon, over a century ago…

Optimized Sudoku solver- Haskell to Scala

Context

As hinted at in the first post, I found Abhinav’s posts to be a great source material for learning and (over this weekend) recreation 🙂

I picked the second post, where the pruning process is tweaked to be faster.

Pruning changes

I pretty much stuck to the original code, just Scala-ized it, most of the action happens here:

  def exclusivePossibilities(row: Row): List[List[Int]] = {
    def foldHelper1(m: Map[Int, List[Int]], entry: (Cell, Int)): Map[Int, List[Int]] =  entry match {
      case (Possible(nums), idx) =>
    nums.foldLeft(m) {  (m,n) =>
          m.updatedWith(n)( (optList) => optList match {
            case None => Some(List(idx))
            case Some(list) => Some(list.appended(idx))
          })
        }
    }

    def foldHelper2(m: Map[List[Int], List[Int]], entry: (Int, List[Int])): Map[List[Int], List[Int]] = entry match {
      case (idx, nums) =>
        m.updatedWith(nums)( (optList) => optList match {
          case None => Some(List(idx))
          case Some(list) => Some(list.appended(idx))
        })
    }

    // Get map of indices to values.
    val interim = row.
      zip(Range(1,10).toList).
      filter {
        case (c, _) => isPossible(c)
      }.
      foldLeft(Map(): Map[Int, List[Int]])(foldHelper1(_, _)).
      filter(_._2.length < 4)

    // Flip map and extract list of indices.
    interim.
      foldLeft(Map(): Map[List[Int], List[Int]])(foldHelper2(_, _)).
      filter { case (k, v) => k.length == v.length }.
      values.
      toList
  }

  def makeCell(nums: List[Int]): Option[Cell] = nums match {
    case List() => None
    case List(x) => Some(Fixed(x))
    case xs => Some(Possible(xs))
  }

… which is then used by the pruning functions (the first largely kept from before, the second one something new) …

  def pruneCellsByFixed(cells: List[Cell]): Option[List[Cell]] = {
    val fixeds = cells.collect { case Fixed(x) => x }

    def pruneCell(c: Cell): Option[Cell] = c match {
      case f @ Fixed(_) => Some(f)
      case Possible(nums) => makeCell(nums.filterNot(fixeds.toSet))
    }

    traverser(cells)(pruneCell)
  }


  def pruneCellsByExclusives(cells: List[Cell]): Option[List[Cell]] = {
    val exclusives = exclusivePossibilities(cells)
    val allExclusives = exclusives.flatten

    def pruneCell(c: Cell): Option[Cell] = c match {
      case f @ Fixed(_) => Some(f)
      case p @ Possible(nums) => {
        val intersection = nums.intersect(allExclusives)

        if (exclusives.contains(intersection)) {
          makeCell(intersection)
        } else {
          Some(p)
        }
      }
    }

    exclusives match {
      case List() => Some(cells)
      case _ => traverser(cells)(pruneCell)
    }
  }

… and the replacement for the old pruneCells is:


 def pruneCells(cells: List[Cell]): Option[List[Cell]] = {
    for {
      step1 <- fixM[List[Cell]](pruneCellsByFixed, cells)
      step2 <- fixM[List[Cell]](pruneCellsByExclusives, step1)
    } yield step2
  }

View source here.

(Note: I had a bug where I had forgotten to filter out keys/values of identical length within exclusivePossibilities, which led to a few rounds of debugging … once again, I elected to leave that commit history instead of cleaning it up)

Results

sbt:sudoku> run "/home/agam/tmp/sudoku17-top-100.txt"
…
Total time: 2 s,

I found a massive speedup too (100x! … two seconds to solve the sample set of a hundred problems, instead of two hundred seconds earlier)