Memoize result of builtins.exec

Decided to try out converting a haskell prime number generator to Nix to test this

{ num }:

with import <nixpkgs/lib>;

rec {
  filter = f: { head, tail }:
    let newTail = filter f tail;
    in if f head then { inherit head; tail = newTail; } else newTail;
  unfoldr = f: b:
    let a = f b;
    in { head = a.elem; tail = unfoldr f a.next; };

  primes = {
    head = 2;
    tail = filter
      (isPrime primes)
      (unfoldr (n: { elem = n; next = n + 2; }) 3);
  };
  isPrime = { head, tail }: n:
    head * head > n || mod n head != 0 && isPrime tail n;

  get = { head, tail }: n: if n == 0 then head else get tail (n - 1);

  foo = get primes num;
  bar = get primes num + get primes num;
}

$ time nix eval -f sleep.nix foo --arg num 20000
224743

real	0m1.901s
user	0m1.798s
sys	0m0.104s
$ time nix eval -f sleep.nix bar --arg num 20000
449486

real	0m1.907s
user	0m1.804s
sys	0m0.103s

Pretty much identical, so it looks like it is doing maximal laziness. I guess this is just disabled somehow for builtins.exec?

2 Likes