Skip to content

Instantly share code, notes, and snippets.

@jfacorro
Last active May 19, 2019 10:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfacorro/e51d0b092e51827dc086d83c7c626a1a to your computer and use it in GitHub Desktop.
Save jfacorro/e51d0b092e51827dc086d83c7c626a1a to your computer and use it in GitHub Desktop.
Clojure on the BEAM: finding a fast and correct implementation for the fn? predicate
(ns fn-pred)
(defn fn?-1
"Returns true if x is either a function"
{:added "1.0"}
[x] (erlang/is_function x))
(defn fn?-2
"Returns true if x is a function"
{:added "1.0"}
[x] (or (erlang/is_function x)
(instance? clojerl.Fn x)))
(defn fn?-3
"Returns true if x is either a function"
{:added "1.0"}
[x] (or (instance? erlang.Fn x)
(instance? clojerl.Fn x)))
(defn* fn?-4
"Returns true if x is either a function"
{:added "1.0"}
([x] {:when (erlang/is_function x)} true)
([x] (instance? clojerl.Fn x)))
(defn fn?-5
"Returns true if x is either a function"
{:added "1.0"}
[x] (satisfies? clojerl.IFn x))
(defn fn?-6
"Returns true if x is either a function"
{:added "1.0"}
[x] (instance? clojerl.Fn x))
(defn* fn?-7
"Returns true if x is either a function"
{:added "1.0"}
([x]
(case* (clj_rt/type_module x)
:erlang.Fn true
:clojerl.Fn true
:clojerl.Var (-> x meta :fn? boolean)
false)))
(defn fn?-8
"Returns true if x is either a function"
{:added "1.0"}
([x]
(case* (clj_rt/type_module x)
:erlang.Fn true
:clojerl.Fn true
:clojerl.Var (-> x meta :fn? boolean)
false)))
(defmacro bench [f]
`(simple-benchmark [x# (fn [])] (~f x#) 10000000))
(defn run []
(bench fn?-1)
(bench fn?-2)
(bench fn?-3)
(bench fn?-4)
(bench fn?-5)
(bench fn?-6)
(bench fn?-7)
(bench fn?-8))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment