![Paul Tagliamonte](/assets/img/avatar_default.png)
The fancypants Hy award goes to Nick for coming up with the quoted symbol hack for exports. This broke with foo?, since the export string needs to be is_foo, but using a quoted string will pick up the change due to it being a Symbol. Mad clown love for that, @olasd.
219 lines
5.7 KiB
Hy
219 lines
5.7 KiB
Hy
;; Copyright (c) 2013 Paul Tagliamonte <paultag@debian.org>
|
|
;; Copyright (c) 2013 Bob Tolbert <bob@tolbert.org>
|
|
|
|
;; Permission is hereby granted, free of charge, to any person obtaining a
|
|
;; copy of this software and associated documentation files (the "Software"),
|
|
;; to deal in the Software without restriction, including without limitation
|
|
;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
;; and/or sell copies of the Software, and to permit persons to whom the
|
|
;; Software is furnished to do so, subject to the following conditions:
|
|
|
|
;; The above copyright notice and this permission notice shall be included in
|
|
;; all copies or substantial portions of the Software.
|
|
|
|
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
;; DEALINGS IN THE SOFTWARE.
|
|
|
|
;;;; This contains some of the core Hy functions used
|
|
;;;; to make functional programming slightly easier.
|
|
;;;;
|
|
|
|
(defn _numeric-check [x]
|
|
(if (not (numeric? x))
|
|
(raise (TypeError (.format "{0!r} is not a number" x)))))
|
|
|
|
(defn cycle [coll]
|
|
"Yield an infinite repetition of the items in coll"
|
|
(setv seen [])
|
|
(foreach [x coll]
|
|
(yield x)
|
|
(.append seen x))
|
|
(while seen
|
|
(foreach [x seen]
|
|
(yield x))))
|
|
|
|
(defn dec [n]
|
|
"Decrement n by 1"
|
|
(_numeric-check n)
|
|
(- n 1))
|
|
|
|
(defn distinct [coll]
|
|
"Return a generator from the original collection with duplicates
|
|
removed"
|
|
(let [[seen []] [citer (iter coll)]]
|
|
(foreach [val citer]
|
|
(if (not_in val seen)
|
|
(do
|
|
(yield val)
|
|
(.append seen val))))))
|
|
|
|
(defn drop [count coll]
|
|
"Drop `count` elements from `coll` and yield back the rest"
|
|
(let [[citer (iter coll)]]
|
|
(try (foreach [i (range count)]
|
|
(next citer))
|
|
(catch [StopIteration]))
|
|
citer))
|
|
|
|
(defn drop-while [pred coll]
|
|
"Drop all elements of `coll` until `pred` is False"
|
|
(let [[citer (iter coll)]]
|
|
(foreach [val citer]
|
|
(if (not (pred val))
|
|
(do (yield val) (break))))
|
|
(foreach [val citer]
|
|
(yield val))))
|
|
|
|
(defn empty? [coll]
|
|
"Return True if `coll` is empty"
|
|
(= 0 (len coll)))
|
|
|
|
(defn even? [n]
|
|
"Return true if n is an even number"
|
|
(_numeric-check n)
|
|
(= (% n 2) 0))
|
|
|
|
(defn filter [pred coll]
|
|
"Return all elements from `coll` that pass `pred`"
|
|
(let [[citer (iter coll)]]
|
|
(foreach [val citer]
|
|
(if (pred val)
|
|
(yield val)))))
|
|
|
|
(defn float? [x]
|
|
"Return True if x is float"
|
|
(isinstance x float))
|
|
|
|
(defn inc [n]
|
|
"Increment n by 1"
|
|
(_numeric-check n)
|
|
(+ n 1))
|
|
|
|
(defn instance? [klass x]
|
|
(isinstance x klass))
|
|
|
|
(defn integer? [x]
|
|
"Return True if x in an integer"
|
|
(if-python2
|
|
(isinstance x (, int long))
|
|
(isinstance x int)))
|
|
|
|
(defn iterable? [x]
|
|
"Return true if x is iterable"
|
|
(try (do (iter x) true)
|
|
(catch [Exception] false)))
|
|
|
|
(defn iterate [f x]
|
|
(setv val x)
|
|
(while true
|
|
(yield val)
|
|
(setv val (f val))))
|
|
|
|
(defn iterator? [x]
|
|
"Return true if x is an iterator"
|
|
(try (= x (iter x))
|
|
(catch [TypeError] false)))
|
|
|
|
(defn neg? [n]
|
|
"Return true if n is < 0"
|
|
(_numeric-check n)
|
|
(< n 0))
|
|
|
|
(defn none? [x]
|
|
"Return true if x is None"
|
|
(is x None))
|
|
|
|
(defn numeric? [x]
|
|
(import numbers)
|
|
(instance? numbers.Number x))
|
|
|
|
(defn nth [coll index]
|
|
"Return nth item in collection or sequence, counting from 0"
|
|
(if (not (neg? index))
|
|
(if (iterable? coll)
|
|
(try (get (list (take 1 (drop index coll))) 0)
|
|
(catch [IndexError] None))
|
|
(try (get coll index)
|
|
(catch [IndexError] None)))
|
|
None))
|
|
|
|
(defn odd? [n]
|
|
"Return true if n is an odd number"
|
|
(_numeric-check n)
|
|
(= (% n 2) 1))
|
|
|
|
(defn pos? [n]
|
|
"Return true if n is > 0"
|
|
(_numeric_check n)
|
|
(> n 0))
|
|
|
|
(defn remove [pred coll]
|
|
"Return coll with elements removed that pass `pred`"
|
|
(let [[citer (iter coll)]]
|
|
(foreach [val citer]
|
|
(if (not (pred val))
|
|
(yield val)))))
|
|
|
|
(defn repeat [x &optional n]
|
|
"Yield x forever or optionally n times"
|
|
(if (none? n)
|
|
(setv dispatch (fn [] (while true (yield x))))
|
|
(setv dispatch (fn [] (foreach [_ (range n)] (yield x)))))
|
|
(dispatch))
|
|
|
|
(defn repeatedly [func]
|
|
"Yield result of running func repeatedly"
|
|
(while true
|
|
(yield (func))))
|
|
|
|
(defn second [coll]
|
|
"Return second item from `coll`"
|
|
(get coll 1))
|
|
|
|
(defn string? [x]
|
|
"Return True if x is a string"
|
|
(if-python2
|
|
(isinstance x (, str unicode))
|
|
(isinstance x str)))
|
|
|
|
(defn take [count coll]
|
|
"Take `count` elements from `coll`, or the whole set if the total
|
|
number of entries in `coll` is less than `count`."
|
|
(let [[citer (iter coll)]]
|
|
(foreach [_ (range count)]
|
|
(yield (next citer)))))
|
|
|
|
(defn take-nth [n coll]
|
|
"Return every nth member of coll
|
|
raises ValueError for (not (pos? n))"
|
|
(if (pos? n)
|
|
(let [[citer (iter coll)] [skip (dec n)]]
|
|
(foreach [val citer]
|
|
(yield val)
|
|
(foreach [_ (range skip)]
|
|
(next citer))))
|
|
(raise (ValueError "n must be positive"))))
|
|
|
|
(defn take-while [pred coll]
|
|
"Take all elements while `pred` is true"
|
|
(let [[citer (iter coll)]]
|
|
(foreach [val citer]
|
|
(if (pred val)
|
|
(yield val)
|
|
(break)))))
|
|
|
|
(defn zero? [n]
|
|
"Return true if n is 0"
|
|
(_numeric_check n)
|
|
(= n 0))
|
|
|
|
(def *exports* '[cycle dec distinct drop drop-while empty? even? filter float?
|
|
inc instance? integer? iterable? iterate iterator? neg? none?
|
|
nth numeric? odd? pos? remove repeat repeatedly second string?
|
|
take take-nth take-while zero?])
|