From c03e798356b65a1f026ee2b1cc4bff872e8b204d Mon Sep 17 00:00:00 2001 From: "Clinton N. Dreisbach" Date: Fri, 10 Jan 2014 16:09:56 -0500 Subject: [PATCH 01/13] Added docs for apply --- docs/language/api.rst | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/language/api.rst b/docs/language/api.rst index cd57464..30cfeb4 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -97,6 +97,31 @@ appends it as the last argument. The following code demonstrates this: 5 10 +apply +----- + +`apply` is used to apply a list of arguments and an optional dictionary of +kwargs to a function. + +Usage: `(apply fn-name args [kwargs])` + +Examples: + +.. code-block:: clj + + (defn total-purchase [price amount &optional [fees 1.05] [vat 1.1]] + (* price amount fees vat)) + + (apply total-purchase [10 15]) + ;=> 173.25 + + (apply total-purchase [10 15] {"vat" 1.05}) + ;=> 165.375 + + (apply total-purchase [] {"price" 10 "amount" 15 "vat" 1.05}) + ;=> 165.375 + + and --- From 977b47d3b4009bae0198494658d40a65af82bfae Mon Sep 17 00:00:00 2001 From: "Clinton N. Dreisbach" Date: Fri, 10 Jan 2014 16:14:20 -0500 Subject: [PATCH 02/13] Noted that args are optional with apply --- docs/language/api.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/language/api.rst b/docs/language/api.rst index 30cfeb4..6c01d0a 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -100,14 +100,19 @@ appends it as the last argument. The following code demonstrates this: apply ----- -`apply` is used to apply a list of arguments and an optional dictionary of -kwargs to a function. +`apply` is used to apply an optional list of arguments and an optional +dictionary of kwargs to a function. -Usage: `(apply fn-name args [kwargs])` +Usage: `(apply fn-name [args] [kwargs])` Examples: .. code-block:: clj + (defn thunk [] + "hy there") + + (apply thunk) + ;=> "hy there" (defn total-purchase [price amount &optional [fees 1.05] [vat 1.1]] (* price amount fees vat)) From c0a654e6cb58df75cd973cd04da50cee39daa36a Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Fri, 10 Jan 2014 21:02:14 -0500 Subject: [PATCH 03/13] Add callgraph stuff. Slick look. --- hy/contrib/profile.hy | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hy/contrib/profile.hy b/hy/contrib/profile.hy index 3992890..485f46b 100644 --- a/hy/contrib/profile.hy +++ b/hy/contrib/profile.hy @@ -23,7 +23,15 @@ ;;; These macros make debugging where bottlenecks exist easier. -(defmacro/g! profile [&rest body] +(defmacro profile/calls [&rest body] + `(do + (import [pycallgraph [PyCallGraph]] + [pycallgraph.output [GraphvizOutput]]) + (with* [(apply PyCallGraph [] {"output" (GraphvizOutput)})] + ~@body))) + + +(defmacro/g! profile/cpu [&rest body] " Profile a bit of code " `(do (import cProfile pstats) From 2167c211203fc1d43cb3a9d8c0d10598f7c55388 Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Fri, 10 Jan 2014 22:00:30 -0500 Subject: [PATCH 04/13] Adjust (for) to just use itertools.product This is to avoid nesting in for loops, helping make clear what (break) and (else) do. This commit is hereby dedicated to @nedbat --- hy/core/macros.hy | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/hy/core/macros.hy b/hy/core/macros.hy index cdc5d17..7c10e70 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -45,10 +45,18 @@ (if (empty? body) (macro-error None "`for' requires a body to evaluate")) - (if args - `(for* [~(.pop args 0) ~(.pop args 0)] - (for ~args ~@body)) - `(do ~@body))) + + (if (= (len args) 2) + ; basecase, let's just slip right in. + `(for* [~@args] ~@body) + ; otherwise, let's do some legit handling. + (let [[it (iter args)] + [az (list (zip it it))] + [alist (list-comp (get x 0) [x az])] + [ilist (list-comp (get x 1) [x az])]] + `(do + (import itertools) + (for* [(, ~@alist) (itertools.product ~@ilist)] ~@body))))) (defmacro with [args &rest body] From abd0669911393188de3c45247625dd9054edf2f4 Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Fri, 10 Jan 2014 22:16:35 -0500 Subject: [PATCH 05/13] add test for new for logic. --- tests/native_tests/language.hy | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index f116233..268c6f2 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -41,6 +41,41 @@ (assert (= count 150))) +(defn test-nasty-nesting [] + "NATIVE: test nesting for loops harder" + ;; This test and feature is dedicated to @nedbat. + + ;; OK. This first test will ensure that the else is hooked up to the + ;; for when we break out of it. + (for [x (range 2) + y (range 2)] + (break) + (else (throw Exception))) + + ;; OK. This next test will ensure that the else is hooked up to the + ;; "inner" iteration + (for [x (range 2) + y (range 2)] + (if (= y 1) (break)) + (else (throw Exception))) + + ;; OK. This next test will ensure that the else is hooked up to the + ;; "outter" iteration + (for [x (range 2) + y (range 2)] + (if (= x 1) (break)) + (else (throw Exception))) + + ;; OK. This next test will ensure that we call the else branch exactly + ;; once. + (setv flag 0) + (for [x (range 2) + y (range 2)] + (+ 1 1) + (else (setv flag (+ flag 2)))) + (assert (= flag 2))) + + (defn test-while-loop [] "NATIVE: test while loops?" (setv count 5) From 0f74b1ddf3d5268fcefde26aa4b8c12f9e90620b Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Fri, 10 Jan 2014 22:29:03 -0500 Subject: [PATCH 06/13] Add handling for (for []). Nice catch, @olasd. --- hy/core/macros.hy | 24 +++++++++++++----------- tests/native_tests/language.hy | 5 +++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/hy/core/macros.hy b/hy/core/macros.hy index 7c10e70..f6b30af 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -46,17 +46,19 @@ (if (empty? body) (macro-error None "`for' requires a body to evaluate")) - (if (= (len args) 2) - ; basecase, let's just slip right in. - `(for* [~@args] ~@body) - ; otherwise, let's do some legit handling. - (let [[it (iter args)] - [az (list (zip it it))] - [alist (list-comp (get x 0) [x az])] - [ilist (list-comp (get x 1) [x az])]] - `(do - (import itertools) - (for* [(, ~@alist) (itertools.product ~@ilist)] ~@body))))) + (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 [[it (iter args)] + [az (list (zip it it))] + [alist (list-comp (get x 0) [x az])] + [ilist (list-comp (get x 1) [x az])]] + `(do + (import itertools) + (for* [(, ~@alist) (itertools.product ~@ilist)] ~@body)))))) (defmacro with [args &rest body] diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index 268c6f2..f954909 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -45,6 +45,11 @@ "NATIVE: test nesting for loops harder" ;; This test and feature is dedicated to @nedbat. + ;; let's ensure empty iterating is an implicit do + (setv t 0) + (for [] (setv t 1)) + (assert (= t 1)) + ;; OK. This first test will ensure that the else is hooked up to the ;; for when we break out of it. (for [x (range 2) From 110476901ca6f0dc7710c0b9dfc240be31530d57 Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Fri, 10 Jan 2014 22:31:00 -0500 Subject: [PATCH 07/13] Fix a few typos in the tests. Thanks again, @olasd --- tests/native_tests/language.hy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index f954909..11bf01a 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -41,7 +41,7 @@ (assert (= count 150))) -(defn test-nasty-nesting [] +(defn test-nasty-for-nesting [] "NATIVE: test nesting for loops harder" ;; This test and feature is dedicated to @nedbat. @@ -65,7 +65,7 @@ (else (throw Exception))) ;; OK. This next test will ensure that the else is hooked up to the - ;; "outter" iteration + ;; "outer" iteration (for [x (range 2) y (range 2)] (if (= x 1) (break)) From cc2f45be69916247f7493c2f2ae64b940660c681 Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Fri, 10 Jan 2014 22:50:20 -0500 Subject: [PATCH 08/13] slice is amazing, @olasd is amazing, I love everything. --- hy/core/macros.hy | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hy/core/macros.hy b/hy/core/macros.hy index f6b30af..b5e5ee0 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -52,10 +52,8 @@ ; basecase, let's just slip right in. `(for* [~@args] ~@body) ; otherwise, let's do some legit handling. - (let [[it (iter args)] - [az (list (zip it it))] - [alist (list-comp (get x 0) [x az])] - [ilist (list-comp (get x 1) [x az])]] + (let [[alist (slice args 0 nil 2)] + [ilist (slice args 1 nil 2)]] `(do (import itertools) (for* [(, ~@alist) (itertools.product ~@ilist)] ~@body)))))) From 18c19043c7843e4898e17082fee089b063710990 Mon Sep 17 00:00:00 2001 From: "Clinton N. Dreisbach" Date: Sat, 11 Jan 2014 09:58:47 -0500 Subject: [PATCH 09/13] Add note about underscore/dash shadowing --- docs/language/api.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/language/api.rst b/docs/language/api.rst index 6c01d0a..c7c288e 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -28,7 +28,9 @@ languages. and `i♥u` will become `hy_iu_t0x`. * Symbols that contain dashes will have them replaced with underscores. For - example, `render-template` will become `render_template`. + example, `render-template` will become `render_template`. This means that + symbols with dashes will shadow their underscore equivalents, and vice + versa. Builtins From 3907c5bc5371651c25c54ccc271af4817d3d59dc Mon Sep 17 00:00:00 2001 From: "Clinton N. Dreisbach" Date: Sat, 11 Jan 2014 23:29:48 -0500 Subject: [PATCH 10/13] Added docs for unquote and unquote-splice --- docs/language/api.rst | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/language/api.rst b/docs/language/api.rst index c7c288e..7883e9f 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -1022,6 +1022,42 @@ given conditional is False. The following shows how the macro expands into code. None (do statement)) + +unquote +------- + +Within a quasiquoted form, `unquote` forces evaluation of a symbol. `unquote` +is aliased to the `~` symbol. + +.. code-block:: clj + + (def name "Cuddles") + (quasiquote (= name (unquote name))) + ;=> (u'=' u'name' u'Cuddles') + + `(= name ~name) + ;=> (u'=' u'name' u'Cuddles') + + +unquote-splice +-------------- + +`unquote-splice` forces the evaluation of a symbol within a quasiquoted form, +much like `unquote`. `unquote-splice` can only be used when the symbol being +unquoted contains an iterable value, as it "splices" that iterable into the +quasiquoted form. `unquote-splice` is aliased to the `~@` symbol. + +.. code-block:: clj + + (def nums [1 2 3 4]) + (quasiquote (+ (unquote-splice nums))) + ;=> (u'+' 1L 2L 3L 4L) + + `(+ ~@nums) + ;=> (u'+' 1L 2L 3L 4L) + + + when ---- From f159f1499b698ba88b536b572d6a20148f2269d1 Mon Sep 17 00:00:00 2001 From: Abhishek L Date: Sun, 12 Jan 2014 15:49:09 +0530 Subject: [PATCH 11/13] Adding a simple `coll?` function to the core * hy/core/language.hy: -Added a simple coll? function that checks whether the given argument is an iterable and not a string, - Also replaced the check in `flatten` by coll? * tests/native_tests/core.hy: Tests updated for checking coll? --- hy/core/language.hy | 10 +++++++--- tests/native_tests/core.hy | 8 ++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/hy/core/language.hy b/hy/core/language.hy index 8fcb615..0ccd3c6 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -30,6 +30,10 @@ (if (not (numeric? x)) (raise (TypeError (.format "{0!r} is not a number" x))))) +(defn coll? [coll] + "Checks whether item is a collection" + (and (iterable? coll) (not (string? coll)))) + (defn cycle [coll] "Yield an infinite repetition of the items in coll" (setv seen []) @@ -112,7 +116,7 @@ (defn flatten [coll] "Return a single flat list expanding all members of coll" - (if (and (iterable? coll) (not (string? coll))) + (if (coll? coll) (_flatten coll []) (raise (TypeError (.format "{0!r} is not a collection" coll))))) @@ -298,8 +302,8 @@ (_numeric_check n) (= n 0)) -(def *exports* '[calling-module-name cycle dec distinct disassemble drop - drop-while empty? even? filter flatten float? gensym +(def *exports* '[calling-module-name coll? cycle dec distinct disassemble + drop drop-while empty? even? filter flatten float? gensym inc instance? integer integer? iterable? iterate iterator? macroexpand macroexpand-1 neg? nil? none? nth numeric? odd? pos? remove repeat repeatedly second diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index 1427187..db2c9e5 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -30,6 +30,14 @@ (defn assert-equal [x y] (assert (= x y))) +(defn test-coll? [] + "NATIVE: testing coll?" + (assert-true (coll? [1 2 3])) + (assert-true (coll? {"a" 1 "b" 2})) + (assert-true (coll? (range 10))) + (assert-false (coll? "abc")) + (assert-false (coll? 1))) + (defn test-cycle [] "NATIVE: testing cycle" (assert-equal (list (cycle [])) []) From bd53416a727f06df702250ad303425578840b9ee Mon Sep 17 00:00:00 2001 From: Abhishek L Date: Sun, 12 Jan 2014 15:52:14 +0530 Subject: [PATCH 12/13] docs: update docs with coll? functionality --- docs/language/core.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/language/core.rst b/docs/language/core.rst index b2e4e3e..deaf16b 100644 --- a/docs/language/core.rst +++ b/docs/language/core.rst @@ -6,6 +6,29 @@ Hy Core Core Functions =============== +.. _is-coll-fn: + +coll? +---- + +.. versionadded:: 0.9.13 + +Usage: ``(coll? x)`` + +Returns true if argument is iterable and not a string. + +.. code-block:: clojure + + => (coll? [1 2 3 4]) + True + + => (coll? {"a" 1 "b" 2}) + True + + => (coll? "abc") + False + + .. _dec-fn: dec From 1e793e696a6ab731d47b8640b0778ee9b429fdb2 Mon Sep 17 00:00:00 2001 From: Nicolas Dandrimont Date: Sun, 12 Jan 2014 17:34:05 +0100 Subject: [PATCH 13/13] Fix indentation of *exports* --- hy/core/language.hy | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hy/core/language.hy b/hy/core/language.hy index 0ccd3c6..786d4de 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -302,9 +302,9 @@ (_numeric_check n) (= n 0)) -(def *exports* '[calling-module-name coll? cycle dec distinct disassemble - drop drop-while empty? even? filter flatten float? gensym - inc instance? integer integer? iterable? iterate - iterator? macroexpand macroexpand-1 neg? nil? none? - nth numeric? odd? pos? remove repeat repeatedly second - string string? take take-nth take-while zero?]) +(def *exports* '[calling-module-name coll? cycle dec distinct + disassemble drop drop-while empty? even? filter flatten + float? gensym inc instance? integer integer? iterable? + iterate iterator? macroexpand macroexpand-1 neg? nil? + none? nth numeric? odd? pos? remove repeat repeatedly + second string string? take take-nth take-while zero?])