;; An Fn is {code, env}: it may have captured, and the caller neither knows ;; nor cares. A CFn is the bare code address, one word, and cannot capture. (defn apply-fn [f (Fn [i32] i32) x i32] i32 (f x)) (defn apply-cfn [f (CFn [i32] i32) x i32] i32 (f x)) (defn bump [x i32] i32 (+ x 1)) (defn main [] () (let [n 10] ;; An fn takes its types from the position it is written in. (println (apply-fn (fn [x] (+ x n)) 5)) ; captures n (println (apply-fn bump 5)) ; a defn captures nothing (println (apply-cfn bump 5)) ; so it fits either position ;; Widening is one way: a CFn goes where an Fn is wanted. (println (apply-fn (fn [x] (* x 2)) 21))))