123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- \documentclass{beamer}
- \title{Clojure Core}
- \subtitle{Primatives, collections, functions, and macros}
- \author{Lily Carpenter}
- \institute{https://gitlab.com/azrazalea/}
- \mode<presentation> {\usetheme{Dresden}}
- \date{}
- \usepackage[latin1]{inputenc}
- \usepackage{times}
- \usepackage[T1]{fontenc}
- \usepackage[english]{babel}
- \usepackage{hyperref}
- \usepackage{minted}
- \usepackage{upquote}
- \AtBeginDocument{%
- \def\PYZsq{\textquotesingle}%
- }
- \begin{document}
- \begin{frame}
- \titlepage
- \end{frame}
- \begin{frame}
- \frametitle{Summary}
- \tableofcontents
- \end{frame}
- \section{Primitives}
- \begin{frame}
- \frametitle{Primitives}
- Uses host language primitives
- \begin{itemize}
- \item{Integers}
- \item{Floating points}
- \item{Ratios}
- \item{Strings}
- \item{Regexes}
- \item{Keywords}
- \item{Symbols}
- \end{itemize}
- \end{frame}
- \begin{frame}
- \frametitle{Integers}
- \begin{itemize}
- \item{Standard java Long}
- \item{Automatically upgrade to arbitrary precision BigInteger with certain functions}
- \item{BigInteger does not exist for ClojureScript}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Integers}
- \begin{minted}{clojure}
- (+ 1 1)
- ;=> 2
- (/ 6 3)
- ;=> 2
- (> 3 2 1)
- ;=> false
- (< 3 2 1)
- ;=> true
- (class (+ 1 1))
- ;=> java.lang.Long
- \end{minted}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Integers}
- \begin{minted}{clojure}
- ;; To the more experienced,
- ;; why does this not need +'?
- (class (+ 200000000000000000000
- 100000000000000000))
- ;=> clojure.lang.BigInt
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Floating points}
- \begin{itemize}
- \item{Standard java Double}
- \item{Automatically upgrade to BigDecimal with certain functions}
- \item{BigDecimal does not exist for ClojureScript}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Floating points}
- \begin{minted}{clojure}
- (+ 0.1 0.1) ; leading zero required
- ;=> 0.2
- (* 0.1 0.1)
- ;=> 0.010000000000000002
- (class (* 0.1 0.1))
- ;=> java.lang.Double
- ;; Note the *', needed to promote doubles
- (class (*' (- 2M 2e-52M) 2e1023M))
- ;=> java.math.BigDecimal
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Ratios}
- \begin{itemize}
- \item{Represents fractions without using floating point}
- \item{Standard numeric operations work}
- \item{Automatically reduces}
- \item{Not in clojurescript}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Ratios}
- \begin{minted}{clojure}
- (/ 2 3)
- ;=> 2/3
- (/ 3 6)
- ;=> 1/2
- (+ 1/2 1/2)
- ;=> 1N
- (class (+ 1/2 1/2))
- ;=> clojure.lang.BigInt
- (+ 3/4 0.25)
- ;=> 1.0
- (class (+ 3/4 0.25))
- ;=> java.lang.Double
- (+ 3/4 1)
- ;=> 7/4
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Strings}
- \begin{itemize}
- \item{Java strings}
- \item{Common to use Java methods to manipulate}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Strings}
- \begin{minted}{clojure}
- (.toUpperCase "blah")
- ;=> "BLAH"
- (.split "BLAH BLAH BLAH" "")
- ;=> ("BLAH" "BLAH" "BLAH")
- (clojure.string/upper-case "blah")
- ;=> "BLAH"
- (clojure.string/split "BLAH BLAH BLAH" "")
- ;=> ("BLAH" "BLAH" "BLAH")
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Regexes}
- \begin{itemize}
- \item{Use either re-pattern or literal syntax}
- \item{Creates java.util.regex.Pattern}
- \item{Use re-seq, re-find, re-matches}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Regex}
- \begin{minted}{clojure}
- (re-seq #"[0-9]+" "abs123def345ghi567")
- ;=> ("123" "345" "567")
- (re-find #"([-+]?[0-9]+)/([0-9]+)" "22/7")
- ;=> ["22/7" "22" "7"]
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Keywords}
- \begin{itemize}
- \item{Identifiers that just evaluate to themselves}
- \item{Can be used to lookup keys in maps}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Keywords}
- \begin{minted}{clojure}
- :foo
- ;=> :foo
- (keyword 'foo)
- ;=> :foo
- (:foo {:foo 1})
- ;=> 1
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Symbols}
- \begin{itemize}
- \item{"Variables": Not really, but partially serve the same purpose}
- \item{They are identifiers pointing to something else}
- \item{They don't vary (hence not really variables)}
- \item{The actual storage location is called a var, symbol is just a name that points to it}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Symbols}
- \begin{minted}{clojure}
- (symbol 'foo)
- ;=> foo
- (symbol "foo")
- ;=> foo
- (symbol "clojure.core" "foo")
- ;=> clojure.core/foo
- (defn blah
- []
- (println "blah"))
- ;=> #'user/blah
- (let [x 5]
- (+ x 2))
- ;=> 7
- \end{minted}
- \end{frame}
- \section{Sequences}
- \begin{frame}
- \frametitle{Sequences}
- \begin{itemize}
- \item{Generalized interface implemented by most collections.}
- \item{Many functions on sequences are lazy}
- \item{first}
- \item{rest}
- \item{cons}
- \end{itemize}
- \end{frame}
- \section{Collections}
- \begin{frame}
- All persistent(shared structure). Also implement the ISeq interface.
- \frametitle{Collections}
- \begin{itemize}
- \item{Lists}
- \item{Vectors}
- \item{Maps}
- \item{Sets}
- \item{Records}
- \end{itemize}
- \end{frame}
- \begin{frame}
- \frametitle{Lists}
- \begin{itemize}
- \item{Basic linked list in function}
- \item{Directly implements Sequence interface, except for empty list}
- \item{Conj puts the item at the front of the list}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Lists}
- \begin{minted}{clojure}
- '(1 2 3 4) ; Literal list
- ;=> (1 2 3 4)
- (list 1 2 3 4)
- ;=> (1 2 3 4)
- (+ 1 2) ; List as code structure
- ;=> 3
- (first '(1 2 3 4)) ; Using list as data structure
- ;=> 1
- (rest '(1 2 3 4))
- ;=> (2 3 4)
- (conj '(1 2 3 4) 5)
- ;=> (5 1 2 3 4)
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Vectors}
- \begin{itemize}
- \item{Very similar to Arrays in other languages}
- \item{Conj puts the item at the end of the vector}
- \item{Supports rseq function for quick reversal}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Vectors}
- \begin{minted}{clojure}
- [1 2 3 4 5] ; Literal vector
- ;=> [1 2 3 4 5]
- (vector 1 2 3 4 5)
- ;=> [1 2 3 4 5]
- (conj [1 2 3 4] 5)
- ;=> [1 2 3 4 5]
- (rseq [1 2 3 4 5])
- ;=> (5 4 3 2 1)
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Maps}
- \begin{itemize}
- \item{Standard key and value pairs}
- \item{Either hashed or sorted}
- \item{Conj expects another Map and merges them}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Maps}
- \begin{minted}{clojure}
- {:key1 1, :key1 2} ; Literal HashMap
- ;=> {:key1 2}
- (hash-map :key1 1, :key1 2)
- ;=> {:key1 2}
- (assoc {} :key1 1)
- ;=> {:key1 1}
- (dissoc {:key1 1} :key1)
- ;=> {}
- (conj {:key1 1} {:key2 2})
- ;=> {:key1 1 :key2 2}
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Sets}
- \begin{itemize}
- \item{Unique set of values}
- \item{Either hashed or sorted}
- \item{Conj adds new elements to set}
- \item{Various set operations including union, difference, and intersection.}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Sets}
- \begin{minted}{clojure}
- #{1 2 3} ; Literal HashSet
- ;=> #{1 2 3}
- (hash-set 1 2 3)
- ;=> #{1 2 3}
- (conj #{1 2 3} 4)
- ;=> #{1 2 3 4}
- (disj #{1 2 3} 3)
- ;=> #{1 2}
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Basic collection functions}
- \begin{itemize}
- \item{Reduce: Standard functional reduce(fold left), iterate over collection and return a single accumulated result.}
- \item{Map: Standard functional map, iterate over collection and return a Sequence containing one value per a collection item.}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Basic collection functions}
- \begin{minted}{clojure}
- (reduce + [1 2 3 4 5])
- ;=> 15
- (reduce conj #{} [:a :b :c])
- ;=> #{:a :b :c}
- (map inc [1 2 3])
- ;=> (2 3 4)
- (map + [1 2 3] [4 5 6] [7 8 9])
- ;=> (12 15 18)
- (defn wrong-arity-func
- [a b]
- (+ a b))
- (map wrong-arity-func [1 2 3] [4 5 6] [7 8 9])
- ;=> ArityException: Wrong number of args (3)
- ;=> passed to wrong-arity-func
- \end{minted}
- \end{frame}
- \section{Control Flow}
- \begin{frame}
- \frametitle{Looping/recursion}
- \begin{itemize}
- \item{Loop: Provides a lexical closure to recur to.}
- \item{Recur: Used for loop control flow as well as for general recursive functions.}
- \item{Recur will throw an exception if it is not in tail position}
- \item{Quite often your use case can be solved using map/reduce or similar instead.}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Looping/recursion}
- \begin{minted}{clojure}
- (loop [x 10]
- (when (> x 1)
- (println x)
- (recur (- x 2))))
- ;=> 10
- ;=> 2
- (defn count-to-10 [x]
- (when (<= x 10)
- (println x)
- (recur (inc x))))
- (count-to-10 5)
- ;=> 5
- ;=> 10
- \end{minted}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Looping/recursion}
- \begin{minted}{clojure}
- (defn count-to-10 [x]
- (when (<= x 10)
- (recur (inc x))
- (println x)))
- ;=> CompilerException java.lang
- ;=> .UnsupportedOperationException: Can only
- ;=> recur from tail position
- \end{minted}
- \end{frame}
- \begin{frame}
- \frametitle{Conditionals}
- \begin{itemize}
- \item{If: Basic if statement, only support true and false branches for one statement. }
- \item{Cond: More complex if, takes many different conditionals.}
- \item{Case: Standard switch case statement}
- \end{itemize}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Conditionals}
- \begin{minted}{clojure}
- (if (even? 6)
- (println true)
- (println false))
- ;=> true
- (if (even? 5)
- (println true)
- (println false))
- ;=> false
- (cond
- (< 5 0) true
- (> 5 0) false
- :else nil)
- ;=> false
- \end{minted}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Conditionals}
- \begin{minted}{clojure}
- (cond
- (< 0 5) true
- (> 0 5) false
- :else nil)
- ;=> true
- (let [mystr "no match"]
- (case mystr
- "" 0
- "hello" (count mystr)
- "default"))
- ;=> "default"
- \end{minted}
- \end{frame}
- \section{Macros}
- \begin{frame}
- \frametitle{Macros}
- Very very very brief(and technically incorrect) explanation is: \\~\\
- A 'function' that does not evaluate its arguments by default and returns
- a list that will then be evaluated as a code form. \\~\\
- Read \url{http://www.braveclojure.com/writing-macros/}
- \end{frame}
- \begin{frame}[fragile]
- \frametitle{Macros}
- \begin{minted}{clojure}
- (defmacro pointless
- [n]
- n)
- (pointless (+ 1 2))
- ;=> 3
- (pointless 3)
- ;=> 3
- (pointless [1 2 3 4])
- ;=> [1 2 3 4]
- \end{minted}
- \end{frame}
- \begin{frame}
- \begin{center}
- \Huge Questions?
- \end{center}
- \end{frame}
- \end{document}
|