Add anaphoric versions of map, filter, and foreach

Anaphoric macros reduce the need to specify a lambda by binding a
special name in a form passed as a parameter to the macro. This allows
you to write more concise code:

    (= (list (--filter (even? it) [1 2 3 4])) [2 4])

This patch just adds a few basic ones. Other forms that can be
converted to anaphoric versions include reduce, remove, enumerate,
etc.
This commit is contained in:
agentultra 2013-11-28 13:23:09 -05:00
parent 63a9e35f7f
commit 2106a0e5d4
2 changed files with 39 additions and 0 deletions

View File

@ -3,6 +3,7 @@
;; Copyright (c) 2013 Nicolas Dandrimont <nicolas.dandrimont@crans.org>
;; Copyright (c) 2013 Paul Tagliamonte <paultag@debian.org>
;; Copyright (c) 2013 Konrad Hinsen <konrad.hinsen@fastmail.net>
;; Copyright (c) 2013 James King <james@agentultra.com>
;;
;; Permission is hereby granted, free of charge, to any person obtaining a
;; copy of this software and associated documentation files (the "Software"),
@ -116,3 +117,20 @@
;; TODO: this needs some gensym love
`(foreach [_hy_yield_from_x ~iterable]
(yield _hy_yield_from_x)))
(defmacro --each [lst &rest body]
`(foreach [it ~list] ~@body))
(defmacro --map [form lst]
`(let [[f (lambda [it] ~form)]]
(foreach [v ~lst]
(yield (f v)))))
(defmacro --filter [form lst]
`(let [[pred (lambda [it] ~form)]]
(foreach [val ~lst]
(if (pred val)
(yield val)))))

View File

@ -1,5 +1,6 @@
;; Copyright (c) 2013 Paul Tagliamonte <paultag@debian.org>
;; Copyright (c) 2013 Bob Tolbert <bob@tolbert.org>
;; Copyright (c) 2013 James King <james@agentultra.com>
;; Permission is hereby granted, free of charge, to any person obtaining a
;; copy of this software and associated documentation files (the "Software"),
@ -391,3 +392,23 @@
(assert-equal res [None None])
(setv res (list (take-while (fn [x] (not (none? x))) [1 2 3 4 None 5 6 None 7])))
(assert-equal res [1 2 3 4]))
(defn test-anaphoric-each []
"NATIVE: testing anaphoric each"
(setv res [])
(--each [1 2 3 4] (.append res it))
(assert-equal res [1 2 3 4]))
(defn test-anaphoric-map []
"NATIVE: testing anaphoric map"
(assert-equal (list (--map (* it 3) [1 2 3]))
[3 6 9])
(assert-equal (list (--map (* it 3) []))
[]))
(defn test-anaphoric-filter []
"NATIVE: testing anaphoric filter"
(assert-equal (list (--filter (> it 2) [1 2 3 4]))
[3 4])
(assert-equal (list (--filter (even? it) [1 2 3 4]))
[2 4]))