(throw (BrowserTooLameException. "Chrome oder Firefox vonnöten"))
(ns de.sourcetalk.2012.clojure) (def smartclaim "Lisp's power is multiplied by the fact that your competitors don't get it. -- Paul Graham, Beating the Averages")
Source Talk Tage 2012
Stefan Kamphausen
Diese Präsentation verwendet:
"LISP is worth learning for a different reason - the profound enlightenment experience you will have when you finally get it. That experience will make you a better programmer for the rest of your days, [..]" -- Eric S. Raymond
lein repl
und M-x nrepl
oder M-x nrepl-jack-in
(defproject STT2012 "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "FIXME Eclipse Public License" :url "FIXME"} :dependencies [[org.clojure/clojure "1.4.0"]])
project.clj
lein help
lein sample
zeigt eine ausführliche und dokumentierte
Projektdefinitionuser=> 1 1 user=> 123 123 user=> 123.456 123.456 user=> :keyword :keyword
source
, doc
, find-doc
(println "Hello World.") '(println "Hello World.")
"Hello World."
(type "Hello World.") ;; ...
["ein" "vector" :von "dingen" 12 12.34 4/3] {:kstring "value" :kkeyword :anothervalue :kint 99 :kchar \s} #{"ein" "Set" :von "Dingen" 123} '(true false nil "eine Liste")
true
, false
, nil
entsprechen Boolean.True/False
und null
get
, nth
, Keyword als Funktion, Datenstruktur als
Funktion
(defn einfache-funktion [arg1 arg2] (println "Arg1:" arg1 "Arg2:" arg2)) (def quadrat (fn [x] (* x x ))) (defn fn-mit-destruct [[a1 a2]] [a2 a1]) (defn multi-arity-fn ([a1] (multi-arity-fn a1 "Default")) ([a1 a2] (vector a1 a2))) (defn fn-mit-doc "Dokumentation [...]" [] (println "Hello World."))
defn
; Makro: Eigentlich def
und fn
(let [pi (Math/PI)] (Math/cos pi)) (new java.io.File "/etc") (java.io.File. "/etc") (.isFile (java.io.File. "/etc")) (.nextFloat (java.util.Random.)) (java.net.URLEncoder/encode "Dick & Doof" "UTF-8") (let [pi (Math/PI)] (Math/cos pi))
new
oder nur .
.methodenName
(if (= 0 (+ 2 3)) "Math is broken" "Puh, alles gut") (cond (= 0 (+ 2 3)) "Math is broken" (= 5 (+ 2 3)) "Richtig" (> 5 (+ 2 3)) "Auch richtig, aber...") (condp = (class x) String (.toLowerCase x) Integer (str (Character/toLowerCase (char x))))
if
: drei Argumente, Test, Then, Elsecond
: Beliebig viele Paare aus Test und Thenand
, or
, do
condp
: Immer gleiches Prädikatcase
, when
, if-let
,
when-let
, cond-let
, if-not
,
when-not
Abstraktion: Erstes Element und Rest: first
und rest
bzw. next
(let [s [1 2 3]] [(first s) (second s) (nth s 2)]) [(first [1]) (next [1]) (rest [1])] (let [v ["1" :zwei]] [(cons 3 v) (conj v 3)]) (range 2 10) (doseq [x [1 2 3] y [1 2 3]] (println "x und y sind jetzt" x y))
first
, second
, nth
(linear time)next
und rest
am Endecons
oder conj
doseq
(defn seq-test [sq] [(first sq) (rest sq) (cons 99 sq)]) (doseq [sq [[1 2] "abc" {:a 1, :b 2} (java.util.ArrayList. [1 2]) (int-array 2 [4 5])]] (println (seq-test sq)))
seq
gewickelt(map inc [1 2 3]) (map * (range 1 4) (range 10 100)) (map #(str "(" % ")") (range 10)) (map #(str "(" %1 "," %2 ")") (range 10) (range 5)) (map (fn [[x y]] (* x y)) (map vector (range 1 5) (range 5 10)))
#()
oder fn
#()
: %
oder %1
...%9
amap
auch für Arrays (Performance...)(take 5 (iterate inc 0)) (nth (map #(* % %) (iterate inc 0)) 100) (def abc (map (fn [x] (printf "<%d> " x) (* 2 x)) (range 100))) (take 2 abc)
take
doall
, Seiteneffekte: dorun
abc
mit doall
und dorun
durchführen.
dorun
und map
? doseq
!(reduce + (range 101)) (reduce str (range 10)) (def x ["ich" "und" "du" "muellers" "esel" "meiers" "kuh"]) (reduce (fn [acc v] (str acc " " v)) x) (reductions #(str %1 " " %2) x) (reductions str "startwert" "SEQ")
reductions
zeigt einzelne Schritteareduce
auch für Arraysreduce
Minimum und Maximum einer Seq von
100 Zufallszahlen zwischen 0 und 100.(filter #{2 3} (range -5 5)) (sort < [1 4 2 66 43 3 6 7 43 88]) (take-while #(< (count %) 2) ["a" "b" "abc"]) (let [v [1 2 3 4]] [(partition 2 v) (partition 2 (next v)) (partition 2 1 v)]) (get (into {} (System/getProperties)) "os.name")
pos?
sort-by
take-while
, drop-while
, split-with
,
split-at
into
concat
, cycle
, distinct
,
every?
, not-any?
, not-every?
, interleave
,
interpose
,
Heuristik: finde die erste Stelle, an der sich 10 Sample hintereinander nur um 10 unterscheiden.
Neues Projekt anlegen; Rohdaten liegen bereits vor
sox -q orig.flac -t raw -c 1 -b 16 -e signed-integer -r 44100 - remix 1 \ > audio.raw
partition
, with-open
,
Arraybit-*
-Funktionenapply
nützlich?:use
, :import
(ns workshop.audio (:use [clojure.java.io :only [input-stream]]) (:import [java.io File])) (defn get-raw-samples [file] (let [buf (byte-array (.length (File. file)))] ;; was ist hier ungewoehnlich? (with-open [is (input-stream file)] (.read is buf)) (map (fn [[a b]] (bit-or (bit-and a 0xff) (bit-shift-left b 8))) (partition 2 buf))))
(defn sample-to-second ([sample] (sample-to-second sample 44100)) ([sample rate] (float (* sample (/ 1 rate)))))
prj/workshop.audio
lein uberjar
und -main
...
(defn analyze-file ([file] (analyze-file file 10 10)) ([file width maxdiff] (if-let [[values sample] (first (drop-while #(> (- (apply max (first %)) (apply min (first %))) maxdiff) (map vector (partition width 1 (get-raw-samples file)) (iterate inc 0))))] (format "%s: %fsec (%d@%d)" file (sample-to-second sample) (first values) sample) (str file ":OK"))))
"Ich bin ein String-Literal: ein Wert" [:das :ist :ein :Vector :von :Keywords] 2001 ; Eine Zahl. Ein Jahr? Ein Filmtitel?
(def gruendungsjahr-fsfe 2001) (def einfuehrungsjahr-11-punkte-saetze 2001) (def identitaet "def verknuepft Wert und Identität")
def
erzeugt eine Var, mit Thread-lokalem Verhalten
Typ | Kontext | Koordination | Ausführung |
---|---|---|---|
Var | lokal | eine Identität | synchron |
Atom | übergreifend | eine Identität | synchron |
Ref | übergreifend | mehrere Identitäten | synchron |
Agent | übergreifend | eine Identität | asynchron |
(def atm (atom "Eins")) (deref atm) (swap! atm (constantly 1)) @atm
atom
deref
oder @
(Read-Syntax)(swap! ATOM FN)
; keine
Seiteneffekte!java.util.concurrent.atomic.AtomicReference
(.start (Thread. #(+ 2 3))) (defn th-info [] (let [t (Thread/currentThread)] {:Name (.getName t) :ID (.getId t)})) (def fu (future (th-info))) @fu (doto (Thread. #(println th-info)) (.setName "Ich, Thread") (.start)) ;; output in REPL/terminal
doto
java.util.concurrent.Executors
(def eine-ref (ref 1)) (dosync (alter eine-ref inc)) (deref eine-ref) (dosync (alter eine-ref + 5))
ref
, alter
, deref
dosync
alter
gehen an Update-Funktioninc
, dec
dotimes
(def kollisionen (atom 0)) (def hochzaehler (ref 0)) (def runterzaehler (ref 100)) (defn inc-mit-zaehl [value] (swap! kollisionen inc) (inc value)) (defn dec-mit-zaehl [value] (swap! kollisionen inc) (dec value)) (defn stm-funktion [] (dosync (alter hochzaehler inc-mit-zaehl) (alter runterzaehler dec-mit-zaehl))) (dotimes [_ 100] (.start (new Thread stm-funktion))) [@hochzaehler @runterzaehler @kollisionen]Schöner mit lokalen Variablenbindungen
(defn ref-praxis [n] (let [koll (atom 0) hochz (ref 0) runterz (ref n) inc-z (fn [val] (swap! koll inc) (inc val)) dec-z (fn [val] (swap! koll inc) (dec val)) stm-fn (fn [] (dosync (alter hochz inc-z) (alter runterz dec-z)))] (dotimes [_ n] (.start (new Thread stm-fn))) (Thread/sleep 1000) [@hochz @runterz @koll]))
LockingTransaction.java
, Ref.java
sowie
Agentsfinal static AtomicLong
: Absoluter Zähler für readPoints, commitPoints
(def ag (agent "0")) (dotimes [i 5] (.start (Thread. #(send ag str " " i))))
send
Berechnung auf fixem Thread-Poolsend-off
wachsender Thread-Pool, z.B. I/O*agent*
(import [java.awt.event ActionListener] [javax.swing JFrame JButton]) (doto (JFrame.) (.add (doto (JButton. "Picard") (.addActionListener (proxy [ActionListener] [] (actionPerformed [e] (println "Energie!")))))) (.pack) (.setVisible true))
proxy
+---------------------+---------------------+---------+ | Markt | Alle Händler | Zustand | +----------+----------+-----------+---------+---------+ | Symbol | Anzahl | Händler | Anz ges | Fehler | +----------+----------+-----------+---------+---------+ | ... | ... | ... | ... | ... | +----------+----------+-----------+---------+---------+Siehe https://github.com/daveray/seesaw
seesaw.core :as s
, seesaw.table :as t
,
seesaw.timer :as st
t/table-model
, s/table
, s/config!
s/scrollable
, s/vertical-panel
,
s/label
, s/left-right-split
s/frame
, st/timer
, s/listen
:id
, s/select