Skip to content

Instantly share code, notes, and snippets.

Avatar

Mark Woodworth Solaxun

  • First Republic Bank
  • San Francisco
View GitHub Profile
@Solaxun
Solaxun / destructuring.clj
Created Jul 21, 2020
restructuring destructuring
View destructuring.clj
(defmulti destruct-type
(fn [binding value]
(cond (sequential? binding) clojure.lang.Sequential ; order matters, vector is associative too
(associative? binding) clojure.lang.Associative
:else (type binding))))
(defn coerce-binding-type [binding-type]
(case binding-type
:strs str
:syms (fn [sym] `'~sym)
@Solaxun
Solaxun / compiletime-closures.clj
Last active Jul 20, 2020
At runtime, the function created by the macroexpansion captures lexical scope from wherever it's called, and is stored in the atom.
View compiletime-closures.clj
(def protos (atom nil))
(defn build-func [[name args body]]
(list 'fn name args body))
(defmacro bleh [fbody]
`(let [f# ~(build-func fbody)]
(do (reset! protos f#) f#)))
(macroexpand-1 '(bleh (foo [y] (+ x y))))
@Solaxun
Solaxun / reify-toy.clj
Last active Jul 19, 2020
Toy implementation of reify, doesn't check the methods are actually part of the protocol, doesn't do namespacing, etc. Just mimicks the interface.
View reify-toy.clj
;;;
;;; implementation
;;;
(defn build-fn [[mname args body]]
{(keyword mname) (list 'fn mname args body)})
(defn make-generic-fn [[mname args body]]
`(defn ~mname ~args
(let [f# (get ~(first args) ~(keyword mname))]
(f# ~@args))))
@Solaxun
Solaxun / multimethods-toy.clj
Last active Jul 20, 2020
toy multimethod implementation
View multimethods-toy.clj
;;;; machinery for multimethods
(defmacro defmethod2 [fname dispatch-val signature body]
`(swap! ~(symbol (str "multimethod-lkp-" fname)) assoc ~dispatch-val
(fn ~signature ~body)))
(defn make-generic-fn [fname dispatchfn]
`(defn ~fname [& ~'args]
(let [dispatch-val# (apply ~(symbol (str "multimethod-dispatch-" fname)) ~'args)
mm-table# (deref ~(symbol (str "multimethod-lkp-" fname)))
matching-fn# (some #(get mm-table# %) [dispatch-val# :default])]
View mm-vs-protocols.clj
(comment
Multimethods are an open dispatch mechanism, but is closed in it's
dispatch function. If the set of dispatch types is open, so is
the multimethod.
Protocols are always open because you can always add a new type.
Multimethods require you to pick something to dispatch on that
remains open so any user can create a new one.
For dependency injection, protocols work great because you can
@Solaxun
Solaxun / ibid.clj
Created Dec 5, 2019
ibid clojure - from Gene Kim's interview on the Functional Geekery podcast.
View ibid.clj
;; couldn't resist after hearing the podcast...
(defn ibid [coll]
(reduce (fn [res cur]
(if (= cur "ibid")
(conj res (last res))
(conj res cur)))
[(first coll)]
(rest coll)))
@Solaxun
Solaxun / my-cons.clj
Last active Jul 3, 2020
Clojure Cons Cell
View my-cons.clj
(def NIL (symbol "NIL"))
(deftype ConsCell [CAR CDR]
clojure.lang.ISeq
(cons [this x] (ConsCell. x this))
(first [this] (.CAR this))
;; next and more must return ISeq:
;; https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java
(more [this] (if
(= (.CDR this) NIL)
@Solaxun
Solaxun / day13.clj
Created Dec 15, 2018
2018 Advent of Code Day 13
View day13.clj
(ns aoc2018-clj.day13
(:require [clojure.string :as str]
[clojure.java.io :as io]
[clojure.math.combinatorics :as combs]
[clojure.set :as set]))
(def track (str/split-lines (-> "day13.txt" io/resource slurp)))
(def race-track (mapv vec track))
(defn intersection-rule [{:keys [loc dir turn-count] :as car}]
You can’t perform that action at this time.