Skip to content

Instantly share code, notes, and snippets.

@bendisposto
Created December 1, 2014 06:21
Show Gist options
  • Save bendisposto/a26e035170a620df2bd8 to your computer and use it in GitHub Desktop.
Save bendisposto/a26e035170a620df2bd8 to your computer and use it in GitHub Desktop.
Code aus der Vorlesung vom 27.11.2014
(ns repl.core)
(comment
;; recursion
(use 'clojure.tools.trace)
(deftrace ! [n]
(if (= 1 n)
n
(*' n (! (dec n)))))
(! 8)
;; Akkumulator, jetzt ist es tail recursive
(deftrace !
([n] (! n 1))
([n a] (if (= 1 n)
a
(! (dec n) (*' a n)))))
(! 8)
;; keine automatische TCO
(deftrace !
([n] (! n 1))
([n a] (if (= 0 n)
a
(recur (dec n) (*' a n)))))
(! 8)
;; ohne trace!
(defn !
([n] (! n 1))
([n a] (if (= 0 n)
a
(recur (dec n) (*' a n)))))
(! 10000)
;; recur geht nicht überall
(deftrace ! [n]
(if (= 1 n)
n
(*' n (recur (dec n)))))
;; mutual recursion
(declare my-odd? my-even?)
(macroexpand-1 '(declare my-odd? my-even?))
(defn my-even? [n]
(cond (= 0 n) true
(= 1 n) false
:otherwise (my-odd? (dec n))))
(defn my-odd? [n]
(cond (= 0 n) false
(= 1 n) true
:otherwise (my-even? (dec n))))
(my-even? 6)
(my-even? 5)
(my-odd? 5)
(my-odd? 6)
(my-even? 100000)
;; recur geht nicht => trampoline
(defn my-even? [n]
(cond (= 0 n) true
(= 1 n) false
:otherwise (fn [] (my-odd? (dec n)))))
(defn my-odd? [n]
(cond (= 1 n) true
(= 0 n) false
:otherwise (fn [] (my-even? (dec n)))))
(trampoline (my-even? 5))
(trampoline (my-even? 100000))
(trampoline (my-even? 1000001))
;; Achtung! Was ist, wenn eine Funktion zurückgegeben werden soll?
;; (let [bindings] body)
(let [x 3] (println x) (+ 3 x))
(for [x [3]] (+ 3 x))
;; destructuring
(let [[x y] [1 2]] (println x y))
(let [[x y] [3 4 6]] (println x y))
(let [[x _ y] [1 2 3]] (println x y))
(let [[x _ x] [1 2 3]] (println x))
(let [[x & y] [7 8 9]] (println x y))
(let [[x & y :as l] [1 2 3]] (println x y l))
(let [point (list 4 8)
[x y] point]
(println x y point))
(let [point {:x 100 :y 200}
[x y] point] (println x y))
(let [point {:x 300 :y 500}
{x :x y :y} point] (println x y))
(let [point {:x 100 :y 200}
{x :x y :y :as m } point] (println x y m))
(let [point {:x 410 :y 600}
{:keys [x y] :as m } point] (println x y m))
(let [point {:x -210 :y 7100}
{:keys [x y z] :or {x 0 y 0 z 0} } point] (println x y z))
(let [db [{:name "Bendisposto" :vorname "Jens"}
{:name "Leuschel" :vorname "Michael"}]
[{n1 :name} {n2 :name}] db] (println n1 n2))
;; Concurrency
;; LazyInit.java
;; Atoms
(def foo (atom {}))
foo
;; Atome ändern:
;; (swap! atom funktion weitere argumente für funktion)
(defn store [k v] (swap! foo assoc ,,,, k v))
(store :x 7)
foo
(:x foo)
(deref foo)
@foo
(:x @foo)
(def counter (atom 0))
(defn incer [] (swap! counter inc))
(do
(future (last (repeatedly 10000000 incer)))
@counter)
counter
(defn sleepy-inc [n]
(println "Zzz")
(Thread/sleep 4000)
(println "Whut?")
(inc n))
(sleepy-inc 6)
(defn v-incer [] (swap! counter sleepy-inc))
(defn tease [] (let [c (rand-int 1000)] (reset! counter c)))
(defn myreset! [a v] (swap! a (fn [_] v)))
(future (v-incer)) ; repl
(tease) ;repl
;; watcher
;; (add-watch atom name vierstelligeFkt)
;; Funktion: name atom alt neu
(def agent-x
(add-watch counter
:my-awesome-watcher
(fn [k r old new]
(println (str k ": " old " -> " new))
(swap! r inc))))
(tease)
(def konto1 (atom 100))
(def konto2 (atom 0))
(defn transfer-money [amount]
(when (<= amount (deref konto1))
(do (swap! konto2 #(+ % amount))
(Thread/sleep 5000)
(swap! konto1 #(- % amount)))))
(defn pay-bill [amount]
(when (<= amount (deref konto1))
(println "Payed" amount)
(swap! konto1 #(- % amount))))
(future (transfer-money 10))
[@konto1 @konto2]
(pay-bill 10)
(future (transfer-money 60))
(pay-bill 60)
[@konto1 @konto2]
(def konto1 (ref 100))
(def konto2 (ref 0))
(defn transfer-money [amount]
(dosync (when (<= amount (deref konto1))
(do (alter konto2 #(+ % amount))
(Thread/sleep 5000)
(alter konto1 #(- % amount))))))
(defn pay-bill [amount]
(dosync (when (<= amount (deref konto1))
(println "Payed" amount)
(alter konto1 #(- % amount)))))
(future (transfer-money 10))
[@konto1 @konto2]
(pay-bill 10)
(future (transfer-money 60))
(pay-bill 60)
[@konto1 @konto2]
(def bank (atom {:konto1 0 :konto2 100}))
;; commute
(def konto1 (ref 10000))
(def konto2 (ref 10000))
(def x-counter (ref 0))
(defn pay-bill [kto amount]
(dosync (when (<= amount (deref kto))
(println "Payed" amount)
(Thread/sleep 2000)
(alter kto #(- % amount))
(alter x-counter inc))))
(pay-bill konto1 10)
[@konto1 @konto2 @x-counter]
(do (future (pay-bill konto1 10))
(future (pay-bill konto2 10)))
(defn pay-bill [kto amount]
(dosync (when (<= amount (deref kto))
(println "Payed" amount)
(Thread/sleep 2000)
(alter kto #(- % amount))
(commute x-counter inc))))
;; agents
(def log-file (atom []))
(defn debug [& words]
(swap! log-file
(fn [x]
(Thread/sleep 1000)
(conj x (apply str (interpose " " words))))))
(debug "Eine" "Ausgabe," "die" "an" "einem" "Stück" "erfolgen" "soll")
(debug "Noch" "eine" "Ausgabe," "die" "an" "einem" "Stück" "erfolgen" "soll")
(time
(do
(debug "Eine" "Ausgabe," "die" "an" "einem" "Stück" "erfolgen" "soll")(debug "Noch" "eine" "Ausgabe," "die" "an" "einem" "Stück" "erfolgen" "soll")
))
log-file
(def log-file (agent []))
(defn debug [& words]
(send log-file
(fn [x]
(Thread/sleep 4000)
(conj x (apply str (interpose " " words))))))
(time
(do
(debug "Eine" "Ausgabe," "die" "an" "einem" "Stück" "erfolgen" "soll")
(debug "Noch" "eine" "Ausgabe")))
(do (await log-file) @log-file)
(def ag
(for [x (range 20)] (agent nil)))
(time
(do
(doseq [a ag] (send a (fn [_] (Thread/sleep 1000))))
(doseq [a ag] (await a))))
(time
(do
(doseq [a ag] (send-off a (fn [_] (Thread/sleep 1000))))
(doseq [a ag] (await a))))
;; future & promise
(defn nag [f]
(if (realized? f)
@f
(do (Thread/sleep 100) (println f) (recur f))))
(let [x (future (do (Thread/sleep 2000) 42))]
(print "nagging ")
(println x)
(nag x))
(let [x (future (do (Thread/sleep 2000) 42))]
(print "nagging ")
(println @x)
(nag x))
(defn stupid-fib [n]
(if (< n 2)
n
(+ (stupid-fib (dec n))
(stupid-fib (- n 2)))))
;; 30 31 32 33 34 35 36 37
;; 200 350 550 900 1500 2300 3700 6000 -> 15500
(time (let [fa (for [x (range 30 38)] (future (stupid-fib x)))]
(doseq [f fa] (println @f))))
(time (let [fa (for [x [36 37]] (future (stupid-fib x)))]
(doseq [f fa] (println @f))))
(def x (promise))
(nag x)
(deliver x 10)
@x
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment