From 2106a0e5d4beb6899d1fb49af655bc90a2c8850e Mon Sep 17 00:00:00 2001 From: agentultra Date: Thu, 28 Nov 2013 13:23:09 -0500 Subject: [PATCH] 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. --- hy/core/macros.hy | 18 ++++++++++++++++++ tests/native_tests/core.hy | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/hy/core/macros.hy b/hy/core/macros.hy index 17792f9..91c477d 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -3,6 +3,7 @@ ;; Copyright (c) 2013 Nicolas Dandrimont ;; Copyright (c) 2013 Paul Tagliamonte ;; Copyright (c) 2013 Konrad Hinsen +;; Copyright (c) 2013 James King ;; ;; 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))))) diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index 6e81f39..cde0cb6 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -1,5 +1,6 @@ ;; Copyright (c) 2013 Paul Tagliamonte ;; Copyright (c) 2013 Bob Tolbert +;; Copyright (c) 2013 James King ;; 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]))