Remove car
and cdr
in favor of first
and rest
(#1241)
* Remove uses of `car` and `cdr` in /hy * Remove uses of `car` and `cdr` in quote tests * Remove `car` and `cdr` in favor of `first` and `rest` I beefed up the documentation and tests for `first` and `rest` while I was at it. I defined `car` and `cdr` in native_tests.cons so the tests read a bit more naturally.
This commit is contained in:
parent
8ecb17d1fd
commit
8b6a45e43a
@ -850,16 +850,26 @@ eval-when-compile
|
|||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
||||||
first / car
|
first
|
||||||
-----------
|
-----
|
||||||
|
|
||||||
``first`` and ``car`` are macros for accessing the first element of a collection:
|
``first`` is a function for accessing the first element of a collection.
|
||||||
|
|
||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
=> (first (range 10))
|
=> (first (range 10))
|
||||||
0
|
0
|
||||||
|
|
||||||
|
It is implemented as ``(next (iter coll) None)``, so it works with any
|
||||||
|
iterable, and if given an empty iterable, it will return ``None`` instead of
|
||||||
|
raising an exception.
|
||||||
|
|
||||||
|
.. code-block:: clj
|
||||||
|
|
||||||
|
=> (first (repeat 10))
|
||||||
|
10
|
||||||
|
=> (first [])
|
||||||
|
None
|
||||||
|
|
||||||
for
|
for
|
||||||
---
|
---
|
||||||
@ -1402,17 +1412,23 @@ periods in them. In fact, ``mymodule`` and ``M`` aren't defined by these
|
|||||||
to do introspection of the current module's set of defined macros, which isn't
|
to do introspection of the current module's set of defined macros, which isn't
|
||||||
really supported anyway.
|
really supported anyway.
|
||||||
|
|
||||||
rest / cdr
|
rest
|
||||||
----------
|
----
|
||||||
|
|
||||||
``rest`` and ``cdr`` return the collection passed as an argument without the
|
``rest`` takes the given collection and returns an iterable of all but the
|
||||||
first element:
|
first element.
|
||||||
|
|
||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
=> (rest (range 10))
|
=> (list (rest (range 10)))
|
||||||
[1, 2, 3, 4, 5, 6, 7, 8, 9]
|
[1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
|
|
||||||
|
Given an empty collection, it returns an empty iterable.
|
||||||
|
|
||||||
|
.. code-block:: clj
|
||||||
|
|
||||||
|
=> (list (rest []))
|
||||||
|
[]
|
||||||
|
|
||||||
set-comp
|
set-comp
|
||||||
--------
|
--------
|
||||||
|
@ -111,10 +111,10 @@ Returns a fresh :ref:`cons cell <hycons>` with car *a* and cdr *b*.
|
|||||||
|
|
||||||
=> (setv a (cons 'hd 'tl))
|
=> (setv a (cons 'hd 'tl))
|
||||||
|
|
||||||
=> (= 'hd (car a))
|
=> (= 'hd (get a 0))
|
||||||
True
|
True
|
||||||
|
|
||||||
=> (= 'tl (cdr a))
|
=> (= 'tl (cut a 1))
|
||||||
True
|
True
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,6 +87,9 @@
|
|||||||
(with-decorator (method-decorator ~name)
|
(with-decorator (method-decorator ~name)
|
||||||
(defn ~name ~params ~@body))))
|
(defn ~name ~params ~@body))))
|
||||||
|
|
||||||
|
(defn head-tail [l]
|
||||||
|
(, (get l 0) (cut l 1)))
|
||||||
|
|
||||||
(defmacro defn [name &rest bodies]
|
(defmacro defn [name &rest bodies]
|
||||||
(def arity-overloaded? (fn [bodies]
|
(def arity-overloaded? (fn [bodies]
|
||||||
(if (isinstance (first bodies) HyString)
|
(if (isinstance (first bodies) HyString)
|
||||||
@ -97,17 +100,14 @@
|
|||||||
(do
|
(do
|
||||||
(def comment (HyString))
|
(def comment (HyString))
|
||||||
(if (= (type (first bodies)) HyString)
|
(if (= (type (first bodies)) HyString)
|
||||||
(do (def comment (car bodies))
|
(def [comment bodies] (head-tail bodies)))
|
||||||
(def bodies (cdr bodies))))
|
|
||||||
(def ret `(do))
|
(def ret `(do))
|
||||||
(.append ret '(import [hy.contrib.multi [MultiDispatch]]))
|
(.append ret '(import [hy.contrib.multi [MultiDispatch]]))
|
||||||
(for [body bodies]
|
(for [body bodies]
|
||||||
(def let-binds (car body))
|
(def [let-binds body] (head-tail body))
|
||||||
(def body (cdr body))
|
|
||||||
(.append ret
|
(.append ret
|
||||||
`(with-decorator MultiDispatch (defn ~name ~let-binds ~comment ~@body))))
|
`(with-decorator MultiDispatch (defn ~name ~let-binds ~comment ~@body))))
|
||||||
ret)
|
ret)
|
||||||
(do
|
(do
|
||||||
(setv lambda-list (first bodies))
|
(setv [lambda-list body] (head-tail bodies))
|
||||||
(setv body (rest bodies))
|
|
||||||
`(setv ~name (fn ~lambda-list ~@body)))))
|
`(setv ~name (fn ~lambda-list ~@body)))))
|
||||||
|
@ -59,16 +59,6 @@
|
|||||||
`(do ~@body)))
|
`(do ~@body)))
|
||||||
|
|
||||||
|
|
||||||
(defmacro car [thing]
|
|
||||||
"Get the first element of a list/cons"
|
|
||||||
`(get ~thing 0))
|
|
||||||
|
|
||||||
|
|
||||||
(defmacro cdr [thing]
|
|
||||||
"Get all the elements of a thing, except the first"
|
|
||||||
`(cut ~thing 1))
|
|
||||||
|
|
||||||
|
|
||||||
(defmacro cond [&rest branches]
|
(defmacro cond [&rest branches]
|
||||||
"shorthand for nested ifs:
|
"shorthand for nested ifs:
|
||||||
(cond [foo bar] [baz quux]) ->
|
(cond [foo bar] [baz quux]) ->
|
||||||
@ -87,8 +77,8 @@
|
|||||||
(macro-error branch "cond branches need to be a list"))
|
(macro-error branch "cond branches need to be a list"))
|
||||||
(if (< (len branch) 2)
|
(if (< (len branch) 2)
|
||||||
(macro-error branch "cond branches need at least two items: a test and one or more code branches"))
|
(macro-error branch "cond branches need at least two items: a test and one or more code branches"))
|
||||||
(setv test (car branch))
|
(setv test (first branch))
|
||||||
(setv thebranch (cdr branch))
|
(setv thebranch (cut branch 1))
|
||||||
`(if ~test (do ~@thebranch)))
|
`(if ~test (do ~@thebranch)))
|
||||||
|
|
||||||
(setv root (check-branch branch))
|
(setv root (check-branch branch))
|
||||||
|
@ -114,8 +114,8 @@
|
|||||||
(defmacro ap-reduce [form lst &optional [initial-value None]]
|
(defmacro ap-reduce [form lst &optional [initial-value None]]
|
||||||
"Anaphoric form of reduce, `acc' and `it' can be used for a form"
|
"Anaphoric form of reduce, `acc' and `it' can be used for a form"
|
||||||
`(do
|
`(do
|
||||||
(setv acc ~(if (none? initial-value) `(car ~lst) initial-value))
|
(setv acc ~(if (none? initial-value) `(get ~lst 0) initial-value))
|
||||||
(ap-each ~(if (none? initial-value) `(cdr ~lst) lst)
|
(ap-each ~(if (none? initial-value) `(cut ~lst 1) lst)
|
||||||
(setv acc ~form))
|
(setv acc ~form))
|
||||||
acc))
|
acc))
|
||||||
|
|
||||||
@ -142,11 +142,11 @@
|
|||||||
(str i)))
|
(str i)))
|
||||||
[i (range 1
|
[i (range 1
|
||||||
;; find the maximum xi
|
;; find the maximum xi
|
||||||
(inc (max (+ (list-comp (int (cdr a))
|
(inc (max (+ (list-comp (int (cut a 1))
|
||||||
[a flatbody]
|
[a flatbody]
|
||||||
(and (symbol? a)
|
(and (symbol? a)
|
||||||
(.startswith a 'x)
|
(.startswith a 'x)
|
||||||
(.isdigit (cdr a))))
|
(.isdigit (cut a 1))))
|
||||||
[0]))))])
|
[0]))))])
|
||||||
;; generate the &rest parameter only if 'xi is present in body
|
;; generate the &rest parameter only if 'xi is present in body
|
||||||
~@(if (in 'xi flatbody)
|
~@(if (in 'xi flatbody)
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
(defmacro car [x] `(get ~x 0))
|
||||||
|
(defmacro cdr [x] `(cut ~x 1))
|
||||||
|
|
||||||
|
|
||||||
(defn test-cons-mutability []
|
(defn test-cons-mutability []
|
||||||
"Test the mutability of conses"
|
"Test the mutability of conses"
|
||||||
(setv tree (cons (cons 1 2) (cons 2 3)))
|
(setv tree (cons (cons 1 2) (cons 2 3)))
|
||||||
|
@ -681,10 +681,11 @@
|
|||||||
|
|
||||||
|
|
||||||
(defn test-first []
|
(defn test-first []
|
||||||
"NATIVE: test firsty things"
|
"NATIVE: test first"
|
||||||
(assert (= (first [1 2 3 4 5]) 1))
|
(assert (= (first [1 2 3 4 5]) 1))
|
||||||
(assert (is (first []) None))
|
(assert (= (first (range 10)) 0))
|
||||||
(assert (= (car [1 2 3 4 5]) 1)))
|
(assert (= (first (repeat 10)) 10))
|
||||||
|
(assert (is (first []) None)))
|
||||||
|
|
||||||
|
|
||||||
(defn test-cut []
|
(defn test-cut []
|
||||||
@ -710,7 +711,9 @@
|
|||||||
|
|
||||||
(defn test-rest []
|
(defn test-rest []
|
||||||
"NATIVE: test rest"
|
"NATIVE: test rest"
|
||||||
(assert (= (list (rest [1 2 3 4 5])) [2 3 4 5])))
|
(assert (= (list (rest [1 2 3 4 5])) [2 3 4 5]))
|
||||||
|
(assert (= (list (take 3 (rest (iterate inc 8)))) [9 10 11]))
|
||||||
|
(assert (= (list (rest [])) [])))
|
||||||
|
|
||||||
|
|
||||||
(defn test-importas []
|
(defn test-importas []
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
(defn test-quoted-hoistable []
|
(defn test-quoted-hoistable []
|
||||||
"NATIVE: check whether quote works on hoisted things"
|
"NATIVE: check whether quote works on hoisted things"
|
||||||
(setv f (quote (if True True True)))
|
(setv f (quote (if True True True)))
|
||||||
(assert (= (car f) (quote if)))
|
(assert (= (get f 0) (quote if)))
|
||||||
(assert (= (cdr f) (quote (True True True)))))
|
(assert (= (cut f 1) (quote (True True True)))))
|
||||||
|
|
||||||
|
|
||||||
(defn test-quoted-macroexpand []
|
(defn test-quoted-macroexpand []
|
||||||
@ -20,8 +20,8 @@
|
|||||||
(setv q1 (quote (-> a b c)))
|
(setv q1 (quote (-> a b c)))
|
||||||
(setv q2 (quasiquote (-> a b c)))
|
(setv q2 (quasiquote (-> a b c)))
|
||||||
(assert (= q1 q2))
|
(assert (= q1 q2))
|
||||||
(assert (= (car q1) (quote ->)))
|
(assert (= (get q1 0) (quote ->)))
|
||||||
(assert (= (cdr q1) (quote (a b c)))))
|
(assert (= (cut q1 1) (quote (a b c)))))
|
||||||
|
|
||||||
|
|
||||||
(defn test-quote-dicts []
|
(defn test-quote-dicts []
|
||||||
|
Loading…
x
Reference in New Issue
Block a user