(defmacro defn [name args body]
'(def ~name (fn ~args ~body)))
(defmacro ->> [coll &forms]
(.reduce forms coll (fn [a f] (.<< f a))))
(defmacro -> [coll &forms]
(.reduce forms coll (fn [a f] (.concat '(~(first f) ~a) (rest f)))))
(defn + [&xs]
(.reduce xs 0 :+))
(defn - [x &xs]
(if (.empty? xs) (- 0 x) (.reduce xs x :-)))
(defn * [&xs]
(.reduce xs 1 :*))
(defn / [x &xs]
(if (.empty? xs) (/ 1 x) (.reduce xs x :/)))
(defn > [&xs]
(.all? (.each_cons xs 2) (fn [[a b]] (.> a b))))
(defn >= [&xs]
(.all? (.each_cons xs 2) (fn [[a b]] (.>= a b))))
(defn < [&xs]
(.all? (.each_cons xs 2) (fn [[a b]] (.< a b))))
(defn <= [&xs]
(.all? (.each_cons xs 2) (fn [[a b]] (.<= a b))))
(defn = [&xs]
(.all? (.each_cons xs 2) (fn [[a b]] (.== a b))))
(defn compare [a b]
(.<=> a b))
(defn vector [&xs]
(.new Hamster/Vector xs))
(defn set [&xs]
(.new Hamster/Set xs))
(defn sorted-set [&xs]
(.new Hamster/SortedSet xs))
(defn sorted-set-by [comparator &xs]
(.new Hamster/SortedSet xs comparator))
(defn list [&xs]
(.new Hamster/List xs))
(defn hash-map [&xs]
(.new Hamster/Hash (.each_slice xs 2)))
(defn ruby-array [&xs]
(.new Array xs))
(defn ruby-set [&xs]
(.new Set xs))
(defn ruby-hash [&xs]
(.to_h (.each_slice xs 2)))
(defn nil? [x]
(.nil? x))
(defn filter [f coll]
(.select coll f))
(defn map [f coll]
(.map coll f))
(defn reduce [f s coll]
(if (nil? coll) (.reduce s f) (.reduce coll s f)))
(defn take [n coll]
(.take coll n))
(defn drop [n coll]
(.drop coll n))
(defn first [coll]
(.first coll))
(defn rest [coll]
(drop 1 coll))
(defn get [coll k default]
(.fetch coll k default))
(defn println [&xs]
(.puts (.new Object) (.join xs " ")))