Back
fn (clj)
(source)macro
(fn & sigs)
params => positional-params*, or positional-params* & rest-param
positional-param => binding-form
rest-param => binding-form
binding-form => name, or destructuring-form
Defines a function.
See https://clojure.org/reference/special_forms#fn for more information
Examples
clojure
(ns clojure.test-clojure.server
(:import java.util.Random)
(:require [clojure.test :refer :all])
(:require [clojure.core.server :as s]))
(defn check-invalid-opts
[opts msg]
(try
(#'clojure.core.server/validate-opts opts)
(is nil)
(catch Exception e
(is (= (ex-data e) opts))
(is (= msg (.getMessage e))))))
(defn create-random-thread
[]
(Thread.
(fn []
(let [random (new Random)]
(while (not (.isInterrupted (Thread/currentThread)))
(System/setProperty (Integer/toString (.nextInt random)) (Integer/toString (.nextInt random))))))))
clojure
(ns clojure.test-clojure.reducers
(:require [clojure.core.reducers :as r]
[clojure.test.generative :refer (defspec)]
[clojure.data.generators :as gen])
(:use clojure.test))
(defmacro defequivtest
;; f is the core fn, r is the reducers equivalent, rt is the reducible ->
;; coll transformer
[name [f r rt] fns]
`(deftest ~name
(let [c# (range -100 1000)]
(doseq [fn# ~fns]
(is (= (~f fn# c#)
(~rt (~r fn# c#))))))))
(defequivtest test-mapcat
[mapcat r/mapcat #(into [] %)]
[(fn [x] [x])
(fn [x] [x (inc x)])
(fn [x] [x (inc x) x])])
(deftest test-sorted-maps
(let [m (into (sorted-map)
'{1 a, 2 b, 3 c, 4 d})]
(is (= "1a2b3c4d" (reduce-kv str "" m))
"Sorted maps should reduce-kv in sorted order")
(is (= 1 (reduce-kv (fn [acc k v]
(reduced (+ acc k)))
0 m))
"Sorted maps should stop reduction when asked")))
(defn gen-num []
(gen/uniform 0 2000))
(defn reduced-at-probe
[m p]
(reduce-kv (fn [_ k v] (when (== p k) (reduced :foo))) nil m))
(defspec reduced-always-returns
(fn [probe to-end]
(let [len (+ probe to-end 1)
nums (range len)
m (zipmap nums nums)]
(reduced-at-probe m probe)))
[^{:tag `gen-num} probe ^{:tag `gen-num} to-end]
(assert (= :foo %)))
(deftest test-fold-runtime-exception
(is (thrown? IndexOutOfBoundsException
(let [test-map-count 1234
k-fail (rand-int test-map-count)]
(r/fold (fn ([])
([ret [k v]])
([ret k v] (when (= k k-fail)
(throw (IndexOutOfBoundsException.)))))
(zipmap (range test-map-count) (repeat :dummy)))))))
clojure
(deftest division
(is (= clojure.core// /))
(binding [*ns* *ns*]
(eval '(do (ns foo
(:require [clojure.core :as bar])
(:use [clojure.test]))
(is (= clojure.core// bar//))))))
(deftest unknown-tag
(let [my-unknown (fn [tag val] {:unknown-tag tag :value val})
throw-on-unknown (fn [tag val] (throw (RuntimeException. (str "No data reader function for tag " tag))))
my-uuid (partial my-unknown 'uuid)
u "#uuid \"550e8400-e29b-41d4-a716-446655440000\""
s "#never.heard.of/some-tag [1 2]" ]
(binding [*data-readers* {'uuid my-uuid}
*default-data-reader-fn* my-unknown]
(testing "Unknown tag"
(is (= (read-string s)
{:unknown-tag 'never.heard.of/some-tag
:value [1 2]})))
(testing "Override uuid tag"
(is (= (read-string u)
{:unknown-tag 'uuid
:value "550e8400-e29b-41d4-a716-446655440000"}))))
(binding [*default-data-reader-fn* throw-on-unknown]
(testing "Unknown tag with custom throw-on-unknown"
(are [err msg form] (thrown-with-msg? err msg (read-string form))
Exception #"No data reader function for tag foo" "#foo [1 2]"
Exception #"No data reader function for tag bar/foo" "#bar/foo [1 2]"
Exception #"No data reader function for tag bar.baz/foo" "#bar.baz/foo [1 2]")))
(defn roundtrip
"Print an object and read it back. Returns rather than throws
any exceptions."
[o]
(binding [*print-length* nil
*print-dup* nil
*print-level* nil]
(try
(-> o pr-str read-string)
(catch Throwable t t))))
(defn roundtrip-dup
"Print an object with print-dup and read it back.
Returns rather than throws any exceptions."
[o]
(binding [*print-length* nil
*print-dup* true
*print-level* nil]
(try
(-> o pr-str read-string)
(catch Throwable t t))))
(defn str->lnpr
[s]
(-> s (java.io.StringReader.) (clojure.lang.LineNumberingPushbackReader.)))
(eval (-> "^{:line 42 :column 99} (defn explicit-line-numbering [])" str->lnpr read))
(is (= {:line 42 :column 99}
(-> 'explicit-line-numbering resolve meta (select-keys [:line :column])))))
TechEmpower/FrameworkBenchmarks
(ns io.github.kit-clj.te-bench.cache.inmem
(:require
[clojure.core.cache :as cache]
[integrant.core :as ig]
[next.jdbc :as jdbc]
[next.jdbc.result-set :as rs]))
(defmethod ig/init-key :cache/inmem
[_ {:keys [db-conn threshold]}]
(cache/fifo-cache-factory
(reduce
(fn [out {:keys [id] :as obj}]
(assoc out id obj))
{}
(jdbc/execute! db-conn ["select * from \"World\""] {:builder-fn rs/as-unqualified-lower-maps}))
{:threshold threshold}))
babashka/babashka
(ns babashka.impl.server
(:require [babashka.impl.clojure.core.server :as server]
[babashka.impl.common :as common]
[babashka.impl.socket-repl :as socket-repl]
[sci.core :as sci]))
(def prepl (fn [& args]
(apply server/prepl (common/ctx) args)))
(def io-prepl
(fn [& args]
(apply server/io-prepl (common/ctx) args)))
(def start-server
(fn [& args]
(apply server/start-server (common/ctx) args)))
nextjournal/clerk
(ns viewers.controls
"Demo of Clerk's two-way bindings."
{:nextjournal.clerk/visibility {:code :show :result :show}}
(:require [clojure.core :as core]
[nextjournal.clerk :as clerk]
[nextjournal.clerk.viewer :as viewer]))
;; # 1️⃣ `comp` `:render-fn`
(def transform-var
(comp clerk/mark-presented
(clerk/update-val (fn [v] (viewer/->ViewerEval (list 'resolve (list 'quote (symbol v))))))))
(def render-slider
'(fn [state-atom]
[:input {:type :range :value @state-atom :on-change #(swap! state-atom (constantly (int (.. % -target -value))))}]))
(def render-text-input
'(fn [state-atom]
[:input {:type :text :value @state-atom :on-change #(swap! state-atom (constantly (.. % -target -value)))
:class "px-3 py-3 placeholder-blueGray-300 text-blueGray-600 relative bg-white bg-white rounded text-sm border border-blueGray-300 outline-none focus:outline-none focus:ring w-full"}]))
^{::clerk/viewer {:render-fn (list 'comp render-slider 'deref) :transform-fn transform-var}}
#'number-atom
^{::clerk/viewer {:render-fn (list 'comp render-text-input 'deref) :transform-fn transform-var}}
#'name-atom
^{::clerk/viewer {:transform-fn transform-var
:render-fn '#(vector nextjournal.clerk.render/inspect @%)}}
#'number-atom
(def var-viewer
{:pred var?
:transform-fn transform-var
:render-fn '(fn [x] [nextjournal.clerk.render/inspect @x])})
^{::clerk/viewers (clerk/add-viewers [(assoc var-viewer :render-fn (list 'comp render-text-input 'deref))])}
#'name-atom
(def convenient-slider
{:transform-fn (comp transform-var (clerk/update-val #(cond-> % (viewer/get-safe % ::clerk/var-from-def) ::clerk/var-from-def)))
:render-fn '(fn [x] (let [state-atom (cond-> x (var? x) deref)]
[:input {:type :range :value @state-atom :on-change #(swap! state-atom (constantly (int (.. % -target -value))))}]))})
hoplon/hoplon
(ns hoplon.binding
(:refer-clojure :exclude [binding bound-fn])
(:require [clojure.core :as clj]
[cljs.analyzer :as a]))
(defmacro binding
"See clojure.core/binding."
[bindings & body]
(let [env (assoc &env :ns (a/get-namespace a/*cljs-ns*))
value-exprs (take-nth 2 (rest bindings))
bind-syms (map #(:name (a/resolve-existing-var env %)) (take-nth 2 bindings))
bind-syms' (map (partial list 'quote) bind-syms)
set-syms (repeatedly (count bind-syms) gensym)
setfn (fn [x y]
{:push! `(fn []
(let [z# ~x]
(set! ~x ~y)
(fn [] (set! ~x z#))))})
thunkmaps (map setfn bind-syms set-syms)]
(a/confirm-bindings env bind-syms)
`(let [~@(interleave set-syms value-exprs)]
(hoplon.binding/push-thread-bindings ~(zipmap bind-syms' thunkmaps))
(try ~@body (finally (hoplon.binding/pop-thread-bindings))))))
(defmacro bound-fn
"See clojure.core/bound-fn."
[args & body]
`(hoplon.binding/bound-fn* (fn [~@args] ~@body)))
noprompt/meander
(ns multimethods
(:refer-clojure :exclude [defmethod defmulti])
(:require
#?(:clj [clojure.core :as clj] :cljs [cljs.core :as cljs])
[meander.epsilon :as m]))
(defprotocol IMeanderMethods
(-set-fn [this f]))
(deftype MultiMeanderFn [^:unsynchronized-mutable target-fn]
IMeanderMethods
(-set-fn [_ f]
(set! target-fn f))
clojure.lang.IFn
(invoke [___ a]
(target-fn a))
(invoke [___ a b]
(target-fn a b))
(invoke [___ a b c]
(target-fn a b c))
(invoke [___ a b c d]
(target-fn a b c d))
(invoke [___ a b c d e]
(target-fn a b c d e))
;; ... apply rest etc
)
(defmacro defmethod
[mf [& lhr] & body]
(swap! cache_ assoc-in [mf lhr] body)
(let [ptrns (get @cache_ mf)]
`(-set-fn ~(with-meta mf {:tag `MultiMeanderFn})
(fn [& ~'argsv]
(m/match ~'argsv
~@(loop [[[l r] & more] ptrns xs []]
(if l
(recur more (conj xs l (cons `do r)))
xs)))))))
(defmulti test-fn)
(defmethod test-fn
[:add ?x ?y]
(println ?x ?y)
(+ ?x ?y))
(test-fn :add 1 2)
;; => 3
(defmethod test-fn
[:sub ?x ?y]
(- ?x ?y))
(test-fn :sub 2 1)
;; => 1
(defmethod test-fn
[:sum . [!xs ...]]
(reduce + !xs))
(test-fn :sum [1 2 3 4 5 6 7 8 9 10])
;; => 55