From 8e173937c358e3f53415b3df8ff163a3f524f6a5 Mon Sep 17 00:00:00 2001 From: James King Date: Fri, 16 May 2014 12:58:57 -0400 Subject: [PATCH] Add shadow.hy to core This new core module allows us to shadow the builtin Python operators so they may be passed to sequence functions that expect functions: => (map / [1 2 3 4 5]) [1.0, 0.5, 0.3333333333333333, 0.25] --- hy/core/__init__.py | 3 +- hy/core/language.hy | 19 ++++++----- hy/core/shadow.hy | 61 ++++++++++++++++++++++++++++++++++++ tests/native_tests/shadow.hy | 41 ++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 hy/core/shadow.hy create mode 100644 tests/native_tests/shadow.hy diff --git a/hy/core/__init__.py b/hy/core/__init__.py index d5349f3..be885ce 100644 --- a/hy/core/__init__.py +++ b/hy/core/__init__.py @@ -1,3 +1,4 @@ STDLIB = [ - "hy.core.language" + "hy.core.language", + "hy.core.shadow" ] diff --git a/hy/core/language.hy b/hy/core/language.hy index 262a45a..fe921b7 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -92,7 +92,8 @@ (setv map itertools.imap) (setv zip itertools.izip) (setv range xrange) - (setv input raw_input)) + (setv input raw_input) + (setv reduce reduce)) (do (setv reduce functools.reduce) (setv filterfalse itertools.filterfalse) @@ -331,10 +332,12 @@ (_numeric_check n) (= n 0)) -(def *exports* '[butlast calling-module-name coll? cons cons? cycle dec distinct - disassemble drop drop-while empty? even? every? first filter - flatten float? gensym identity inc instance? integer - integer? integer-char? iterable? iterate iterator? keyword? - list* macroexpand macroexpand-1 map neg? nil? none? nth - numeric? odd? pos? range remove repeat repeatedly rest second - some string string? take take-nth take-while zero? zip zipwith]) +(def *exports* '[butlast calling-module-name coll? cons cons? cycle + dec distinct disassemble drop drop-while empty? even? + every? first filter flatten float? gensym identity + inc instance? integer integer? integer-char? + iterable? iterate iterator? keyword? list* + macroexpand macroexpand-1 map neg? nil? none? nth + numeric? odd? pos? range remove repeat repeatedly + rest reduce second some string string? take take-nth + take-while zero? zip zipwith]) diff --git a/hy/core/shadow.hy b/hy/core/shadow.hy new file mode 100644 index 0000000..f59f0ca --- /dev/null +++ b/hy/core/shadow.hy @@ -0,0 +1,61 @@ +;; Copyright (c) 2014 Paul Tagliamonte +;; Copyright (c) 2014 James King + +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: + +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. + +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +;; DEALINGS IN THE SOFTWARE. + +;;;; Hy shadow functions + +(import operator) + + +(defn + [&rest args] + "Shadow + operator for when we need to import / map it against something" + (if (= (len args) 0) + 0 + (sum args))) ; shortcut here. + + +(defn - [&rest args] + "Shadow - operator for when we need to import / map it against something" + (let [[count (len args)]] + (if (= count 0) + (raise (TypeError "Need at least 1 argument to subtract")) + (if (= count 1) + (- (get args 0)) + (reduce operator.sub args))))) + + +(defn * [&rest args] + "Shadow * operator for when we need to import / map it against something" + (if (= (len args) 0) + 1 ; identity + (reduce operator.mul args))) + + +(defn / [&rest args] + "Shadow / operator for when we need to import / map it against something" + (let [[count (len args)]] + (if (= count 0) + (raise (TypeError "Need at least 1 argument to divide")) + (if (= count 1) + (operator.truediv 1 (get args 0)) + (reduce operator.truediv args))))) + + +(setv *exports* ['+ '- '* '/]) diff --git a/tests/native_tests/shadow.hy b/tests/native_tests/shadow.hy new file mode 100644 index 0000000..362ac50 --- /dev/null +++ b/tests/native_tests/shadow.hy @@ -0,0 +1,41 @@ + + +(defn test-shadow-addition [] + "NATIVE: test shadow addition" + (let [[x +]] + (assert (= (x) 0)) + (assert (= (x 1 2 3 4) 10)) + (assert (= (x 1 2 3 4 5) 15)))) + + +(defn test-shadow-subtraction [] + "NATIVE: test shadow subtraction" + (let [[x -]] + (assert (try + (x) + (catch [TypeError] True) + (else (throw AssertionError)))) + (assert (= (x 1) -1)) + (assert (= (x 2 1) 1)) + (assert (= (x 2 1 1) 0)))) + + +(defn test-shadow-multiplication [] + "NATIVE: test shadow multiplication" + (let [[x *]] + (assert (= (x) 1)) + (assert (= (x 3) 3)) + (assert (= (x 3 3) 9)))) + + +(defn test-shadow-division [] + "NATIVE: test shadow division" + (let [[x /]] + (assert (try + (x) + (catch [TypeError] True) + (else (throw AssertionError)))) + (assert (= (x 1) 1)) + (assert (= (x 8 2) 4)) + (assert (= (x 8 2 2) 2)) + (assert (= (x 8 2 2 2) 1))))