Skip to content

Instantly share code, notes, and snippets.

;; What's a partial function?
(partial + 1)
;; this partial function is a function which returns a function whose operator is "addition" and whose first parameter is 1
;; let's give this a name to give you some intution.
(def inc (partial + 1))
;; just like you can create a new function in terms of a partial function, you can also compose functions.
(def false? (comp not true?))
;; see what we did there? We defined a new function, false?, which returns true if the argument is false
;; by composing two functions - true? and not.
;; true? is a function which returns true if its argument is truthy
;; and false if its argument is not truthy, which in Clojure is only one of two values - false and nil.
;; in math, when you compose functions, you "unroll" them from the innermost function call outward.
;; so what is stream fusion in a nutshell?
;; now that you have an intution for partial functions and composed functions, you now possess the intuition for stream fusion!
;; in category theory, mathematicians attempt to "categorize" all sorts of different "like" objects.
;; You're probably familiar with the notion of a Set in math. A set is an unordered and unique "bag" of elements.
(def my-set #{1 2 3})
#{1 2 3}
;; you can perform certain operations on sets.
(union my-set #{4 5 6})
#{1 2 3 4 5 6}
;; now remember, clojure values are immutable by default, so my-set (the var itself) is still pointing to #{1 2 3}, but this an aside.
;; so now that you can intuitively understand the notion of a "Category", let's talk about Streams.
;; Streams are a category invented to optimize the execution of functions performed on Lists.
;; Categories are like Types in a way. We can have Real numbers, Complex numbers, Sets, Integers, Lists, etc.
;; They all have different properties. Some are more general, and some are less general.
;; When we can create a function that maps an element of one Category A to another Category B in
;; a way that preserves the "structure" of the category, we have shown that there is some morphism between them.
;; a "morphism" is just a fancy way of saying mapping function, (map)!
;; we create morphisms all the time in functional programming.
;; So now you have a feel for when you can preserve the essence of some function or procedure, even when it appears different at first glance.
;; Now we are finally ready to understand Stream Fusion.
;; Streams are a "Type" of sequential collection that may be useful for "unrolling" complex list operations into
;; a list which is structurally equivalent, but much faster to execute.
;; consider the following
(->> (map squared (range 100))
(filter even?)
(remove prime?)
(defn cyborg?
[user]
(->> (get-in user [:user :description])
(tokenize) (pos-tag) (personal-pronouns)
(map first)
(map str/lower-case)
(set)
(intersection person-pronouns)
(intersection non-org-pronouns)
(empty?)))
(defn import!
[resources account-id]
(map
(fn [resource]
(if-let [doc (mc/find-by-id "resources" (:URI resource))]
(mc/update-by-id "resources" (:URI resource)
(if-let
[account (get-in doc ["accounts" account-id])]
{$inc {(str "accounts" "." account-id) 1}}
{$set {(str "accounts" "." account-id) 1}}))
;; sometimes it's useful to cache results of previous computations so you don't have to repeat them again
(def sum (memo #(reduce + (range %)))
;; where the input to sum is the limit of the range of the numbers you want to sum
(time (sum 100000))
"Elapsed time: 44.191 msecs"
4999950000
(defmacro compile-events
[events]
(let [handlers (vals events)
compiled-handlers
(for [handler handlers]
(let [func (into (list) (reverse (cons 'defn (cons 'e (rest handler)))))]
(-> (build func {:optimizations :advanced})
(clojure.string/replace #"^.*=" "var tmp=")
(clojure.string/replace #";$" "; tmp;"))))]
(json/write-str (zipmap (keys events) compiled-handlers))))
(defprotocol IAnimatable
(position [this])
(scroll [this])
(dims [this])
(width [this])
(height [this])
(fade-in! [el time show?])
(fade-out! [el time hide?]))
(extend-protocol IAnimatable