Inspired by Clojure.
Require & Import all objects and macros of hy-functional directly.
(hy.I.hy-functional._bootstrap)
(require
hy-functional.core [comment])
(defn add [x y]
(+ x y))
;; Ignore body when compile.
;; Writing some tests for repl or rct.
(comment
(add 1 2) ; => 3
(add 1 3) ; => 4
)
(require
hy-functional.core [ignore])
(defn log-error [msg]
;; Ignore body return value.
(ignore
(print msg)))
(require
hy-functional.core [if-not when-not])
(defn f [opts]
;; Reverse branch of if, short first for readability.
(if-not opts
(short-form)
(long-form
process-opts
...)))
(defn f [success?]
;; Reverse branch of when.
(when-not success?
(raise ...)))
(require
hy-functional.core [def])
;; Alias of setv, used in top level.
(def x 1)
(require
hy-functional.core [defarity])
;;; Clojure like fn def for varargs.
(defarity reduce
([f iterable]
...)
([f init iterable]
...))
(require
hy-functional.core [-> ->>])
(import
hy-functional.core [reduce inc even? assoc update])
;; For nested object transformation.
(-> {}
(assoc "a" 1 "b" 2)
(update "a" inc))
;; equiv: (update (assoc {} "a" 1 "a" 2) "a" inc)
;; => {"a" 2 "b" 2}
;; For nexted seq transformation.
(->> (range 4)
(map inc)
(filter even?)
(reduce +))
;; equiv: (reduce + (filter even? (map inc (range 4))))
;; => 6
(require
hy-functional.core [doto])
;; For impure object method calls.
(doto []
(.append 1)
(.extend [2 3]))
;; equiv: (let [$ []] (.append $ 1) (.extend $ [2 3]) $)
(require
hy-functional.core [cond-> cond->>])
(import
hy-functinal.core [conj assoc])
;; Easy opts processing.
(defn f [opt1 opt2]
(cond-> {}
opt1 (assoc "opt1" ...)
opt2 (assoc "opt2" ...)))
(defn g [opt1 opt2]
(cond-> []
opt1 (conj "opt1" ...)
opt2 (conj "opt2" ...)))
(require
hy-functional.core [loop])
;; Clojure like loop.
(loop [i 0]
(if (> i 10)
i
(recur (<< i 1))))
;; => 16
;; Loop with yield.
(loop [i 0]
(if (> i 10)
i
(do
(yield i)
(recur (<< i 1)))))
;; => 1, 2, 4, 8, 16
;; None pred.
(none? None) ; => True
(none? []) ; => False
(some? None) ; => False
(some? []) ; => True
;; Int utils.
(inc 1) ; => 2
(dec 2) ; => 1
(zero? 0) ; => True
(pos? 1) ; => True
(neg? -1) ; => True
(even? 2) ; => True
(odd? 1) ; => True
(defn f [callback]
(let [res ...]
(callback res)))
;; Accept any args, do nothing.
(f :callback ignore)
;; Cons a new fn like ignore with spec return value.
(f :callback (constantly :error))
;; Return arg directly.
(identity 1) ; => 1
;; Unit of fn mult.
(identity (f x)) ; => (f x)
;; Fn mult.
((comp inc inc) 1) ; => 3
((comp inc inc inc) 1) ; => 4
;; Partially bind args to fn.
(setv add-1-2-* (partial hy.pyops.+ 1 2))
(add-1-2-* 3) ; => 6
;; Curry the fn.
(setv add-1-*-* (curry 3 hy.pyops.+ 1))
(add-1-*-* 2 3) ; => 6
((add-1-*-* 2) 3) ; => 6
(filter even? (range 6)) ; => 0, 2, 4
;; Reverse pred result.
(filter (complement even?) (range 6)) ; => 1, 3, 5
;; Reduce seq to result by reducing fn: acc, input => acc.
(reduce hy.pyops.+ 1 (range 4)) ; => 10
(reduce hy.pyops.+ (range 4)) ; => 9
;; Reverse of filter.
(remove even? (range 6)) ; => 1, 3, 5
;; Concat seqs.
(concat [1 2] [3 4]) ; => 1, 2, 3, 4
(concat [1] [2 3] [4]) ; => 1, 2, 3, 4
;; Concat seqs from seq, for undetermined (even infinite) inputs.
(cat [[1 2] [3 4]]) ; => 1, 2, 3, 4
(cat [[1] [2 3] [4]]) ; => 1, 2, 3, 4
;; Concat one object before seq.
(cons 1 [2 3]) ; => 1, 2, 3
;; Concat result of maps.
(mapcat range [1 2 3]) ; => 0, 0, 1, 0, 1, 2
;; First of seq.
(first [1 2 3]) ; => 1
(first (range 3)) ; => 0
;; Rest of seq.
(rest [1 2 3]) ; => 2, 3
(rest (range 3)) ; => 1, 2
;; Is seq empty?
(empty? [1 2 3]) ; => False
(empty? (range 3)) ; => False
(empty? []) ; => True
(empty? (range 0)) ; => True
;; Second of seq.
(second [1 2]) ; => 2
(second (range 3)) ; => 1
;; Last of seq.
(last [1 2 3]) ; => 3
;; Seq without last.
(butlast [1 2 3]) ; => 2, 3
;; iterate fn on a init value.
(iterate inc 0) ; => 0, 1, 2, ...
(iterate dec 0) ; => 0, -1, -2, ...
;; Repeat value.
(repeat 1) ; => 1, 1, 1, ...
;; Repeat fn.
(repeatedly auto) ; => auto-0, auto-1, auto-2, ...
;; Cycle in seq.
(cycle [1 2 3]) ; => 1, 2, 3, 1, 2, 3, ...
;; Interleave shortest seqs.
(interleave [1 2 3] [4 5 6] [7 8 9 10]) ; => 1, 4, 7, 2, 5, 8, 3, 6, 9
;; Interpose sep to seq.
(interpose [0 [1 2 3]]) ; => 1, 0, 2, 0, 3
(interpose [0 [1]]) ; => 1,
(interpose [0 []]) ; => <empty>
;; Conjoin object to list.
(conj [1 2] 3) ; => [1 2 3]
(conj [1 2] 3 4) ; => [1 2 3 4]
;; Seqs into list.
(into [1 2] (range 3)) ; => [1 2 0 1 2]
;; Assoc dict of k to v.
(assoc {"a" 1} "b" 2) ; => {"a" 1 "b" 2}
(assoc {"a" 1} "b" 2 "c" 3) ; => {"a" 1 "b" 2 "c" 3}
;; Dissoc dict of k.
(dissoc {"a" 1 "b" 2} "b") ; => {"a" 1}
(dissoc {"a" 1 "b" 2} "a" "b") ; => {}
;; Update dict of k with f, and optional additional args.
(update {"a" 1 "b" 2} "a" inc) ; => {"a" 2 "b" 2}
(update {"a" 1 "b" 2} "a" hy.pyops.+ 2) ; => {"a" 3 "b" 2}
;; Merge dicts to one dict.
(merge {"a" 1 "b" 2} {"b" 3 "c" 4} {"c" 5 "d" 6}) ; {"a" 1 "b" 3 "c" 5 "d" 6}
;; Coll: iterable and not str or bytes.
(coll? "hello") ; => False
(coll? b"hello") ; => False
(coll? [1 2 3]) ; => True
(coll? #{1 2 3}) ; => True
(coll? (range 3)) ; => True
;; Flatten nested seq.
(flatten [1 2 [3 4 #{5 6} "hello"] "world"]) ; => 1, 2, 3, 4, 5, 6, "hello", "world"
;; Group seqs by key fn.
(group-by even? (range 10)) ; => {True [0 2 4 6 8] False [1 3 5 7 9]}
(group-by (fn [x] (% x 3)) (range 10)) ; => {0 [0 3 6 9] 1 [1 4 7] [2 5 8]}
TODO