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)
|
||||
|
||||
Macros
|
||||
======
|
||||
|
||||
|
||||
.. _ap-if:
|
||||
|
||||
ap-if
|
||||
-------
|
||||
=====
|
||||
|
||||
Usage: ``(ap-if (foo) (print it))``
|
||||
|
||||
@ -31,7 +28,7 @@ true and false branches.
|
||||
.. _ap-each:
|
||||
|
||||
ap-each
|
||||
-------
|
||||
=======
|
||||
|
||||
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)))
|
||||
=> (op 2)
|
||||
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]
|
||||
"Returns a function which is the composition of several 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"
|
||||
(assert-equal ((ap-compose (+ it 1) (* it 3)) 2) 9)
|
||||
(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