From e65132c751adad3155ceef3cfcb4b5ef13c32ce7 Mon Sep 17 00:00:00 2001 From: Christian Weilbach Date: Sat, 30 Nov 2013 03:00:45 +0100 Subject: [PATCH 01/16] Set sys.argv default to [''] like Python does. --- hy/cmdline.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hy/cmdline.py b/hy/cmdline.py index 031eb33..899224c 100644 --- a/hy/cmdline.py +++ b/hy/cmdline.py @@ -228,7 +228,10 @@ def cmdline_handler(scriptname, argv): options = parser.parse_args(argv[1:]) # reset sys.argv like Python - sys.argv = options.args + if options.args and len(options.args) > 0: + sys.argv = options.args + else: # Python default + sys.argv = [''] if options.command: # User did "hy -c ..." From 46d77f69e65e3230cc6b76b7b5f006f100bb4214 Mon Sep 17 00:00:00 2001 From: Christian Weilbach Date: Mon, 24 Feb 2014 23:08:40 +0100 Subject: [PATCH 02/16] Fix disassembly, add butlast, profile --- hy/core/language.hy | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/hy/core/language.hy b/hy/core/language.hy index 19e8486..30f5b76 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -32,6 +32,10 @@ (if (not (numeric? x)) (raise (TypeError (.format "{0!r} is not a number" x))))) +(defn butlast [coll] + "Returns coll except of last element." + (slice coll 0 (dec (len coll)))) + (defn coll? [coll] "Checks whether item is a collection" (and (iterable? coll) (not (string? coll)))) @@ -60,17 +64,24 @@ (- n 1)) (defn disassemble [tree &optional [codegen false]] - "Dump the python AST for a given Hy tree to standard output + "Return the python AST for a quoted Hy tree as a string. If the second argument is true, generate python code instead." (import astor) (import hy.compiler) (fake-source-positions tree) (setv compiled (hy.compiler.hy_compile tree (calling-module-name))) - (print ((if codegen + ((if codegen astor.codegen.to_source astor.dump) - compiled))) + compiled)) + +(defn profile [tree] + "Profile a quoted Hy tree." + (import cProfile) + (import re) + + (.run cProfile (disassemble tree true))) (defn distinct [coll] "Return a generator from the original collection with duplicates @@ -351,10 +362,11 @@ (import functools) (map (functools.partial (fn [f args] (apply f args)) func) (apply zip lists)))) -(def *exports* '[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? - list* macroexpand macroexpand-1 neg? nil? none? nth - numeric? odd? pos? remove repeat repeatedly rest second - some string string? take take-nth take-while zero? zipwith]) +(def *exports* '[butlast calling-module-name coll? cons cons? cycle dec + distinct disassemble profile drop drop-while empty? + even? every? first filter flatten float? gensym + identity inc instance? integer integer? integer-char? + iterable? iterate iterator? list* macroexpand + macroexpand-1 neg? nil? none? nth numeric? odd? pos? + remove repeat repeatedly rest second some string + string? take take-nth take-while zero? zipwith]) From 2e4b77267ecec32c2dec4da6e5b1c1dd79ac8a6c Mon Sep 17 00:00:00 2001 From: Christian Weilbach Date: Wed, 26 Feb 2014 00:03:42 +0100 Subject: [PATCH 03/16] Remove profile fn. https://github.com/hylang/hy/pull/522#issuecomment-35972534 --- hy/core/language.hy | 7 ------- 1 file changed, 7 deletions(-) diff --git a/hy/core/language.hy b/hy/core/language.hy index 30f5b76..6629e57 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -76,13 +76,6 @@ astor.dump) compiled)) -(defn profile [tree] - "Profile a quoted Hy tree." - (import cProfile) - (import re) - - (.run cProfile (disassemble tree true))) - (defn distinct [coll] "Return a generator from the original collection with duplicates removed" From 1a6b484ccb25039c13444d4c1798da75c3781c91 Mon Sep 17 00:00:00 2001 From: Christian Weilbach Date: Sun, 2 Mar 2014 12:24:05 +0100 Subject: [PATCH 04/16] Remove profile export. --- hy/core/language.hy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hy/core/language.hy b/hy/core/language.hy index 6629e57..8377822 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -356,7 +356,7 @@ (map (functools.partial (fn [f args] (apply f args)) func) (apply zip lists)))) (def *exports* '[butlast calling-module-name coll? cons cons? cycle dec - distinct disassemble profile drop drop-while empty? + distinct disassemble drop drop-while empty? even? every? first filter flatten float? gensym identity inc instance? integer integer? integer-char? iterable? iterate iterator? list* macroexpand From 0195de6545eba857927980f423adb7a2f37a5f7a Mon Sep 17 00:00:00 2001 From: maresp Date: Fri, 18 Apr 2014 02:45:05 +0200 Subject: [PATCH 05/16] fixed ap-map potential naming conflict --- hy/contrib/anaphoric.hy | 7 ++++--- tests/native_tests/contrib/anaphoric.hy | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/hy/contrib/anaphoric.hy b/hy/contrib/anaphoric.hy index 2f37b47..5a6b236 100644 --- a/hy/contrib/anaphoric.hy +++ b/hy/contrib/anaphoric.hy @@ -46,9 +46,10 @@ (defmacro ap-map [form lst] "Yield elements evaluated in the form for each element in the list." - `(let [[f (lambda [it] ~form)]] - (for [v ~lst] - (yield (f v))))) + (let [[v (gensym 'v)] [f (gensym 'f)]] + `(let [[~f (lambda [it] ~form)]] + (for [~v ~lst] + (yield (~f ~v)))))) (defmacro ap-map-when [predfn rep lst] diff --git a/tests/native_tests/contrib/anaphoric.hy b/tests/native_tests/contrib/anaphoric.hy index 791b24c..3d67e82 100644 --- a/tests/native_tests/contrib/anaphoric.hy +++ b/tests/native_tests/contrib/anaphoric.hy @@ -54,7 +54,9 @@ (assert-equal (list (ap-map (* it 3) [1 2 3])) [3 6 9]) (assert-equal (list (ap-map (* it 3) [])) - [])) + []) + (assert-equal (let [[v 1] [f 1]] (list (ap-map (it v f) [(fn [a b] (+ a b))]))) + [2])) (defn test-ap-map-when [] "NATIVE: testing anaphoric map-when" From 21cff9d14ff3597a2f5275d31ca72dc155290524 Mon Sep 17 00:00:00 2001 From: Tuukka Turto Date: Mon, 21 Apr 2014 08:04:03 +0300 Subject: [PATCH 06/16] initial implementation for doto macro relates #567 --- hy/core/macros.hy | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hy/core/macros.hy b/hy/core/macros.hy index f20d0a7..548a81b 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -127,6 +127,16 @@ ret) +(defmacro doto [form &rest expressions] + (setv expressions (iter expressions)) + (defn build-form [form expression] + `(~(first expression) ~form ~@(rest expression))) + (setv result `()) + (for* [expression expressions] + (.append result (build-form form expression))) + `(do ~@result)) + + (defmacro ->> [head &rest rest] ;; TODO: fix the docstring by someone who understands this (setv ret head) From 8a5a1eea27311d6ed8623cf59d0986712f4a8a1a Mon Sep 17 00:00:00 2001 From: Tuukka Turto Date: Mon, 21 Apr 2014 13:21:11 +0300 Subject: [PATCH 07/16] test for doto macro relates #567 --- tests/native_tests/core.hy | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index 15debf4..fec1316 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -478,3 +478,10 @@ (assert-equal (list res) [4 4 4]) (setv res (zipwith operator.sub [3 7 9] [1 2 4])) (assert-equal (list res) [2 5 5])) + +(defn test-doto [] + "NATIVE: testing doto macro" + (setv collection []) + (doto collection (.append 1) (.append 2) (.append 3)) + (assert-equal collection [1 2 3])) + From f4b67e8bd815c132fa4a602e80f9f21c57216878 Mon Sep 17 00:00:00 2001 From: Tuukka Turto Date: Mon, 21 Apr 2014 13:28:08 +0300 Subject: [PATCH 08/16] documentation for doto relates #567 --- docs/language/api.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/language/api.rst b/docs/language/api.rst index fe3575e..f5b1ac5 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -560,6 +560,27 @@ del => dic {} +doto +---- + +`doto` macro is used to make repetitive calls to an object easy. Following +example demonstrates this. + +.. code-block:: clj + + => (setv collection []) + => (doto collection (.append 1) (.append 2)) + => collection + [1 2] + +.. code-block:: clj + + => (setv collection []) + => (.append 1 collection) + => (.append 2 collection) + => collection + [1 2] + eval ---- From 834b0019a715f6351d53963f743361651cd60912 Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Mon, 21 Apr 2014 12:35:56 -0700 Subject: [PATCH 09/16] Fixing `doto` to be API compatible with Clojure's `doto` --- docs/language/api.rst | 22 ++++++++++------------ hy/core/macros.hy | 17 +++++++++-------- tests/native_tests/core.hy | 6 +++++- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/docs/language/api.rst b/docs/language/api.rst index f5b1ac5..53b89a5 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -563,23 +563,21 @@ del doto ---- -`doto` macro is used to make repetitive calls to an object easy. Following -example demonstrates this. +`doto` macro is used to make a sequence of method calls for an object easy. + +.. code-block:: clj + + => (doto [] (.append 1) (.append 2) .reverse) + [2 1] .. code-block:: clj => (setv collection []) - => (doto collection (.append 1) (.append 2)) + => (.append collection 1) + => (.append collection 2) + => (.reverse collection) => collection - [1 2] - -.. code-block:: clj - - => (setv collection []) - => (.append 1 collection) - => (.append 2 collection) - => collection - [1 2] + [2 1] eval ---- diff --git a/hy/core/macros.hy b/hy/core/macros.hy index 548a81b..29db215 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -128,14 +128,15 @@ (defmacro doto [form &rest expressions] - (setv expressions (iter expressions)) - (defn build-form [form expression] - `(~(first expression) ~form ~@(rest expression))) - (setv result `()) - (for* [expression expressions] - (.append result (build-form form expression))) - `(do ~@result)) - + "Performs a sequence of potentially mutating actions on an initial object, returning the resulting object after the sequence is performed" + (setv f (gensym)) + (defn build-form [expression] + (if (isinstance expression HyExpression) + `(~(first expression) ~f ~@(rest expression)) + `(~expression ~f))) + `(let [[~f ~form]] + ~@(map build-form expressions) + ~f)) (defmacro ->> [head &rest rest] ;; TODO: fix the docstring by someone who understands this diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index fec1316..c1ef191 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -483,5 +483,9 @@ "NATIVE: testing doto macro" (setv collection []) (doto collection (.append 1) (.append 2) (.append 3)) - (assert-equal collection [1 2 3])) + (assert-equal collection [1 2 3]) + (setv res (doto (set) (.add 2) (.add 1))) + (assert-equal res (set [1 2])) + (setv res (doto [] (.append 1) (.append 2) .reverse)) + (assert-equal res [2 1])) From 43f63e9ae7a6c479258e978fdb585a4fa8c6a5d2 Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Mon, 21 Apr 2014 13:17:40 -0700 Subject: [PATCH 10/16] Shortening docstring --- hy/core/macros.hy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hy/core/macros.hy b/hy/core/macros.hy index 29db215..cc9d2b9 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -128,7 +128,8 @@ (defmacro doto [form &rest expressions] - "Performs a sequence of potentially mutating actions on an initial object, returning the resulting object after the sequence is performed" + "Performs a sequence of potentially mutating actions + on an initial object, returning the resulting object" (setv f (gensym)) (defn build-form [expression] (if (isinstance expression HyExpression) From 5c9a8f8975ea43d2b62c272aedd6c2f12d7f4eca Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Tue, 22 Apr 2014 08:56:44 -0700 Subject: [PATCH 11/16] Closes #573, restores 0.9.12 for loop behavior (and everyone wins!) --- hy/core/macros.hy | 7 ++----- tests/native_tests/language.hy | 8 ++++++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/hy/core/macros.hy b/hy/core/macros.hy index f20d0a7..6ae1cd7 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -52,11 +52,8 @@ ; basecase, let's just slip right in. `(for* [~@args] ~@body) ; otherwise, let's do some legit handling. - (let [[alist (slice args 0 nil 2)] - [ilist (slice args 1 nil 2)]] - `(do - (import itertools) - (for* [(, ~@alist) (itertools.product ~@ilist)] ~@body)))))) + (let [[alist (slice args 0 nil 2)]] + `(for* [(, ~@alist) (genexpr (, ~@alist) [~@args])] ~@body))))) (defmacro with [args &rest body] diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index ccf81c5..c394891 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -29,7 +29,7 @@ (defn test-for-loop [] - "NATIVE: test for loops?" + "NATIVE: test for loops" (setv count 0) (for [x [1 2 3 4 5]] (setv count (+ count x))) @@ -38,7 +38,11 @@ (for [x [1 2 3 4 5] y [1 2 3 4 5]] (setv count (+ count x y))) - (assert (= count 150))) + (assert (= count 150)) + (assert (= (list ((fn [] (for [x [[1] [2 3]] y x] (yield y))))) + (list-comp y [x [[1] [2 3]] y x]))) + (assert (= (list ((fn [] (for [x [[1] [2 3]] y x z (range 5)] (yield z))))) + (list-comp z [x [[1] [2 3]] y x z (range 5)])))) (defn test-nasty-for-nesting [] From 41a8b6e09b176ebe151aa9b2f846ec2ea77a48fb Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Tue, 22 Apr 2014 09:17:16 -0700 Subject: [PATCH 12/16] Adding myself as an author --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index e5b61cf..8bcae09 100644 --- a/AUTHORS +++ b/AUTHORS @@ -45,3 +45,4 @@ * kirbyfan64 * Brendan Curran-Johnson * Ivan Kozik +* Matthew Wampler-Doty From 92a1f17b36685154fd684e15b47e27ba65c8979d Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Tue, 22 Apr 2014 09:18:01 -0700 Subject: [PATCH 13/16] Adding myself as an author --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index e5b61cf..8bcae09 100644 --- a/AUTHORS +++ b/AUTHORS @@ -45,3 +45,4 @@ * kirbyfan64 * Brendan Curran-Johnson * Ivan Kozik +* Matthew Wampler-Doty From f2f38a1cf82bc0374d28acdd4334ba9c1569baa9 Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Tue, 22 Apr 2014 16:47:42 -0700 Subject: [PATCH 14/16] Refactor for loop to use cond --- hy/core/macros.hy | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/hy/core/macros.hy b/hy/core/macros.hy index 6ae1cd7..537cfa4 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -31,31 +31,6 @@ [hy._compat [PY33 PY34]]) -(defmacro for [args &rest body] - "shorthand for nested for loops: - (for [x foo - y bar] - baz) -> - (for* [x foo] - (for* [y bar] - baz))" - - (if (odd? (len args)) - (macro-error args "`for' requires an even number of args.")) - - (if (empty? body) - (macro-error None "`for' requires a body to evaluate")) - - (if (empty? args) - `(do ~@body) - (if (= (len args) 2) - ; basecase, let's just slip right in. - `(for* [~@args] ~@body) - ; otherwise, let's do some legit handling. - (let [[alist (slice args 0 nil 2)]] - `(for* [(, ~@alist) (genexpr (, ~@alist) [~@args])] ~@body))))) - - (defmacro with [args &rest body] "shorthand for nested for* loops: (with [[x foo] [y bar]] baz) -> @@ -113,6 +88,26 @@ root) +(defmacro for [args &rest body] + "shorthand for nested for loops: + (for [x foo + y bar] + baz) -> + (for* [x foo] + (for* [y bar] + baz))" + (cond + [(odd? (len args)) + (macro-error args "`for' requires an even number of args.")] + [(empty? body) + (macro-error None "`for' requires a body to evaluate")] + [(empty? args) `(do ~@body)] + [(= (len args) 2) `(for* [~@args] ~@body)] + [true + (let [[alist (slice args 0 nil 2)]] + `(for* [(, ~@alist) (genexpr (, ~@alist) [~@args])] ~@body))])) + + (defmacro -> [head &rest rest] ;; TODO: fix the docstring by someone who understands this (setv ret head) From fa5f51e0f12e99b725cf5d7856506b259517c63e Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Fri, 25 Apr 2014 08:19:22 -0500 Subject: [PATCH 15/16] Adding Version Added 0.10.1 --- docs/language/api.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/language/api.rst b/docs/language/api.rst index 53b89a5..a7efde9 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -563,6 +563,8 @@ del doto ---- +.. versionadded:: 0.10.1 + `doto` macro is used to make a sequence of method calls for an object easy. .. code-block:: clj From 7b5cb390abf271b5f40f18eee2c43da56c11c9c3 Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Tue, 29 Apr 2014 09:22:55 -0500 Subject: [PATCH 16/16] `setv` no longer creates variables with '.' in their names FIXES #577 --- AUTHORS | 1 + hy/compiler.py | 21 +++++++++++---------- tests/native_tests/core.hy | 28 ++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/AUTHORS b/AUTHORS index 847740c..c83f5ff 100644 --- a/AUTHORS +++ b/AUTHORS @@ -46,3 +46,4 @@ * Brendan Curran-Johnson * Ivan Kozik * Allison Kaptur +* Matthew Wampler-Doty diff --git a/hy/compiler.py b/hy/compiler.py index 032a49a..353fb0d 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -1751,18 +1751,19 @@ class HyASTCompiler(object): def _compile_assign(self, name, result, start_line, start_column): result = self.compile(result) - - if result.temp_variables and isinstance(name, HyString): - result.rename(name) - return result - ld_name = self.compile(name) - st_name = self._storeize(ld_name) - result += ast.Assign( - lineno=start_line, - col_offset=start_column, - targets=[st_name], value=result.force_expr) + if result.temp_variables \ + and isinstance(name, HyString) \ + and '.' not in name: + result.rename(name) + else: + st_name = self._storeize(ld_name) + result += ast.Assign( + lineno=start_line, + col_offset=start_column, + targets=[st_name], + value=result.force_expr) result += ld_name return result diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index 98e403d..c5c58d5 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -57,6 +57,34 @@ (try (do (dec None) (assert False)) (catch [e [TypeError]] (assert (in "not a number" (str e)))))) +(defn test-setv [] + "NATIVE: testing setv mutation" + (setv x 1) + (setv y 1) + (assert-equal x y) + (setv x (setv y 12)) + (assert-equal x 12) + (assert-equal y 12) + (setv x (setv y (fn [x] 9))) + (assert-equal (x y) 9) + (assert-equal (y x) 9) + (try (do (setv a.b 1) (assert False)) + (catch [e [NameError]] (assert (in "name 'a' is not defined" (str e))))) + (try (do (setv b.a (fn [x] x)) (assert False)) + (catch [e [NameError]] (assert (in "name 'b' is not defined" (str e))))) + (import itertools) + (setv foopermutations (fn [x] (itertools.permutations x))) + (setv p (set [(, 1 3 2) (, 3 2 1) (, 2 1 3) (, 3 1 2) (, 1 2 3) (, 2 3 1)])) + (assert-equal (set (itertools.permutations [1 2 3])) p) + (assert-equal (set (foopermutations [3 1 2])) p) + (setv permutations- itertools.permutations) + (setv itertools.permutations (fn [x] 9)) + (assert-equal (itertools.permutations p) 9) + (assert-equal (foopermutations foopermutations) 9) + (setv itertools.permutations permutations-) + (assert-equal (set (itertools.permutations [2 1 3])) p) + (assert-equal (set (foopermutations [2 3 1])) p)) + (defn test-distinct [] "NATIVE: testing the distinct function" (setv res (list (distinct [ 1 2 3 4 3 5 2 ])))