Open kurtzace opened 4 months ago
vector []
(first (rest (nth.. (conj my-arr "..") (cons ".." my-arr)
list '(....)
same as vector
map
{"ke" "val" "key2" "val2"}
{:"ke" "val" :"key2" "val2"}
(hash-map k v
k2 v2)
(get my-map "k")
(my-map :"k")
(assoc my-map :k2 36)
(dissoc my-map :k1)
(keys
(vals
Sets
#{:sci-fi :romance :mystery}
(contains?
(disj my-set "king"
let inside func
(defn compute-discount-amount [amount discount-percent min-charge]
(let [discount (* amount discount-percent)
discounted-amount (- amount discount)]
;;if & let
(defn uppercase-author [book]
(if-let [author (:author book)]
(.toUpperCase author)))
;;or
(when-let [author (:author book)]
(.toUpperCase author)))
merge request params to body
(defn assoc-query-params
"Parse and assoc parameters from the query string
with the request."
[request encoding]
(merge-with merge request
(if-let [query-string (:query-string request)]
(let [params (parse-params query-string encoding)]
{:query-params params, :params params})
{:query-params {}, :params {}})))
symbols
(.get the-var) ; Get the value of the var: "Austen"
(.-sym the-var) ; Get the symbol of the var: author
ns
from cli
(require '[myapp.pricing :as pricing]) ;;or (require '[myapp.pricing :refer [my-func]])
from prog
(ns myapp.core
(:require [myapp.pricing :as pricing])
(:gen-class))
get pre-defined vars
(ns-map (find-ns 'user))
(require :reload
(ns-unmap ;; to remove old mapping
(def title-seq (seq [
(cons "myelem" (seq '( ;;add elem
(first
(next
(rest
(sort
(reverse
(partition 2 my-seq)
(interleave titles authors) ;; combine
(def my-lets ["L" "T" "B"])
(interpose "and" my-lets) ;;(L and T and B)
(filter neg? '(1 -22 3 -99 4 5 6 -77))
(some my-func? books) ;;
(def doubled (map #(* 2 %) some-numbers))
(map :title books) ;; or (map (fn [book] (:title book)) books)
;;shotcut
(map (fn [book] (count (:title book))) books) === (map (comp count :title) books) === (for [b books] \n (count (:title b)))
(reduce + 0 numbers)
;; or any single value result
(defn hi-price [hi book]
(if (> (:price book) hi)
(:price book)
hi))
(reduce hi-price 0 books)
;; top three rated books by title
(interpose
" // "
(map :title (take 3 (reverse (sort-by :rating books)))))
count
(defn my-count [col]
(let [the-seq (seq col)]
(loop [n 0 s the-seq]
(if (seq s)
(recur (inc n) (rest s))
n))))
IO
(require '[clojure.java.io :as io])
... (with-open [r (io/reader "authors.txt")]
(line-seq r)
regex
(def re #"\w+")
(if (re-matches re title)
(re-seq #"\w+" title)
->> lets you write a nested expression
(defn format-top-titles [books]
(->>
books
(sort-by :rating)
reverse
(take 3)
(map :title)
(interpose " // ")
(apply str)))
;; is equivalent to
(defn format-top-titles [books]
(apply
str
(interpose
" // "
(map :title (take 3 (reverse (sort-by :rating books)))))))
(def repeated-text (repeat jack))
(take 7 (cycle [1 2 3])) ;;will give you (1 2 3 1 2 3 1).
(def numbers [1 2 3])
(def trilogy (map #(str "w, Book " % ) numbers)) ;;gives
("w, Book 1"
"w, Book 2"
"w, Book 3")
lazy-seq uses some macro magi
;; Get the contents of the file as a string.
(slurp "chap1.txt")
;;skip lazy
(doall chapters)
doseq, which realizes each item in a lazy sequence one at a time
Destructuring (destructuring with function parameters and with let)
(let [[elem1 elem2 elem3] artists]
(let [[dummy dummy elem3] artists]
;or
(let [[_ _ elem3] artists]
(def authors [{:name "Jane Austen" :born 1775}
{:name "Charles Dickens" :born 1812}]
(let [[{dob-1 :born} {dob-2 :born}] authors]
{:name "Romeo" :age 16 :gender :male}
(defn character-desc [{name :name age :age gender :gender}] ;; or (defn character-desc [{:keys [name age gender]}]
(defrecord MyRec[name place animal])
(def watson (->MyRec "ka" "IN" "hen"))
or
(def elizabeth (map->MyRec
{:name "Elizabeth"
:place "PrideApts"
:animal "PrideLions"}))
(:name elizabeth)
;;use assoc to modify the values
(def specific-eliz (assoc elizabeth :place "Bungalow"))
return the type of the record
(class specific-eliz)
(= (instance? MyRec specific-eliz)
(defprotocol Person
(full-name [this])
(greeting [this msg])
(description [this]))
(defrecord FictionalCharacter[name appears-in author]
Person
(full-name [this] (:name this))
(greeting [this msg] (str msg " " (:name this)))
(description [this]
(str (:name this) " is a character in " (:appears-in this))))
(def sam (->FictionalCharacter "Sam Weller" "The Pickwick Papers" "Dickens"))
(greeting sam "Hello!")
(extend-protocol Marketable
Employee
...
FictionalCharacter
(make-slogan [fc] (str (:name fc) " is the GREATEST character!"))
(extend-protocol Marketable
String
(make-slogan [s] (str \" s \" " is a string! WOW!"))
Clojure provides us with reify, which takes a protocol name and some method implementations and creates a one-off implementation of that protocol:
(def test-component (reify Lifecycle
(start [this]
(println "Start!")
this)
(stop [this]
(println "Stop!")
this)))
(ns inventory.core-test
(:require [clojure.test :refer :all])
(:require [inventory.core :as i]))
(deftest test-finding-books
(is (not (nil? (i/find-by-title "Emma" books)))))
;;in run_tests.clj
(require '[inventory.core-test :as ct])
(ct/test-finding-books)
with lein test
test.check library provides a variety of generators, values you can use to generate test data
(require '[clojure.test.check.generators :as gen])
(gen/sample gen/string-alphanumeric)
(def copies-gen (gen/such-that (complement zero?) gen/pos-int))
;;generate an endless supply of inventories:
(def inventory-gen (gen/not-empty (gen/vector book-gen)))
...
(def book-gen
(gen/hash-map :title title-gen :author author-gen :copies copies-gen))
prop check ( test.check )
;;each positive integer is smaller than the next
(prop/for-all [i gen/pos-int]
(< i (inc i)))
(defspec longrange-equals-range 100
(prop/for-all [start gen/int
end gen/int
step gen/s-pos-int]
(= (clojure.lang.Range/create start end step)
(clojure.lang.LongRange/create start end step))))
(ns my-app.core
(:require [clojure.spec.alpha :as s]))
(s/valid? number? 44) ; Returns true.
(s/and number? #(> % 10) #(< % 100)))
(def n-or-s (s/or :a-number number? :a-string string?))
(s/valid? n-or-s "Hello!")
(s/coll-of string?)
(def book-s
(s/keys :req-un [:inventory.core/title
:inventory.core/author
:inventory.core/copies]))
(s/valid? book-s {:title "Arabian Nights" :copies 17})
clojure.core/def! The idea of clojure.spec/def is to allow you to register your spec in a JVM-wide registry of specs any code can then use. For example, this:
explain to figure out why your book map failed to match the spec
(s/explain ::book {:author :austen :title :emma})
;; for function
(s/fdef find-by-title
:args (s/cat :title ::title
:inventory ::inventory))
;;to use functional spec with unit test generator
(defn book-blurb [book]
| (str "The best selling book " (:title book) " by " (:author book)))
(s/fdef book-blurb
:args (s/cat :book ::book)
:ret (s/and string? (partial re-find #"The best selling")))
(stest/check 'inventory.core/book-blurb)
s/?. Essentially, s/? makes the next part of the spec optional
;use explain to figure out why your book map failed to match the spec:
(s/explain ::book {:author :austen :title :emma})
;even conform
;within tests
(require '[clojure.spec.test.alpha :as stest])
(stest/check 'inventory.core/book-blurb)
(defn check-return [{:keys [args ret]}]
(let [author (-> args :book :author)]
(not (neg? (.indexOf ret author)))))
;:fn key.
(s/fdef book-blurb
:args (s/cat :book ::book)
:ret (s/and string? (partial re-find #"The best selling"))
:fn check-return)
loop
(def authors (java.io.File. "authors.txt"))
(.exists authors)
(def rect (java.awt.Rectangle. 0 0 10 20))
we could then reach into its public fields:
(println "Width:" (.-width rect))
(println "Height:" (.-height rect))
(ns read-authors
(:import (java.io File InputStream)))
;; In the REPL.
(import '(java.io File InputStream))
(def temp-authors-file (File/createTempFile "authors_list" ".txt"))
lein new my-proj
(defproject my-proj "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.8.0"]
[com.google.code.gson/gson "2.8.0"]])
;you can use the built-in memfn function to turn a method name into a function. For example, while .exists is not a function, (memfn exists) is.
main
(defn -main []
(println "Coming to you live from the main thread!"))
new thread
;; Make a thread.
(defn do-in-a-thread []
(Thread/sleep 3000)
....)
(def the-thread (Thread. do-in-a-thread))
;; And run it.
(.start my-thread)
(.join my-thread)
;to deliver result
(def the-result (promise)); declare promise
(deliver the-result "A-Result"); from bg process
(deref the-result) ; or @the-result to get answer by waiting
;or better to autocreate thread
(def revenue-future
(future (apply + (map :revenue inventory))))
@revenue-future
;java way
(import java.util.concurrent.Executors)
(def fixed-pool (Executors/newFixedThreadPool 3))
(.execute work-1-func)
(.execute work-2-func)
;for timeout
(deref revenue-promise 500 :oh-snap)
;for non blocking main thread - allowing main to exit
(.setDaemon t true)
;parallel map
(pmap some-computationally-intensive-f a-collection)
(ns storefront.handler
(:require [compojure.core :refer :all]
[compojure.handler :as handler]))
(defroutes main-routes
(GET "/" [] "Welcome")
(GET "/book" [title author]
(str "....")))
(def app (handler/site main-routes))
(def counter (atom 0))
;then inside a method
(swap! counter inc); or (swap! counter + 1)
(if (= @counter 5)...
;maps too
(def by-title (atom {}))
(defn add-book [{title :title :as book}]
(swap! by-title #(assoc % title book)))
(swap! by-title #(assoc % dissoc book)))
;; for keeping 2 values synchronized
(def by-title (ref {}))
(def total-copies (ref 0))
;inside method
(dosync
(alter by-title #(assoc % title book))
(alter total-copies + (:copies book)))
;If there are side effects that need to happen as you update your mutable state, then use an agent.
;The purpose of memoize is to speed up your program by caching the results of function calls.
(shutdown-agents))
(def title-agent (agent "..."))
(send title-agent + "...")
(if (agent-error title-agent)
(restart-agent
title-agent
"..."
:clear-actions true))
(eval '(count title))
to read untrusted data'
(require '[clojure.edn :as edn])
(def untrusted (edn/read))
;macro
(defmacro print-it [something]
(list 'println "Something is" something))
(print-it (+ 10 20));; (println "Something is" (+ 10 20))
Example dependencies![image](https://github.com/kurtzace/diary-2024/assets/2136211/4cb3b511-ee43-4cc8-b71a-e0e1773284d7)
Line by line io![image](https://github.com/kurtzace/diary-2024/assets/2136211/84189eca-5653-4a28-8aa5-abe124f49f41)
Json file io
Thread![image](https://github.com/kurtzace/diary-2024/assets/2136211/15ff1535-8119-47ab-bf4f-10f88299647e)