Beispiele
Etwas größere Stücke, jedes gegen v0.60.0 ausgeführt, mit der Ausgabe, die es erzeugt hat.
Worthäufigkeiten
Eine Pipeline über die Standardbibliothek. Jeder Schritt nimmt Text oder Collection zuerst, deshalb fädelt -> ihn durch.
(defn top-words "The `n` most frequent words in `text`."
[text n] :spec [string integer -> seq]
(-> text
string/lower-case
(string/split " ")
(seq/remove string/blank?)
seq/frequencies
map/to-pairs
(seq/sort-by (fn [#(_word count)] (- count)))
(seq/take n)))
(top-words "the cat and the hat and the bat" 2)
; => (#("the" 3) #("and" 2))Binäre Suche
Zwei Stelligkeiten — eine zum Starten, eine für den Zustand — und recur für die Schleife.
(defn guesses
([low high target] (guesses low high target 1))
([low high target tries]
(let [middle (+ low (integer/divide (- high low) 2))]
(cond (= middle target) tries
(< middle target) (recur (+ middle 1) high target (+ tries 1))
true (recur low (- middle 1) target (+ tries 1))))))
(guesses 1 100 73) ; => 6
(guesses 1 1000000 1000000) ; => 20Validierung, die jeden Fehler meldet
Map-Destrukturierung in der Parameterliste, with für den Normalfall und result/collect, um jeden Fehler zu sammeln, statt beim ersten aufzuhören. Preise sind Dezimalzahlen, die Summe ist also exakt.
(defn- positive [field value]
(if (> value 0)
#(:ok value)
#(:error (str field " must be positive"))))
(defn check-order [{:qty qty :price price}]
(with [#(:ok checked) (result/collect [(positive "qty" qty) (positive "price" price)])]
#(:ok {:qty (seq/first checked) :price (seq/nth checked 1) :total (* qty price)})))
(check-order {:qty 3 :price 1.25M})
; => #(:ok {:total 3.75M, :qty 3, :price 1.25M})
(check-order {:qty 0 :price -1})
; => #(:error ("qty must be positive" "price must be positive"))Ein überwachter Actor
Let it crash, in Praxis: eine laufende Summe in einem eigenen Prozess, ein Supervisor, der ihn neu startet, und eine Anwendung, die ihn absichtlich scheitern lässt.
(ns shop.till "A running total, kept in its own process." (:behaviour praxis.actor))
(defn init [from] #(:ok from))
(defn handle-call [:total _from state] #(:reply state state))
(defn handle-cast
([#(:add price) state] #(:noreply (+ state price)))
([:crash _state] (throw :asked-to-fail)))
(defn start-link [from] (praxis.actor/start-link shop.till from {:name shop.till}))(ns shop.tree "Everything the shop runs." (:behaviour praxis.supervisor)) (require [praxis.supervisor :as sup]) (defn init [_argument] #(:ok #((sup/flags :one-for-one) (list (sup/child shop.till 0)))))
Die Anwendung startet den Baum, addiert 1.50, 2.25 und 0.99, fragt nach der Summe, schickt :crash und fragt erneut. prx run:
total: 4.74
22:52:30.564 [error] shop.till stopped: #(:bad_return_value #(:asked-to-fail {}))
It was casting :crash
restarted: true
total after restart: 0Eine Quelle, zwei Maschinen
Das portable Beispiel im Repository ist ein einziges Programm, zweimal ausgeführt — prx run auf der BEAM, und prx compile --target js gefolgt von Node — mit zeilenweisem Vergleich der Ausgaben. Der JavaScript-Build schreibt ein ES-Modul pro Namespace, eine Source-Map und aus den Specs erzeugte TypeScript-Deklarationen. Über die gesamte Konformitäts-Suite stimmen BEAM und JavaScript in 877 von 877 Fällen überein.