Merge branch 'master' into paultag/ana/if
Conflicts: hy/contrib/anaphoric.hy
This commit is contained in:
commit
1dc26148c6
@ -1,6 +1,8 @@
|
|||||||
====================
|
================
|
||||||
Anaphoric Macros
|
Anaphoric Macros
|
||||||
====================
|
================
|
||||||
|
|
||||||
|
.. versionadded:: 0.9.12
|
||||||
|
|
||||||
The anaphoric macros module makes functional programming in Hy very
|
The anaphoric macros module makes functional programming in Hy very
|
||||||
concise and easy to read.
|
concise and easy to read.
|
||||||
@ -94,3 +96,90 @@ the current element in the iteration.
|
|||||||
[4, 5]
|
[4, 5]
|
||||||
|
|
||||||
|
|
||||||
|
.. _ap-reject:
|
||||||
|
|
||||||
|
ap-reject
|
||||||
|
=========
|
||||||
|
|
||||||
|
Usage: ``(ap-reject form list)``
|
||||||
|
|
||||||
|
This function does the opposite of ``ap-filter``, it rejects the
|
||||||
|
elements passing the predicate . The special name ``it`` is bound to
|
||||||
|
the current element in the iteration.
|
||||||
|
|
||||||
|
.. code-block:: clojure
|
||||||
|
|
||||||
|
=> (list (ap-reject (> (* it 2) 6) [1 2 3 4 5]))
|
||||||
|
[1, 2, 3]
|
||||||
|
|
||||||
|
|
||||||
|
.. _ap-dotimes:
|
||||||
|
|
||||||
|
ap-dotimes
|
||||||
|
==========
|
||||||
|
|
||||||
|
Usage ``(ap-dotimes n body)``
|
||||||
|
|
||||||
|
This function evaluates the body *n* times, with the special
|
||||||
|
variable ``it`` bound from *0* to *1-n*. It is useful for side-effects.
|
||||||
|
|
||||||
|
.. code-block:: clojure
|
||||||
|
|
||||||
|
=> (setv n [])
|
||||||
|
=> (ap-dotimes 3 (.append n it))
|
||||||
|
=> n
|
||||||
|
[0, 1, 2]
|
||||||
|
|
||||||
|
|
||||||
|
.. _ap-first:
|
||||||
|
|
||||||
|
ap-first
|
||||||
|
========
|
||||||
|
|
||||||
|
Usage ``(ap-first predfn list)``
|
||||||
|
|
||||||
|
This function returns the first element that passes the predicate or
|
||||||
|
``None``, with the special variable ``it`` bound to the current element in
|
||||||
|
iteration.
|
||||||
|
|
||||||
|
.. code-block:: clojure
|
||||||
|
|
||||||
|
=>(ap-first (> it 5) (range 10))
|
||||||
|
6
|
||||||
|
|
||||||
|
|
||||||
|
.. _ap-last:
|
||||||
|
|
||||||
|
ap-last
|
||||||
|
========
|
||||||
|
|
||||||
|
Usage ``(ap-last predfn list)``
|
||||||
|
|
||||||
|
This function returns the last element that passes the predicate or
|
||||||
|
``None``, with the special variable ``it`` bound to the current element in
|
||||||
|
iteration.
|
||||||
|
|
||||||
|
.. code-block:: clojure
|
||||||
|
|
||||||
|
=>(ap-last (> it 5) (range 10))
|
||||||
|
9
|
||||||
|
|
||||||
|
|
||||||
|
.. _ap-reduce:
|
||||||
|
|
||||||
|
ap-reduce
|
||||||
|
=========
|
||||||
|
|
||||||
|
Usage ``(ap-reduce form list &optional initial-value)``
|
||||||
|
|
||||||
|
This function returns the result of applying form to the first 2
|
||||||
|
elements in the body and applying the result and the 3rd element
|
||||||
|
etc. until the list is exhausted. Optionally an initial value can be
|
||||||
|
supplied so the function will be applied to initial value and the
|
||||||
|
first element instead. This exposes the element being iterated as
|
||||||
|
``it`` and the current accumulated value as ``acc``.
|
||||||
|
|
||||||
|
.. code-block:: clojure
|
||||||
|
|
||||||
|
=>(ap-reduce (+ it acc) (range 10))
|
||||||
|
45
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
;;
|
;;
|
||||||
;; Copyright (c) 2013 James King <james@agentultra.com>
|
;; Copyright (c) 2013 James King <james@agentultra.com>
|
||||||
;; 2013 Paul R. Tagliamonte <tag@pault.ag>
|
;; 2013 Paul R. Tagliamonte <tag@pault.ag>
|
||||||
|
;; 2013 Abhishek L <abhishek.lekshmanan@gmail.com>
|
||||||
;;
|
;;
|
||||||
;; Permission is hereby granted, free of charge, to any person obtaining a
|
;; Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
;; copy of this software and associated documentation files (the "Software"),
|
;; copy of this software and associated documentation files (the "Software"),
|
||||||
@ -66,3 +67,42 @@
|
|||||||
(foreach [val ~lst]
|
(foreach [val ~lst]
|
||||||
(if (pred val)
|
(if (pred val)
|
||||||
(yield val)))))
|
(yield val)))))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro ap-reject [form lst]
|
||||||
|
"Yield elements returned when the predicate form evaluates to False"
|
||||||
|
`(ap-filter (not ~form) ~lst))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro ap-dotimes [n &rest body]
|
||||||
|
"Execute body for side effects `n' times, with it bound from 0 to n-1"
|
||||||
|
(unless (numeric? n)
|
||||||
|
(raise (TypeError (.format "{0!r} is not a number" n))))
|
||||||
|
`(ap-each (range ~n) ~@body))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro ap-first [predfn lst]
|
||||||
|
"Yield the first element that passes `predfn`"
|
||||||
|
`(let [[n (gensym)]]
|
||||||
|
(ap-each ~lst (when ~predfn (setv n it) (break)))
|
||||||
|
n))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro ap-last [predfn lst]
|
||||||
|
"Yield the last element that passes `predfn`"
|
||||||
|
`(let [[n (gensym)]]
|
||||||
|
(ap-each ~lst (none? n)
|
||||||
|
(when ~predfn
|
||||||
|
(setv n it)))
|
||||||
|
n))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro ap-reduce [form lst &optional [initial-value None]]
|
||||||
|
"Anaphoric form of reduce, `acc' and `it' can be used for a form"
|
||||||
|
(if (none? initial-value)
|
||||||
|
`(let [[acc (car ~lst)]]
|
||||||
|
(ap-each (cdr ~lst) (setv acc ~form))
|
||||||
|
acc)
|
||||||
|
`(let [[acc ~initial-value]]
|
||||||
|
(ap-each ~lst (setv acc ~form))
|
||||||
|
acc)))
|
||||||
|
@ -12,3 +12,4 @@ from .native_tests.when import * # noqa
|
|||||||
from .native_tests.with_decorator import * # noqa
|
from .native_tests.with_decorator import * # noqa
|
||||||
from .native_tests.core import * # noqa
|
from .native_tests.core import * # noqa
|
||||||
from .native_tests.reader_macros import * # noqa
|
from .native_tests.reader_macros import * # noqa
|
||||||
|
from .native_tests.contrib.anaphoric import * # noqa
|
||||||
|
0
tests/native_tests/contrib/__init__.hy
Normal file
0
tests/native_tests/contrib/__init__.hy
Normal file
@ -67,3 +67,35 @@
|
|||||||
[3 4])
|
[3 4])
|
||||||
(assert-equal (list (ap-filter (even? it) [1 2 3 4]))
|
(assert-equal (list (ap-filter (even? it) [1 2 3 4]))
|
||||||
[2 4]))
|
[2 4]))
|
||||||
|
|
||||||
|
(defn test-ap-reject []
|
||||||
|
"NATIVE: testing anaphoric filter"
|
||||||
|
(assert-equal (list (ap-reject (> it 2) [1 2 3 4]))
|
||||||
|
[1 2])
|
||||||
|
(assert-equal (list (ap-reject (even? it) [1 2 3 4]))
|
||||||
|
[1 3]))
|
||||||
|
|
||||||
|
(defn test-ap-dotimes []
|
||||||
|
"NATIVE: testing anaphoric dotimes"
|
||||||
|
(assert-equal (let [[n []]] (ap-dotimes 3 (.append n 3)) n)
|
||||||
|
[3 3 3])
|
||||||
|
(assert-equal (let [[n []]] (ap-dotimes 3 (.append n it)) n)
|
||||||
|
[0 1 2]))
|
||||||
|
|
||||||
|
(defn test-ap-first []
|
||||||
|
"NATIVE: testing anaphoric first"
|
||||||
|
(assert-equal (ap-first (> it 5) (range 10)) 6)
|
||||||
|
(assert-equal (ap-first (even? it) [1 2 3 4]) 2))
|
||||||
|
|
||||||
|
(defn test-ap-last []
|
||||||
|
"NATIVE: testing anaphoric last"
|
||||||
|
(assert-equal (ap-last (> it 5) (range 10)) 9)
|
||||||
|
(assert-equal (ap-last (even? it) [1 2 3 4]) 4))
|
||||||
|
|
||||||
|
(defn test-ap-reduce []
|
||||||
|
"NATIVE: testing anaphoric reduce"
|
||||||
|
(assert-equal (ap-reduce (* acc it) [1 2 3]) 6)
|
||||||
|
(assert-equal (ap-reduce (* acc it) [1 2 3] 6) 36)
|
||||||
|
(assert-equal (ap-reduce (+ acc " on " it) ["Hy" "meth"])
|
||||||
|
"Hy on meth")
|
||||||
|
(assert-equal (ap-reduce (+ acc it) [] 1) 1))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user