Micro Review: Gideon Falls

I’ve seen Gideon Falls mentioned often, but to be honest I kept confusing it with Gravity Falls.

The difference is: Gravity Falls is a rather entertaining cartoon with a bit of mystery that may entertain small kids, while Gideon Falls is a horror comic series that may traumatise them for life.

Read more for my opinion of it, but beware the mild spoilers.

cover for Gideon Falls Deluxe Edition (Book 1)

Gideon Falls is a comic written by Jeff Lemire and penciled by Andrea Sorrentino, centred around a group of people that enter in contact with a mysterious black barn.

It’s partly Lovecraft cosmic horror stuff, partly Stephen King’s The Dark Tower, and a sprinkle of David Lynch’s Twin Peaks.

The story touches on multiverses and time travel, which these days brings to mind the horrible way the Marvel Cinematic Universe does this, but it’s done with talent, so it does not suffer from the devaluation of any action done by the characters. On the contrary things have gravity and piece fall in place as they should. In spite of this, the plot is somewhat linear (but not without twists!).

The art is quite good. The style per-se is not my favourite, but the composition of the scenes and pages is beautiful, and you feel a lot of effort went into this.

I read this over a few days, and I probably didn’t pay enough attention to it, I think a re-read might reveal a lot of hidden gems and hints that I missed on the first read.

The series won 2 Eisner Awards (best new series and best colouring), when it came out a few years ago, make of that what you will.

I liked it enough that I’m going to try and read more of the Lemire/Sorrentino duo, since they seem to have been quite productive.

Vote: 7/10, I will read more by the same authors.

A memoize macro in Elixir

During my 2024 Advent of Code, I decided to try and write some solutions in Elixir. I knew almost nothing of it, and after a month or so with it, I still know basically nothing but I had fun.

I also solved the problem with Ruby, so most days I limited myself to translating the solution from one language to the other, which is pretty straightforward: both Elixir and Ruby have high level data types (lists, sets, dictionaries, regular expressions), similar functions/methods to work with them (map, reduce, sum, etc) and you can typically convert things line by line. There’s one big difference tho.

State

Elixir is mainly a functional language, so if I had written something in ruby which used mutable state (pretty natural) I’d have to do a bit more work when translating it.

For example, many AoC problems require writing a depth-first-search or a variation of that (Dijkstra, A* etc), I’d write that imperatively in Ruby mutating state (e.g. push/pop things from a queue), but doing it in Elixir you’d carry the state in an additional function argument.

This generally works fine, but at some point I wanted to try something different, since there’s a lot of AoC problems solved with dynamic programming and memoization.

Typically, the first part of the problem is something that can be brute forced, and the second part requires you to apply memoization in a smart way, understanding what is the “state” you care about.

In languages such as Ruby/Python/Perl/Raku you generally do this with some metaprogramming that converts a method/function into its memo-ized equivalent, so you’d go from something like e.g.

  def fib(n)
    if n < 2 do
      n
    else
      fib(n - 1) + fib(n - 2)
    end
  endCode language: Ruby (ruby)

to

  memoize def fib(n)
    if n < 2 do
      n
    else
      fib(n - 1) + fib(n - 2)
    end
  endCode language: Ruby (ruby)

Alas, this was a bit tricky to do in Elixir.

Memoization in Elixir, done bad

At first, I thought I’d write a higher order function that just wrapped the code with a cache check

    def make_memo(fun) do
      cache = %{}
      fn args ->
        case Map.get(cache, args) do
          nil ->
            result = apply(fun, args)
            cache = Map.put(cache, args, result)
            result

          result ->
            result
        end
      end
    endCode language: Elixir (elixir)

Something like this might work in Scheme or other mostly-functional languages, but this does not work in Elixir: re-assigning to cache creates a different variable, rather than update the existing one. The Map object is also immutable, so I can’t update it in-place.

Luckily, Erlang (and thus Elixir) come with two mutable dictionaries you can use!

The Erlang Term Storage (ETS) is a shared dictionary that is writable by the current process and readable by all. The Process dictionary is, well, a per-process dictionary which is also mutable. I do not really know what the specific limitations are for either, and I was going to have a single process anyway, so I went with the latter purely on aesthetical reasons.

Thus I could write code like this

  defmodule Demo do
    def make_memo(fun) do
      fn arg ->
        # try to avoid the most obvious name collisions
        case Process.get({:memo, fun, arg}) do
          nil ->
            result = fun.(arg)
            # mutable state baby!
            Process.put({:memo, fun, arg}, result)
            result

          result ->
            result
        end
      end
    end

    def slow_math(n) do
      IO.puts("slow computation..")
      n * n
    end

    def main() do
      IO.puts(slow_math(10))
      fast_math = make_memo(&slow_math/1)
      IO.puts("should only execute this once:")
      IO.puts(fast_math.(10))
      IO.puts(fast_math.(10))
    end
  end

  Demo.main()Code language: Elixir (elixir)

And executing this seems to show the memoized function is indeed only executed once

  $ elixir fib.ex
  slow computation..
  100
  should only execute this once:
  slow computation..
  100
  100Code language: Bash (bash)

My code is still broken tho! While it works for this simple function, it would not work for e.g. a standard recursive fibonacci:

    def fib(n) do
      IO.puts("fib(#{n})")
      case n do
        0 -> 0
        1 -> 1
        _ -> fib(n - 1) + fib(n - 2)
      end
    end

    def main() do
      fast_fib = make_memo(&fib/1)
      IO.puts(fast_fib.(4))
    endCode language: Elixir (elixir)

This outputs

  $ elixir fib.ex
  fib(4)
  fib(3)
  fib(2)
  fib(1)
  fib(0)
  fib(1)
  fib(2)
  fib(1)
  fib(0)
  3Code language: Bash (bash)

And you can see the output multiple times for each number.

What is wrong here is that the function calls itself, and not the memoized function. If you wrote a memoizing function in Ruby or Python you’d (likely) be shadowing the existing one, so that each call would then hit the memoized one.

But I can’t do this in Elixir (or perhaps I can and I just don’t know how, I’m a newbie).

The obvious fix would be to alter the function to receive a reference to itself as an extra argument, but that means I need to also update all call sites which is ugly and boring. There’s a solution which is more fun.

Macro all the things!

Elixir is largely built from macros. Many (all?) of the various defsomething are macros. The Elixir developers advice against overusing macros but a project that you’re doing for fun and literally lasts one day seems like a good fit.

The idea is the following: rather than define a base function and then wrapping it with something else, we will define a function using a body and wrapping it with our caching logic.

The only function will be the one we define, and thus any recursive call will hit the same macro-defined memoized function.

The main thing to remember about Elixir macros is:

  • quote is used to generate code
  • unquote is used to insert values into a quoted expression

It may help to think of them as “defining a string” and “interpolate a value in a string“.

The standard example from the Elixir docs is to define an unless (“if not”) macro

  # usage: macro_unless(condition, do: something)
  defmacro macro_unless(clause, do: expression) do
    quote do
      if(!unquote(clause), do: unquote(expression))
    end
  endCode language: Elixir (elixir)

you can imagine this as more or less

 macro_unless = "if !#{clause}, do: #{expression}"Code language: Ruby (ruby)

You can see how the macro will get the block of code in the do argument, via either the inline do: or the block-based do ... end form.

But function definitions have more than a single word as condition, what is their shape? Well, you can find out easily, spin up an elixir shell and use quote

  iex(1)> quote do def fun(arg), do: whatever end
  {:def, [context: Elixir, imports: [{1, Kernel}, {2, Kernel}]],
  [
    {:fun, [context: Elixir], [{:arg, [], Elixir}]},
    [do: {:whatever, [], Elixir}]
  ]}
Code language: PHP (php)

AKA

  • literally the :def symbol
  • some “context”, whatever that is
  • an array containing
    • the “head” of the function (name, more context, arguments, etc)
    • the “body” of the function.

Elixir provides a handy helper Macro.decompose_call/1 to extract function name and argument names (and ignore the various “contexts”), so our final implementation of a defmemo macro looks like this

  defmacro defmemo(head, do: block) do
    {func_name, args} = Macro.decompose_call(head)
    quote do
      def unquote(func_name)(unquote_splicing(args)) do
        key = {:memo_cache, __MODULE__, unquote(func_name), unquote(args)}
        case Process.get(key) do
          nil ->
            result = unquote(block)
            Process.put(key, result)
            result

          result ->
            result
        end
      end
    endCode language: Elixir (elixir)

Notice the unquote_splicing, in our “macros are string definition+interpolation” simile, this is the equivalent of “join the values with a comma“.

The last step is putting this all together, the only thing to keep in mind is you need to put the macro in a separate module before using it

  defmodule Memo do
    defmacro defmemo(head, do: block) do
      {func_name, args} = Macro.decompose_call(head)
      quote do
        def unquote(func_name)(unquote_splicing(args)) do
          key = {:memo_cache, __MODULE__, unquote(func_name), unquote(args)}
          case Process.get(key) do
            nil ->
              result = unquote(block)
              Process.put(key, result)
              result

            result ->
              result
          end
        end
      end
    end
  end

  defmodule Demo do
    require Memo

    Memo.defmemo fib(n) do
      IO.puts("fib(#{n})")
      case n do
        0 -> 0
        1 -> 1
        _ -> fib(n - 1) + fib(n - 2)
      end
    end

    def main() do
      IO.puts(fib(4))
    end
  end

  Demo.main()Code language: PHP (php)

And executing this it seems to work

  $ elixir fib.ex
  fib(4)
  fib(3)
  fib(2)
  fib(1)
  fib(0)
  3Code language: Bash (bash)

Success!

defmemo, how are thee broken? Let me count the ways. 

This implementation was enough for me to solve Day 19 of the 2024 Advent of Code, and I am very proud of myself for having managed to do it, tho 90% of the credit goes to Saša Jurić for his articles on elixir macros.

But beware: this code is still utterly broken, and that is my fault 🙂

For example, functions in Elixir can be defined multiple times using pattern matching, and can have guard clauses

  def fib(0), do: 0
  def fib(1), do: 1
  def fib(n) when n > 1 do
    fib(n - 1) + fib(n - 2)
  endCode language: Elixir (elixir)

If you try to replace def with defmemo it will not work.

Likewise, functions can be defined multiple times with different arity (number of arguments), and that will also not work. Functions can also have default arguments, and I’ve not even tried to see how those work.

I’m also not sure I used the Process dictionary properly, and I think there’s a lot of room for name clashes. So, in short do not use this code.

If you’re looking for a proper defmemo you better use one of the established modules such as https://github.com/melpon/memoize.

Still, I hope you enjoyed this short tour of how to write an elixir defmemo macro as much as I did. And notice I’m still a wildly incompetent Elixir programmer, so feel free to correct me in comments if anything I wrote is too far from the truth.

Micro Review: Dodger

Dodger is a non-Discworld novel of the late Sir Terry Pratchett, set in Victorian London, following the adventures of a “tosher”, AKA someone who looks for valuables in the sewers. A few “known faces” appear in the book such as Charles Dickens, Benjamin Disraeli, Sweeney Todd, Robert Peel, etc.

But, I gifted this book to my wife a few years back, and it took me a long, long time to actually read it. I loved Pratchett, I literally learned English on his books but getting through this was a bit of a slog.

There’s some funny bits, but it’s not nearly as brilliant as your average Discworld novel. It’s also very lengthy for no obvious reason, there are just a lot of things that happen which do not seem to add anything to the story.

I enjoyed the depiction of old London, learned a few things (did you ever imagine the Romans had a Goddess of sewers? Just the kind of trivia Terry would put in a book), but still not enough to cover for the rest.

Perhaps this was just the author trying something new. Perhaps it was his disease advancing. Perhaps it’s just me being angry at him for getting an incurable degenerative disease and dying. People should be more sensible than that.

The end result is I didn’t like this book., but it’s not bad, so consider giving it a try if you’re a Pratchett completionist, or perhaps a Dickens one.

Vote: 6/10, meh.

Micro Review: Fragile Things

I started listening to this audiobook around the time Vulture’s article about Neil Gaiman came out.

This book contains some of my favourite stories, not just by the author, but among all stories I’ve read and I remember, such as A Study in Emerald, which is probably my favorite fanfiction of both Sherlock Holmes and the Cthulhu mythos.

But the behaviour described in the article is so fowl I cannot in good honesty recommend the experience of listening to the author’s voice reading his own words after knowing of the accusations.

I’m no prude, I’m no judge, I’ve got my own opinions and I’ll bite my tongue and keep them to myself.

But I can say this felt like a punch in the gut. The folks over at Fumettologica (in Italian, use some translation service) have a very nice article on why this is so upsetting. We thought Gaiman was one of the good ones, this feels like betrayal (and I am in no way trying to say the fans’ feelings are comparable to the victims’).

Anyways, I’d suggest if you want to experience the stories, maybe get the Dark Horse collection via Humble Bundle, or pick the book at a library.

He’s rich enough and won’t suffer from this either way, but it may make your soul feel a bit better.

Micro Review: Something Wicked This Way Comes

I was reminded of this book while reading the short story The Man Who Forgot Ray Bradbury, by Neil Gaiman, which was reprinted in Trigger Warning.

I realized I’ve read very little of Ray Bradbury, the greatest sci-fi writer in history, and I thought I should fill this void a bit.

Given the crazy amount of stuff he wrote, I would have been troubled to choose. Likely, this one has the catchiest title.

In some ways, it was exactly the story I expected: Small Town America gets in touch with capital case Evil. A Carnival is involved, which seem to be a scary thing in US pop culture, like clowns. Or perhaps they started being scary with this story, it’s hard to tell.

The story has kids in it, so, to me, it felt like going home. How many stories I’ve enjoyed, of kids dealing with the supernatural in small american towns? From King’s “IT” to Netflix’s “Stranger Things”, I’ve visited this topos a hundred times.

And as usual, I enjoyed it. I didn’t find this book particularly original (could be a case of Once Original, Now Common), but it is certainly well written and entertaining, the characters are lively and the dialogs feel real. I also feel I missed some sub-text and meanings, so I welcome anyone who’d like to point me to some literary analysis of the work.

It did not leave me wanting for more tho, so I think it’ll be a while before I move on to other Bradbury works.

Vote: 6.5/10, good, just not as good as I expected.

Micro Review: un po’ di fumetti

(post in Italian)

Nel 2024 ho letto un bel po’ di fumetti, questa è una lista del penultimo carico

Nero 1-8 (Bonelli Audace)

Ottima l’idea: il medio oriente durante le crociate, ma in versione magica dove gli esseri umani si confrontano con forze soprannaturali, con buoni e cattivi sia tra i musulmani che tra i cristiani. Belli i disegni, storia ok. I personaggi mi sono sembrati tutti abbastanza stereotipati. Per qualche ragione piace un sacco a mio figlio.

Non sono un fan del formato (e del prezzo!) ma è una bella edizione.

Voto: 7/10, continuerò a comprarlo.

L’ignobile Shermann (Saldapress)

Un vecchio pirata che tutti odiano muore e lascia un’eredità a un gruppo di eredi sconclusionati. Per qualche ragione mi aspettavo Shermann come Barney nel libro eponimo (La versione d Barney). Ma no, effettivamente Shermann è un personaggio 100% negativo. E all’inizio sembra lo siano anche gli eredi, ma poi d’un tratto cambiano. Cambiamenti un po’ immotivati a mio avviso.

Disegni belli, ma non il mio stile.

Voto: 6/10, la copertina è meglio del libro.

Nathan Never: Il Giorno del Giudizio

Vent’anni fa compravo ogni uscita di Nathan Never, poi ho smesso. Ne ricompro qualcuna ogni tanto quando vado in Italia, ma mediamente le trovo deludenti.

Il giorno del giudizio è la ristampa di tre fumetti pubblicati una decina d’anni fa (vedi la recensione del primo numero su Spazio Bianco). È una buona storia con bei disegni, ma sempre più spesso mi capita di trovare i dialoghi dei fumetti italiani macchinosi e finti. Un po’ come succede con il doppiaggio nei film, dove attori bravissimi si trovano a parlare un doppiaggese che non esiste (“ehy amico stai attento, o quel fottuto bastardo ti farà fuori” e giù di lì).

Voto: 6.5/10, forse non sono più il pubblico di Nathan Never

Quando muori resta a me

Ennesimo capolavoro di Zerocalcare. Commovente a tratti, divertente per la maggior parte. Piaciuto anche a mia moglie che è cresciuta lontana dal GRA.

Forse un po’ troppi temi, ma è un libro molto intimo dato che tratta del rapporto dell’autore col padre e della sua famiglia, quindi chi sono io per criticarlo?

Voto: 8/10, Zerocalcare non delude quasi mai.

Docteur Mystère – L’integrale

Esiste (?) un personaggio creato da Paul d’Ivoi alla fine del 1800. Nel 1998 Alfredo Castelli e Lucio Filippucci hanno deciso di mischiarne la storia con Martin Mystère, e poi han finito per scrivere alcune storie dedicate solo a lui.

Quando ho scoperto che esisteva un’edizione integrale pubblicata dieci anni fa, ho deciso di leggerla, pur non essendo un lettore di MM. Non è stato facile procurarsela, ma alla fine ce l’ho fatta.

Il Docteur è geniale, atletico, onorabile e strapieno di sé. Una specie di Capitano Nemo + Batman + Poirot. Le storie so scritte in modo ironico e auto-caricaturale e hanno continui rimandi alla lettura di inizio secolo scorso, nonché a eventi e persone del periodo (il maresciallo Radetzky ke parla kome uno tetesko di Sturmtruppen è stato esilarante per i miei figli).

È un divertissement surreale e a tratti demenziale, con storie che non hanno granché senso, ma a me ha divertito molto, e questa specifica edizione è molto bella e ricca di contenuti extra.

Voto: 8/10, lo rileggerò.

Micro Review: Way Station

I don’t have proof, but I think the ’60s had the best sci-fi. Looking at the list of Hugo Award for best novel there’s not a book in the ’60s which isn’t absolutely great. But I have not read them all, so I decided to pick up the missing ones.

I think this one is free if you have an audible subscription, so if audiobooks are your thing give it a go.

Way Station by Clifford D. Simak is one I missed. The premise is quite original: Enoch Wallace is an American civil war veteran who ends up managing an interstellar traveling station in his house, apparently made immortal, and being more in touch with aliens who pass by than with his own world.

I won’t give spoilers, but the book seems to have a few ideas that may have deserved a better exposition, and some things seem just a bit forced. Enoch is a wonderful character, but there’s basically little else.

Still it’s a an original and optimistic piece from 80 years ago, and I enjoyed it.

Vote: 6.5/10, you can’t go wrong with the ’60s sci-fi

Micro Review: You Like It Darker

Following up on my summer trend of reading short stories, I got this recent collection of Stephen King’s short fiction.

I remember reading Night Shift when I was a kid (my dad loved King, and we had plenty of his books around) and it’s probably one of the things that stayed with me the most from that era.

I mostly forget everything I read, but I can still remember most of the stories in tt. I like to think it’s because they were really, really, good.1

Quitters, Inc may be my favorite short story after Asimov’s The Last Question and Brown’s Sentry, it’s just so powerful.

Anyway, when I noticed there was a new short story collection I decided to give it a go. And well, Stephen delivers.

If you haven’t read a lot of King and you’re only familiar with It or Cujo, you may think he’s mostly an horror writer. But he’s not, in fact his best fiction (see Quitters, Inc) is speculative fiction at it’s best.

It’s our world but a little off . A little something that makes it uncomfortable, scary, or just makes you think harder. Just like in Night Shift, some stories have zero paranormal and are just unsettling. Unlike Night Shift, many (most?) stories seem to have a positive ending.

I guess Stephen got softer with age, just like me.

Vote: 7-/10, not all stories are great, and overall this is not as good as some of his older collections, but it’s still good.

  1. . Rather than think my memory was better 20+ years ago. ↩︎

Micro Review: Trigger Warning

Some time ago I listened to Neil Gaiman’s short story collection Smoke and Mirrors and I liked it and thought I should read more like it. So I did, and I listened to Trigger Warning.

This collection is just as good as the other one: a few stories are fantastic, most are good, some are meh. It’s been a few months since I went through this, and like for most short story collections I have since forgotten most of them.

Still, I recommend it. There are occasional poems in it. Many stories refer or happen in worlds by other authors, so you may enjoy them more, or less, if you are familiar with the source material. But this is just normal for Gaiman stuff.

There’s also a short story where we meet again Shadow Moon, the protagonist of the (wonderful) novel “American Gods”. But somehow stuff happened to him between that novel and this short story. That’s cause there was another collection between this and the other one I read, and for some reason I skipped it.

It is one of the blessed rights of readers, to read books out of order.

Vote: 7/10, I need to get more of his other short story collections, possibly in order.

Micro review: The Atrocity Archives (The Laundry Files, book 1)

I like Charlie Stross in general, I really enjoyed Accelerando, and many people talked positively about The Laundry Files, so I decided to give it a go.

I like the universe, where unspeakable horrors exist and governments have secret departments in charge of keeping the world safe. I like this premise already.

But it’s a well trodden trope, and what differentiates this from, say, Hellboy, or Man in Black§ is that it’s crossed with the “bureacracy rules the world” meme.

These aren’t your all-action cool guys with magic weapons and super boomsticks, these are the policemen at the embassy when you try to renew your passport. It’s a government job, it has its own quirks, but it’s not glamorous.

Given all these premises, I should have loved the book, but I didn’t.

I found it pretty predictable, the humor uninspired and a bit too much of the “I know about IT, so here’s a joke about it, wink wink” stuff.

This is a pretty long series so it may get better in later books§, but I’m not sure I’m going to give it another try.

Vote: 6.5/10, not great, not as bad as things from the dungeon dimensions.