lisp_apply = (fn, x, a) => {
  console.log('apply >', pp(fn), pp(x), pp(a))
  let retval =
    atom(fn) ? (
      eq(fn, 'CAR') ? caar(x) :
      eq(fn, 'CDR') ? cdar(x) :
      eq(fn, 'CONS') ? cons(car(x), cadr(x)) :
      eq(fn, 'ATOM') ? atom(car(x)) :
      eq(fn, 'EQ') ? eq(car(x), cadr(x)) :
      /* T ? */ lisp_apply(lisp_eval(fn, a), x, a)
    ) :
    eq(car(fn), 'LAMBDA') ?
      lisp_eval(caddr(fn), pairlis(cadr(fn), x, a)) :
    eq(car(fn), 'LABEL') ?
      lisp_apply(caddr(fn), x, cons(cons(cadr(fn), caddr(fn)), a)) :
    undefined

  console.log('apply <', pp(retval))
  return retval
}
