Second (smaller) set of native core functions

This rounds out the first pass at a set of core functions, adding
some that were not in the first PR.

From here I'm working on a contrib.seq and contrib.io module to
hold less obvious but maybe interesting native functions that can
move to core if desired.

This should also close out issure #150 asking for some core
functions like these.
This commit is contained in:
Bob Tolbert 2013-07-29 10:40:48 -06:00
parent b2c51d0130
commit 399ea1889a
3 changed files with 288 additions and 5 deletions

View File

@ -15,6 +15,8 @@ Usage: ``(dec x)``
Return one less than x. Equivalent to ``(- x 1)``.
Raises ``TypeError`` if ``(not (numeric? x))``.
.. code-block:: clojure
=> (dec 3)
@ -27,6 +29,45 @@ Return one less than x. Equivalent to ``(- x 1)``.
11.3
.. _emtpy?-fn:
empty?
------
Usage: ``(empty? coll)``
Return True if ``coll`` is empty, i.e. ``(= 0 (len coll))``.
.. code-block:: clojure
=> (empty? [])
True
=> (empty? "")
True
=> (empty? (, 1 2))
False
.. _float?-fn:
float?
-------
Usage: ``(float? x)``
Return True if x is a float.
.. code-block:: clojure
=> (float? 3.2)
True
=> (float? -2)
False
.. _even?-fn:
even?
@ -36,6 +77,8 @@ Usage: ``(even? x)``
Return True if x is even.
Raises ``TypeError`` if ``(not (numeric? x))``.
.. code-block:: clojure
=> (even? 2)
@ -57,6 +100,8 @@ Usage: ``(inc x)``
Return one more than x. Equivalent to ``(+ x 1)``.
Raises ``TypeError`` if ``(not (numeric? x))``.
.. code-block:: clojure
=> (inc 3)
@ -94,6 +139,24 @@ Return True if x is an instance of CLASS.
=> (instance? TestClass inst)
True
.. _integer?-fn:
integer?
--------
Usage: ``(integer? x)``
Return True if x is an integer. For Python 2, this is
either ``int`` or ``long``. For Python 3, this is ``int``.
.. code-block:: clojure
=> (integer? 3)
True
=> (integer? -2.4)
False
.. _iterable?-fn:
@ -166,6 +229,8 @@ Usage: ``(neg? x)``
Return True if x is less than zero (0).
Raises ``TypeError`` if ``(not (numeric? x))``.
.. code-block:: clojure
=> (neg? -2)
@ -228,6 +293,28 @@ if the `n` is outside the range of `coll`.
=> (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2))
5
.. _numeric?-fn:
numeric?
---------
Usage: ``(numeric? x)``
Return True if x is a numeric, as defined in the Python
numbers module class ``numbers.Number``.
.. code-block:: clojure
=> (numeric? -2)
True
=> (numeric? 3.2)
True
=> (numeric? "foo")
False
.. _odd?-fn:
odd?
@ -237,6 +324,8 @@ Usage: ``(odd? x)``
Return True if x is odd.
Raises ``TypeError`` if ``(not (numeric? x))``.
.. code-block:: clojure
=> (odd? 13)
@ -258,6 +347,8 @@ Usage: ``(pos? x)``
Return True if x is greater than zero (0).
Raises ``TypeError`` if ``(not (numeric? x))``.
.. code-block:: clojure
=> (pos? 3)
@ -290,6 +381,39 @@ Return True if x is zero (0).
=> (zero? 0)
True
.. _second-fn:
second
-------
Usage: ``(second coll)``
Return the second member of ``coll``. Equivalent to
``(get coll 1)``
.. code-block:: clojure
=> (second [0 1 2])
1
.. _string?-fn:
string?
-------
Usage: ``(string? x)``
Return True if x is a string.
.. code-block:: clojure
=> (string? "foo")
True
=> (string? -2)
False
Sequence Functions
=======================
@ -410,6 +534,27 @@ Return an iterator, skipping the first ``n`` members of ``coll``
=> (list (drop 6 [1 2 3 4 5]))
[]
.. _drop-while-fn:
drop-while
-----------
Usage: ``(drop-while pred coll)``
Return an iterator, skipping members of ``coll`` until ``pred``
is False.
.. code-block:: clojure
=> (list (drop-while even? [2 4 7 8 9]))
[7, 8, 9]
=> (list (drop-while numeric? [1 2 3 None "a"])))
[None, u'a']
=> (list (drop-while pos? [2 4 7 8 9]))
[]
.. _filter-fn:

View File

@ -1,8 +1,28 @@
;; 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)))))
@ -40,6 +60,20 @@
(catch [StopIteration]))
citer))
(defn drop-while [pred coll]
"Drop all elements of `coll` until `pred` is False"
(let [[citer (iter coll)]]
(let [found false]
(for [val citer]
(if (not (pred val))
(setv found true))
(if found
(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)
@ -52,6 +86,10 @@
(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)
@ -60,6 +98,13 @@
(defn instance? [klass x]
(isinstance x klass))
(defn integer? [x]
"Return True if x in an integer"
(import sys)
(if (< (get sys.version_info 0) 3)
(isinstance x (, int long)))
(isinstance x int))
(defn iterable? [x]
"Return true if x is iterable"
(try (do (iter x) true)
@ -128,6 +173,17 @@
(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"
(import sys)
(if (< (get sys.version_info 0) 3)
(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`."
@ -159,7 +215,9 @@
(_numeric_check n)
(= n 0))
(def *exports* ["cycle" "dec" "distinct" "drop" "even?" "filter" "inc"
"instance?" "iterable?" "iterate" "iterator?" "neg?"
(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" "take" "take_nth" "take_while" "zero?"])
"repeatedly" "second" "string?" "take" "take_nth" "take_while"
"zero?"])

View File

@ -1,4 +1,23 @@
(import time)
;; 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.
;;;; some simple helpers
@ -62,6 +81,28 @@
(setv res (list (take 5 (drop 2 (iterate inc 0)))))
(assert-equal res [2 3 4 5 6]))
(defn test-drop-while []
"NATIVE: testing drop-while function"
(setv res (list (drop-while even? [2 4 7 8 9])))
(assert (= res [7 8 9]))
(setv res (list (drop-while pos? [2 4 7 8 9])))
(assert (= res []))
(setv res (list (drop-while numeric? [1 2 3 None "a"])))
(assert (= res [None "a"])))
(defn test-empty? []
"NATIVE: testing the empty? function"
(assert-true (empty? ""))
(assert-false (empty? "None"))
(assert-true (empty? (,)))
(assert-false (empty? (, None)))
(assert-true (empty? []))
(assert-false (empty? [None]))
(assert-true (empty? {}))
(assert-false (empty? {"a" None}))
(assert-true (empty? (set)))
(assert-false (empty? (set [None]))))
(defn test-even []
"NATIVE: testing the even? function"
(assert-true (even? -2))
@ -92,6 +133,14 @@
(setv res (list (filter none? [1 2 None 3 4 None 4 6])))
(assert-equal res [None None]))
(defn test-float? []
"NATIVE: testing the float? function"
(assert-true (float? 4.2))
(assert-false (float? 0))
(assert-false (float? -3))
(assert-true (float? -3.2))
(assert-false (float? "foo")))
(defn test-inc []
"NATIVE: testing the inc function"
(assert-equal 3 (inc 2))
@ -117,6 +166,15 @@
(assert-true (instance? int 3))
(assert-true (instance? str (str "hello"))))
(defn test-integer? []
"NATIVE: testing the integer? function"
(assert-true (integer? 0))
(assert-true (integer? 3))
(assert-true (integer? -3))
(assert-false (integer? 4.2))
(assert-false (integer? None))
(assert-false (integer? "foo")))
(defn test-iterable []
"NATIVE: testing iterable? function"
;; should work for a string
@ -213,6 +271,15 @@
(assert-true (none? (nth (iter [1 2 4 7]) -1)))
(assert-equal 5 (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2)))
(defn test-numeric? []
"NATIVE: testing the numeric? function"
(assert-true (numeric? 1))
(assert-true (numeric? 3.4))
(assert-true (numeric? 0.0))
(assert-true (numeric? -1.45))
(assert-false (numeric? "Foo"))
(assert-false (numeric? None)))
(defn test-odd []
"NATIVE: testing the odd? function"
(assert-true (odd? -3))
@ -262,6 +329,19 @@
(assert-equal (list (take 4 r)) [5 5 5 5])
(assert-equal (list (take 6 r)) [5 5 5 5 5 5]))
(defn test-second []
"NATIVE: testing second"
(assert-equal 2 (second [1 2]))
(assert-equal 3 (second [2 3 4])))
(defn test-string? []
"NATIVE: testing string?"
(assert-true (string? "foo"))
(assert-true (string? ""))
(assert-false (string? 5.3))
(assert-true (string? (str 5.3)))
(assert-false (string? None)))
(defn test-take []
"NATIVE: testing the take function"
(setv res (list (take 3 [1 2 3 4 5])))