added xi-forms
These work like Clojure's `#()` anonymous function literals.
This commit is contained in:
parent
4834b59cba
commit
0bf1084d8c
@ -13,14 +13,11 @@ concise and easy to read.
|
|||||||
|
|
||||||
-- Wikipedia (http://en.wikipedia.org/wiki/Anaphoric_macro)
|
-- Wikipedia (http://en.wikipedia.org/wiki/Anaphoric_macro)
|
||||||
|
|
||||||
Macros
|
|
||||||
======
|
|
||||||
|
|
||||||
|
|
||||||
.. _ap-if:
|
.. _ap-if:
|
||||||
|
|
||||||
ap-if
|
ap-if
|
||||||
-------
|
=====
|
||||||
|
|
||||||
Usage: ``(ap-if (foo) (print it))``
|
Usage: ``(ap-if (foo) (print it))``
|
||||||
|
|
||||||
@ -31,7 +28,7 @@ true and false branches.
|
|||||||
.. _ap-each:
|
.. _ap-each:
|
||||||
|
|
||||||
ap-each
|
ap-each
|
||||||
-------
|
=======
|
||||||
|
|
||||||
Usage: ``(ap-each [1 2 3 4 5] (print it))``
|
Usage: ``(ap-each [1 2 3 4 5] (print it))``
|
||||||
|
|
||||||
@ -228,3 +225,24 @@ Returns a function which applies several forms in series from left to right. The
|
|||||||
=> (def op (ap-compose (+ it 1) (* it 3)))
|
=> (def op (ap-compose (+ it 1) (* it 3)))
|
||||||
=> (op 2)
|
=> (op 2)
|
||||||
9
|
9
|
||||||
|
|
||||||
|
.. _xi
|
||||||
|
|
||||||
|
xi
|
||||||
|
==
|
||||||
|
|
||||||
|
Usage ``(xi function body ...)``
|
||||||
|
|
||||||
|
Returns a function with parameters implicitly determined by the presence in the body of xi parameters. An xi symbol designates the ith parameter (1-based, e.g. x1, x2, x3, etc.), or all remaining parameters for xi itself. This is not a replacement for lambda. The xi forms cannot be nested.
|
||||||
|
|
||||||
|
This is similar to Clojure's anonymous function literals (``#()``).
|
||||||
|
|
||||||
|
.. code-block:: hy
|
||||||
|
|
||||||
|
=> ((xi identity [x1 x5 [x2 x3] xi x4]) 1 2 3 4 5 6 7 8)
|
||||||
|
[1, 5, [2, 3,] (6, 7, 8), 4]
|
||||||
|
=> (def add-10 (xi + 10 x1))
|
||||||
|
=> (add-10 6)
|
||||||
|
16
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,3 +121,27 @@
|
|||||||
(defmacro ap-compose [&rest forms]
|
(defmacro ap-compose [&rest forms]
|
||||||
"Returns a function which is the composition of several forms."
|
"Returns a function which is the composition of several forms."
|
||||||
`(fn [var] (ap-pipe var ~@forms)))
|
`(fn [var] (ap-pipe var ~@forms)))
|
||||||
|
|
||||||
|
(defmacro xi [function &rest body]
|
||||||
|
"Returns a function with parameters implicitly determined by the presence in
|
||||||
|
the body of xi parameters. An xi symbol designates the ith parameter
|
||||||
|
(1-based, e.g. x1, x2, x3, etc.), or all remaining parameters for xi itself.
|
||||||
|
This is not a replacement for lambda. The xi forms cannot be nested. "
|
||||||
|
(setv flatbody (flatten body))
|
||||||
|
`(lambda [;; generate all xi symbols up to the maximum found in body
|
||||||
|
~@(genexpr (HySymbol (+ "x"
|
||||||
|
(str i)))
|
||||||
|
[i (range 1
|
||||||
|
;; find the maximum xi
|
||||||
|
(inc (max (genexpr (int (cdr a))
|
||||||
|
[a flatbody]
|
||||||
|
(and (symbol? a)
|
||||||
|
(.startswith a 'x)
|
||||||
|
(.isdigit (cdr a))))
|
||||||
|
:default 0)))])
|
||||||
|
;; generate the &rest paremeter only if 'xi is present in body
|
||||||
|
~@(if (in 'xi flatbody)
|
||||||
|
'(&rest xi)
|
||||||
|
'())]
|
||||||
|
(~function ~@body)))
|
||||||
|
|
||||||
|
@ -113,3 +113,25 @@
|
|||||||
"NATIVE: testing anaphoric compose"
|
"NATIVE: testing anaphoric compose"
|
||||||
(assert-equal ((ap-compose (+ it 1) (* it 3)) 2) 9)
|
(assert-equal ((ap-compose (+ it 1) (* it 3)) 2) 9)
|
||||||
(assert-equal ((ap-compose (list (rest it)) (len it)) [4 5 6 7]) 3))
|
(assert-equal ((ap-compose (list (rest it)) (len it)) [4 5 6 7]) 3))
|
||||||
|
|
||||||
|
(defn test-xi []
|
||||||
|
"NATIVE: testing xi forms"
|
||||||
|
;; test ordering
|
||||||
|
(assert-equal ((xi / x1 x2) 2 4) 0.5)
|
||||||
|
(assert-equal ((xi / x2 x1) 2 4) 2)
|
||||||
|
(assert-equal ((xi identity (, x5 x4 x3 x2 x1)) 1 2 3 4 5) (, 5 4 3 2 1))
|
||||||
|
(assert-equal ((xi identity (, x1 x2 x3 x4 x5)) 1 2 3 4 5) (, 1 2 3 4 5))
|
||||||
|
(assert-equal ((xi identity (, x1 x5 x2 x3 x4)) 1 2 3 4 5) (, 1 5 2 3 4))
|
||||||
|
;; test &rest
|
||||||
|
(assert-equal ((xi sum xi) 1 2 3) 6)
|
||||||
|
(assert-equal ((xi identity (, x1 xi)) 10 1 2 3) (, 10 (, 1 2 3)))
|
||||||
|
;; no parameters
|
||||||
|
(assert-equal ((xi list)) [])
|
||||||
|
(assert-equal ((xi identity "Hy!")) "Hy!")
|
||||||
|
(assert-equal ((xi identity "xi")) "xi")
|
||||||
|
(assert-equal ((xi + "Hy " "world!")) "Hy world!")
|
||||||
|
;; test skipped parameters
|
||||||
|
(assert-equal ((xi identity [x3 x1]) 1 2 3) [3 1])
|
||||||
|
;; test nesting
|
||||||
|
(assert-equal ((xi identity [x1 (, x2 [x3] "Hy" [xi])]) 1 2 3 4 5)
|
||||||
|
[1 (, 2 [3] "Hy" [(, 4 5)])]))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user