Drop a set of brackets from let.

This changes let to use a flat list of symbol-value pairs instead of a
vector of vectors. One side effect is that (let [[a 1] z]) is not
expressible now, and one will explicitly need to set a nil value for z,
such as: (let [a 1 z nil]).

Closes #713.

Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
This commit is contained in:
Gergely Nagy 2015-08-17 09:07:32 +02:00
parent 9569537f8c
commit 9f88e07e1d
27 changed files with 254 additions and 256 deletions

View File

@ -213,17 +213,17 @@ Examples of usage:
.. code-block:: clj .. code-block:: clj
=>(let [[collection {}]] =>(let [collection {}]
... (assoc collection "Dog" "Bark") ... (assoc collection "Dog" "Bark")
... (print collection)) ... (print collection))
{u'Dog': u'Bark'} {u'Dog': u'Bark'}
=>(let [[collection {}]] =>(let [collection {}]
... (assoc collection "Dog" "Bark" "Cat" "Meow") ... (assoc collection "Dog" "Bark" "Cat" "Meow")
... (print collection)) ... (print collection))
{u'Cat': u'Meow', u'Dog': u'Bark'} {u'Cat': u'Meow', u'Dog': u'Bark'}
=>(let [[collection [1 2 3 4]]] =>(let [collection [1 2 3 4]]
... (assoc collection 2 None) ... (assoc collection 2 None)
... (print collection)) ... (print collection))
[1, 2, None, 4] [1, 2, None, 4]
@ -463,8 +463,8 @@ Parameters may have the following keywords in front of them:
.. code-block:: clj .. code-block:: clj
=> (defn zig-zag-sum [&rest numbers] => (defn zig-zag-sum [&rest numbers]
(let [[odd-numbers (list-comp x [x numbers] (odd? x))] (let [odd-numbers (list-comp x [x numbers] (odd? x))
[even-numbers (list-comp x [x numbers] (even? x))]] even-numbers (list-comp x [x numbers] (even? x))]
(- (sum odd-numbers) (sum even-numbers)))) (- (sum odd-numbers) (sum even-numbers))))
=> (zig-zag-sum) => (zig-zag-sum)
@ -486,7 +486,7 @@ Parameters may have the following keywords in front of them:
.. code-block:: clj .. code-block:: clj
=> (defn compare [a b &kwonly keyfn [reverse false]] => (defn compare [a b &kwonly keyfn [reverse false]]
... (let [[result (keyfn a b)]] ... (let [result (keyfn a b)]
... (if (not reverse) ... (if (not reverse)
... result ... result
... (- result)))) ... (- result))))
@ -786,8 +786,8 @@ list. Example usage:
.. code-block:: clj .. code-block:: clj
=> (let [[animals {"dog" "bark" "cat" "meow"}] => (let [animals {"dog" "bark" "cat" "meow"}
... [numbers ["zero" "one" "two" "three"]]] ... numbers ["zero" "one" "two" "three"]]
... (print (get animals "dog")) ... (print (get animals "dog"))
... (print (get numbers 2))) ... (print (get numbers 2)))
bark bark
@ -988,30 +988,24 @@ example showcases this behaviour:
.. code-block:: clj .. code-block:: clj
=> (let [[x 5]] (print x) => (let [x 5] (print x)
... (let [[x 6]] (print x)) ... (let [x 6] (print x))
... (print x)) ... (print x))
5 5
6 6
5 5
The ``let`` macro takes two parameters: a vector defining *variables* and the The ``let`` macro takes two parameters: a vector defining *variables*
*body* which gets executed. *variables* is a vector where each element is either and the *body* which gets executed. *variables* is a vector of
a single variable or a vector defining a variable value pair. In the case of a variable and value pairs.
single variable, it is assigned value ``None``; otherwise, the supplied value is
used.
.. code-block:: clj
=> (let [x [y 5]] (print x y))
None 5
Note that the variable assignments are executed one by one, from left to right. Note that the variable assignments are executed one by one, from left to right.
The following example takes advantage of this: The following example takes advantage of this:
.. code-block:: clj .. code-block:: clj
=> (let [[x 5] [y (+ x 1)]] (print x y)) => (let [x 5
y (+ x 1)] (print x y))
5 6 5 6
@ -1050,15 +1044,15 @@ to modify variables through nested ``let`` or ``fn`` scopes:
.. code-block:: clj .. code-block:: clj
(let [[x 0]] (let [x 0]
(for [y (range 10)] (for [y (range 10)]
(let [[z (inc y)]] (let [z (inc y)]
(nonlocal x) ; allow the setv to "jump scope" to resolve x (nonlocal x) ; allow the setv to "jump scope" to resolve x
(setv x (+ x y)))) (setv x (+ x y))))
x) x)
(defn some-function [] (defn some-function []
(let [[x 0]] (let [x 0]
(register-some-callback (register-some-callback
(fn [stuff] (fn [stuff]
(nonlocal x) (nonlocal x)
@ -1467,9 +1461,9 @@ expands to:
.. code-block:: hy .. code-block:: hy
(let [[a (gensym) (let [a (gensym)
[b (gensym) b (gensym)
[c (gensym)]] c (gensym)]
...) ...)
.. seealso:: .. seealso::

View File

@ -1103,7 +1103,7 @@ if *from-file* ends before a complete expression can be parsed.
=> (with [[f (open "example.hy")]] => (with [[f (open "example.hy")]]
... (try ... (try
... (while true ... (while true
... (let [[exp (read f)]] ... (let [exp (read f)]
... (do ... (do
... (print "OHY" exp) ... (print "OHY" exp)
... (eval exp)))) ... (eval exp))))

View File

@ -381,7 +381,7 @@ A first pass might be something like:
.. code-block:: hy .. code-block:: hy
(defmacro nif [expr pos-form zero-form neg-form] (defmacro nif [expr pos-form zero-form neg-form]
`(let [[obscure-name ~expr]] `(let [obscure-name ~expr]
(cond [(pos? obscure-name) ~pos-form] (cond [(pos? obscure-name) ~pos-form]
[(zero? obscure-name) ~zero-form] [(zero? obscure-name) ~zero-form]
[(neg? obscure-name) ~neg-form]))) [(neg? obscure-name) ~neg-form])))
@ -396,8 +396,8 @@ such an occasion. A much better version of ``nif`` would be:
.. code-block:: hy .. code-block:: hy
(defmacro nif [expr pos-form zero-form neg-form] (defmacro nif [expr pos-form zero-form neg-form]
(let [[g (gensym)]] (let [g (gensym)]
`(let [[~g ~expr]] `(let [~g ~expr]
(cond [(pos? ~g) ~pos-form] (cond [(pos? ~g) ~pos-form]
[(zero? ~g) ~zero-form] [(zero? ~g) ~zero-form]
[(neg? ~g) ~neg-form])))) [(neg? ~g) ~neg-form]))))
@ -415,9 +415,9 @@ expands to:
.. code-block:: hy .. code-block:: hy
(let [[a (gensym) (let [a (gensym)
[b (gensym) b (gensym)
[c (gensym)]] c (gensym)]
...) ...)
so our re-written ``nif`` would look like: so our re-written ``nif`` would look like:
@ -426,7 +426,7 @@ so our re-written ``nif`` would look like:
(defmacro nif [expr pos-form zero-form neg-form] (defmacro nif [expr pos-form zero-form neg-form]
(with-gensyms [g] (with-gensyms [g]
`(let [[~g ~expr]] `(let [~g ~expr]
(cond [(pos? ~g) ~pos-form] (cond [(pos? ~g) ~pos-form]
[(zero? ~g) ~zero-form] [(zero? ~g) ~zero-form]
[(neg? ~g) ~neg-form])))) [(neg? ~g) ~neg-form]))))
@ -440,7 +440,7 @@ Our final version of ``nif``, built with ``defmacro/g!`` becomes:
.. code-block:: hy .. code-block:: hy
(defmacro/g! nif [expr pos-form zero-form neg-form] (defmacro/g! nif [expr pos-form zero-form neg-form]
`(let [[~g!res ~expr]] `(let [~g!res ~expr]
(cond [(pos? ~g!res) ~pos-form] (cond [(pos? ~g!res) ~pos-form]
[(zero? ~g!res) ~zero-form] [(zero? ~g!res) ~zero-form]
[(neg? ~g!res) ~neg-form])))) [(neg? ~g!res) ~neg-form]))))

View File

@ -105,8 +105,8 @@ Layout & Indentation
.. code-block:: clj .. code-block:: clj
(let [[foo (bar)] (let [foo (bar)]
[qux (baz)]] qux (baz)]
(foo qux)) (foo qux))

View File

@ -27,7 +27,7 @@
(reactor.stop)) (reactor.stop))
(defn get-page [url] (defn get-page [url]
(let [[d (getPage url)]] (let [d (getPage url)]
(d.addCallback get-page-size) (d.addCallback get-page-size)
(d.addErrback log-error) (d.addErrback log-error)
(d.addCallback finish))) (d.addCallback finish)))

View File

@ -30,8 +30,8 @@
(defmacro defn-alias [names lambda-list &rest body] (defmacro defn-alias [names lambda-list &rest body]
"define one function with several names" "define one function with several names"
(let [[main (first names)] (let [main (first names)
[aliases (rest names)]] aliases (rest names)]
(setv ret `(do (defn ~main ~lambda-list ~@body))) (setv ret `(do (defn ~main ~lambda-list ~@body)))
(for* [name aliases] (for* [name aliases]
(.append ret (.append ret

View File

@ -26,7 +26,7 @@
(defmacro ap-if (test-form &rest args) (defmacro ap-if (test-form &rest args)
`(let [[it ~test-form]] (if it ~@args))) `(let [it ~test-form] (if it ~@args)))
(defmacro ap-each [lst &rest body] (defmacro ap-each [lst &rest body]
@ -37,7 +37,7 @@
(defmacro ap-each-while [lst form &rest body] (defmacro ap-each-while [lst form &rest body]
"Evalutate the body form for each element in the list while the "Evalutate the body form for each element in the list while the
predicate form evaluates to True." predicate form evaluates to True."
`(let [[p (lambda [it] ~form)]] `(let [p (lambda [it] ~form)]
(for [it ~lst] (for [it ~lst]
(if (p it) (if (p it)
~@body ~@body
@ -46,8 +46,9 @@
(defmacro ap-map [form lst] (defmacro ap-map [form lst]
"Yield elements evaluated in the form for each element in the list." "Yield elements evaluated in the form for each element in the list."
(let [[v (gensym 'v)] [f (gensym 'f)]] (let [v (gensym 'v)
`(let [[~f (lambda [it] ~form)]] f (gensym 'f)]
`(let [~f (lambda [it] ~form)]
(for [~v ~lst] (for [~v ~lst]
(yield (~f ~v)))))) (yield (~f ~v))))))
@ -55,7 +56,7 @@
(defmacro ap-map-when [predfn rep lst] (defmacro ap-map-when [predfn rep lst]
"Yield elements evaluated for each element in the list when the "Yield elements evaluated for each element in the list when the
predicate function returns True." predicate function returns True."
`(let [[f (lambda [it] ~rep)]] `(let [f (lambda [it] ~rep)]
(for [it ~lst] (for [it ~lst]
(if (~predfn it) (if (~predfn it)
(yield (f it)) (yield (f it))
@ -64,7 +65,7 @@
(defmacro ap-filter [form lst] (defmacro ap-filter [form lst]
"Yield elements returned when the predicate form evaluates to True." "Yield elements returned when the predicate form evaluates to True."
`(let [[pred (lambda [it] ~form)]] `(let [pred (lambda [it] ~form)]
(for [val ~lst] (for [val ~lst]
(if (pred val) (if (pred val)
(yield val))))) (yield val)))))
@ -85,7 +86,7 @@
(defmacro ap-first [predfn lst] (defmacro ap-first [predfn lst]
"Yield the first element that passes `predfn`" "Yield the first element that passes `predfn`"
(with-gensyms [n] (with-gensyms [n]
`(let [[~n None]] `(let [~n None]
(ap-each ~lst (when ~predfn (setv ~n it) (break))) (ap-each ~lst (when ~predfn (setv ~n it) (break)))
~n))) ~n)))
@ -93,7 +94,7 @@
(defmacro ap-last [predfn lst] (defmacro ap-last [predfn lst]
"Yield the last element that passes `predfn`" "Yield the last element that passes `predfn`"
(with-gensyms [n] (with-gensyms [n]
`(let [[~n None]] `(let [~n None]
(ap-each ~lst (none? ~n) (ap-each ~lst (none? ~n)
(when ~predfn (when ~predfn
(setv ~n it))) (setv ~n it)))
@ -103,10 +104,10 @@
(defmacro ap-reduce [form lst &optional [initial-value None]] (defmacro ap-reduce [form lst &optional [initial-value None]]
"Anaphoric form of reduce, `acc' and `it' can be used for a form" "Anaphoric form of reduce, `acc' and `it' can be used for a form"
(if (none? initial-value) (if (none? initial-value)
`(let [[acc (car ~lst)]] `(let [acc (car ~lst)]
(ap-each (cdr ~lst) (setv acc ~form)) (ap-each (cdr ~lst) (setv acc ~form))
acc) acc)
`(let [[acc ~initial-value]] `(let [acc ~initial-value]
(ap-each ~lst (setv acc ~form)) (ap-each ~lst (setv acc ~form))
acc))) acc)))
@ -115,7 +116,7 @@
"Pushes a value through several forms. "Pushes a value through several forms.
(Anaphoric version of -> and ->>)" (Anaphoric version of -> and ->>)"
(if (empty? forms) var (if (empty? forms) var
`(ap-pipe (let [[it ~var]] ~(first forms)) ~@(rest forms)))) `(ap-pipe (let [it ~var] ~(first forms)) ~@(rest forms))))
(defmacro ap-compose [&rest forms] (defmacro ap-compose [&rest forms]

View File

@ -26,8 +26,8 @@
(do (do
(import [requests]) (import [requests])
(let [[r (requests.get (let [r (requests.get
"https://raw.githubusercontent.com/hylang/hy/master/AUTHORS")]] "https://raw.githubusercontent.com/hylang/hy/master/AUTHORS")]
(repeat r.text))) (repeat r.text)))
(except [e ImportError] (except [e ImportError]
(repeat "Botsbuildbots requires `requests' to function.")))) (repeat "Botsbuildbots requires `requests' to function."))))

View File

@ -2,8 +2,8 @@
(defn curry [func] (defn curry [func]
(let [[sig (.getargspec inspect func)] (let [sig (.getargspec inspect func)
[count (len sig.args)]] count (len sig.args)]
(fn [&rest args] (fn [&rest args]
(if (< (len args) count) (if (< (len args) count)

View File

@ -58,7 +58,7 @@
(defmacro/g! fnr [signature &rest body] (defmacro/g! fnr [signature &rest body]
(let [[new-body (recursive-replace 'recur g!recur-fn body)]] (let [new-body (recursive-replace 'recur g!recur-fn body)]
`(do `(do
(import [hy.contrib.loop [--trampoline--]]) (import [hy.contrib.loop [--trampoline--]])
(with-decorator (with-decorator
@ -85,7 +85,7 @@
;; If recur is used in a non-tail-call position, None is returned, which ;; If recur is used in a non-tail-call position, None is returned, which
;; causes chaos. Fixing this to detect if recur is in a tail-call position ;; causes chaos. Fixing this to detect if recur is in a tail-call position
;; and erroring if not is a giant TODO. ;; and erroring if not is a giant TODO.
(let [[fnargs (map (fn [x] (first x)) bindings)] (let [fnargs (map (fn [x] (first x)) bindings)
[initargs (map second bindings)]] initargs (map second bindings)]
`(do (defnr ~g!recur-fn [~@fnargs] ~@body) `(do (defnr ~g!recur-fn [~@fnargs] ~@body)
(~g!recur-fn ~@initargs)))) (~g!recur-fn ~@initargs))))

View File

@ -3,11 +3,11 @@
(defmacro route-with-methods [name path methods params &rest code] (defmacro route-with-methods [name path methods params &rest code]
"Same as route but with an extra methods array to specify HTTP methods" "Same as route but with an extra methods array to specify HTTP methods"
`(let [[deco (apply app.route [~path] `(let [deco (apply app.route [~path]
{"methods" ~methods})]] {"methods" ~methods})]
(with-decorator deco (with-decorator deco
(defn ~name ~params (defn ~name ~params
(do ~@code))))) (do ~@code)))))
;; Some macro examples ;; Some macro examples
(defmacro route [name path params &rest code] (defmacro route [name path params &rest code]

View File

@ -42,22 +42,14 @@
(defmacro let [variables &rest body] (defmacro let [variables &rest body]
"Execute `body` in the lexical context of `variables`" "Execute `body` in the lexical context of `variables`"
(setv macroed_variables [])
(if (not (isinstance variables HyList)) (if (not (isinstance variables HyList))
(macro-error variables "let lexical context must be a list")) (macro-error variables "let lexical context must be a list"))
(for* [variable variables] (if (= (len variables) 0)
(if (isinstance variable HyList) `((fn []
(do ~@body))
(if (!= (len variable) 2) `((fn []
(macro-error variable "let variable assignments must contain two items")) (setv ~@variables)
(.append macroed-variables `(setv ~(get variable 0) ~(get variable 1)))) ~@body))))
(if (isinstance variable HySymbol)
(.append macroed-variables `(setv ~variable None))
(macro-error variable "let lexical context element must be a list or symbol"))))
`((fn []
~@macroed-variables
~@body)))
(defmacro if-python2 [python2-form python3-form] (defmacro if-python2 [python2-form python3-form]
"If running on python2, execute python2-form, else, execute python3-form" "If running on python2, execute python2-form, else, execute python3-form"

View File

@ -84,12 +84,13 @@
(defn distinct [coll] (defn distinct [coll]
"Return a generator from the original collection with duplicates "Return a generator from the original collection with duplicates
removed" removed"
(let [[seen (set)] [citer (iter coll)]] (let [seen (set)
(for* [val citer] citer (iter coll)]
(if (not_in val seen) (for* [val citer]
(do (if (not_in val seen)
(yield val) (do
(.add seen val)))))) (yield val)
(.add seen val))))))
(if-python2 (if-python2
(def (def
@ -158,7 +159,7 @@
(defn drop-last [n coll] (defn drop-last [n coll]
"Return a sequence of all but the last n elements in coll." "Return a sequence of all but the last n elements in coll."
(let [[iters (tee coll)]] (let [iters (tee coll)]
(map first (apply zip [(get iters 0) (map first (apply zip [(get iters 0)
(drop n (get iters 1))])))) (drop n (get iters 1))]))))
@ -210,7 +211,7 @@
(setv _gensym_lock (Lock)) (setv _gensym_lock (Lock))
(defn gensym [&optional [g "G"]] (defn gensym [&optional [g "G"]]
(let [[new_symbol None]] (let [new_symbol None]
(global _gensym_counter) (global _gensym_counter)
(global _gensym_lock) (global _gensym_lock)
(.acquire _gensym_lock) (.acquire _gensym_lock)
@ -310,15 +311,16 @@
from the latter (left-to-right) will be combined with the mapping in from the latter (left-to-right) will be combined with the mapping in
the result by calling (f val-in-result val-in-latter)." the result by calling (f val-in-result val-in-latter)."
(if (any maps) (if (any maps)
(let [[merge-entry (fn [m e] (let [merge-entry (fn [m e]
(let [[k (get e 0)] [v (get e 1)]] (let [k (get e 0)
(if (in k m) v (get e 1)]
(assoc m k (f (get m k) v)) (if (in k m)
(assoc m k v))) (assoc m k (f (get m k) v))
m)] (assoc m k v)))
[merge2 (fn [m1 m2] m)
(reduce merge-entry (.items m2) (or m1 {})))]] merge2 (fn [m1 m2]
(reduce merge2 maps)))) (reduce merge-entry (.items m2) (or m1 {})))]
(reduce merge2 maps))))
(defn neg? [n] (defn neg? [n]
"Return true if n is < 0" "Return true if n is < 0"
@ -402,12 +404,13 @@
"Return every nth member of coll "Return every nth member of coll
raises ValueError for (not (pos? n))" raises ValueError for (not (pos? n))"
(if (pos? n) (if (pos? n)
(let [[citer (iter coll)] [skip (dec n)]] (let [citer (iter coll)
(for* [val citer] skip (dec n)]
(yield val) (for* [val citer]
(for* [_ (range skip)] (yield val)
(next citer)))) (for* [_ (range skip)]
(raise (ValueError "n must be positive")))) (next citer))))
(raise (ValueError "n must be positive"))))
(defn zero? [n] (defn zero? [n]
"Return true if n is 0" "Return true if n is 0"

View File

@ -39,7 +39,7 @@
baz))" baz))"
(if (not (empty? args)) (if (not (empty? args))
(let [[primary (.pop args 0)]] (let [primary (.pop args 0)]
(if (isinstance primary HyList) (if (isinstance primary HyList)
;;; OK. if we have a list, we can go ahead and unpack that ;;; OK. if we have a list, we can go ahead and unpack that
;;; as the argument to with. ;;; as the argument to with.
@ -115,7 +115,7 @@
[(empty? args) `(do ~@body ~@belse)] [(empty? args) `(do ~@body ~@belse)]
[(= (len args) 2) `(for* [~@args] (do ~@body) ~@belse)] [(= (len args) 2) `(for* [~@args] (do ~@body) ~@belse)]
[true [true
(let [[alist (cut args 0 nil 2)]] (let [alist (cut args 0 nil 2)]
`(for* [(, ~@alist) (genexpr (, ~@alist) [~@args])] (do ~@body) ~@belse))])) `(for* [(, ~@alist) (genexpr (, ~@alist) [~@args])] (do ~@body) ~@belse))]))
@ -138,7 +138,7 @@
(if (isinstance expression HyExpression) (if (isinstance expression HyExpression)
`(~(first expression) ~f ~@(rest expression)) `(~(first expression) ~f ~@(rest expression))
`(~expression ~f))) `(~expression ~f)))
`(let [[~f ~form]] `(let [~f ~form]
~@(map build-form expressions) ~@(map build-form expressions)
~f)) ~f))
@ -180,14 +180,25 @@
(defmacro with-gensyms [args &rest body] (defmacro with-gensyms [args &rest body]
`(let ~(HyList (map (fn [x] `[~x (gensym '~x)]) args)) (setv syms [])
~@body)) (for* [arg args]
(.extend syms `[~arg (gensym '~arg)]))
`(let ~syms
~@body))
(defmacro defmacro/g! [name args &rest body] (defmacro defmacro/g! [name args &rest body]
(let [[syms (list (distinct (filter (fn [x] (and (hasattr x "startswith") (.startswith x "g!"))) (flatten body))))]] (let [syms (list
(distinct
(filter (fn [x]
(and (hasattr x "startswith")
(.startswith x "g!")))
(flatten body))))
gensyms []]
(for* [sym syms]
(.extend gensyms `[~sym (gensym (cut '~sym 2))]))
`(defmacro ~name [~@args] `(defmacro ~name [~@args]
(let ~(HyList (map (fn [x] `[~x (gensym (cut '~x 2))]) syms)) (let ~gensyms
~@body)))) ~@body))))
(if-python2 (if-python2
@ -211,9 +222,9 @@
(defmacro defmain [args &rest body] (defmacro defmain [args &rest body]
"Write a function named \"main\" and do the if __main__ dance" "Write a function named \"main\" and do the if __main__ dance"
(let [[retval (gensym)] (let [retval (gensym)
[mainfn `(fn [~@args] mainfn `(fn [~@args]
~@body)]] ~@body)]
`(when (= --name-- "__main__") `(when (= --name-- "__main__")
(import sys) (import sys)
(setv ~retval (apply ~mainfn sys.argv)) (setv ~retval (apply ~mainfn sys.argv))
@ -222,6 +233,6 @@
(defreader @ [expr] (defreader @ [expr]
(let [[decorators (cut expr nil -1)] (let [decorators (cut expr nil -1)
[fndef (get expr -1)]] fndef (get expr -1)]
`(with-decorator ~@decorators ~fndef))) `(with-decorator ~@decorators ~fndef)))

View File

@ -26,7 +26,7 @@
(defn + [&rest args] (defn + [&rest args]
"Shadow + operator for when we need to import / map it against something" "Shadow + operator for when we need to import / map it against something"
(let [[count (len args)]] (let [count (len args)]
(if (zero? count) (if (zero? count)
(raise (TypeError "Need at least 1 argument to add/concatenate")) (raise (TypeError "Need at least 1 argument to add/concatenate"))
(if (= count 1) (if (= count 1)
@ -36,7 +36,7 @@
(defn - [&rest args] (defn - [&rest args]
"Shadow - operator for when we need to import / map it against something" "Shadow - operator for when we need to import / map it against something"
(let [[count (len args)]] (let [count (len args)]
(if (= count 0) (if (= count 0)
(raise (TypeError "Need at least 1 argument to subtract")) (raise (TypeError "Need at least 1 argument to subtract"))
(if (= count 1) (if (= count 1)
@ -53,7 +53,7 @@
(defn / [&rest args] (defn / [&rest args]
"Shadow / operator for when we need to import / map it against something" "Shadow / operator for when we need to import / map it against something"
(let [[count (len args)]] (let [count (len args)]
(if (= count 0) (if (= count 0)
(raise (TypeError "Need at least 1 argument to divide")) (raise (TypeError "Need at least 1 argument to divide"))
(if (= count 1) (if (= count 1)

View File

@ -8,22 +8,22 @@
" -- Alexander Artemenko <svetlyak.40wt@gmail.com> Thu, 30 Sep 2014 13:06:09 +0400") " -- Alexander Artemenko <svetlyak.40wt@gmail.com> Thu, 30 Sep 2014 13:06:09 +0400")
(defn read-lines-from-file [filename] (defn read-lines-from-file [filename]
(let [[f (codecs.open filename "r" "utf-8")]] (let [f (codecs.open filename "r" "utf-8")]
(fn [] (let [[line (.readline f) ]] (fn [] (let [line (.readline f) ]
line)))) line))))
(defn get-version-number [line] (defn get-version-number [line]
(let [[match (re.search r"Changes from.*(\d+\.\d+\.\d+)$" line)]] (let [match (re.search r"Changes from.*(\d+\.\d+\.\d+)$" line)]
(if match (if match
(let [[version (.group match (int 1))] (let [version (.group match (int 1))
[numbered (list (map int (.split version "."))) ] numbered (list (map int (.split version ".")))
[explicit-mapping {"0.9.12" "0.10.0" explicit-mapping {"0.9.12" "0.10.0"
"0.8.2" "0.9.0"}]] "0.8.2" "0.9.0"}]
(assoc numbered 2 (+ (get numbered 2) 1)) (assoc numbered 2 (+ (get numbered 2) 1))
(.get explicit-mapping (.get explicit-mapping
version version
(.join "." (map str numbered))))))) (.join "." (map str numbered)))))))
(defn read-version-content [reader] (defn read-version-content [reader]
@ -36,14 +36,14 @@
(defn read-versions-from-file [filename] (defn read-versions-from-file [filename]
(let [[reader (read-lines-from-file filename)]] (let [reader (read-lines-from-file filename)]
(read-versions-rec (reader) (read-versions-rec (reader)
reader))) reader)))
(defn read-versions-rec [line reader] (defn read-versions-rec [line reader]
(if line (if line
(let [[version (get-version-number line)] (let [version (get-version-number line)
[[content next-line] (read-version-content reader)]] [content next-line] (read-version-content reader)]
(+ [{"from" version (+ [{"from" version
"content" content}] "content" content}]
@ -61,6 +61,6 @@
(defmain [&rest args] (defmain [&rest args]
(let ((versions (read-versions-from-file "NEWS"))) (let [versions (read-versions-from-file "NEWS")]
(for [version versions] (for [version versions]
(print (.encode (format-deb-version version) "utf-8"))))) (print (.encode (format-deb-version version) "utf-8")))))

View File

@ -321,20 +321,18 @@ def test_ast_invalid_for():
def test_ast_valid_let(): def test_ast_valid_let():
"Make sure AST can compile valid let" "Make sure AST can compile valid let"
can_compile("(let [])")
can_compile("(let [a b])") can_compile("(let [a b])")
can_compile("(let [[a 1]])") can_compile("(let [a 1])")
can_compile("(let [[a 1] b])") can_compile("(let [a 1 b nil])")
def test_ast_invalid_let(): def test_ast_invalid_let():
"Make sure AST can't compile invalid let" "Make sure AST can't compile invalid let"
cant_compile("(let 1)") cant_compile("(let 1)")
cant_compile("(let [1])") cant_compile("(let [1])")
cant_compile("(let [[a 1 2]])") cant_compile("(let [a 1 2])")
cant_compile("(let [[]])") cant_compile("(let [a])")
cant_compile("(let [[a]])") cant_compile("(let [1])")
cant_compile("(let [[1]])")
def test_ast_expression_basics(): def test_ast_expression_basics():

View File

@ -55,7 +55,7 @@
[3 6 9]) [3 6 9])
(assert-equal (list (ap-map (* it 3) [])) (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))]))) (assert-equal (let [v 1 f 1] (list (ap-map (it v f) [(fn [a b] (+ a b))])))
[2])) [2]))
(defn test-ap-map-when [] (defn test-ap-map-when []
@ -79,9 +79,9 @@
(defn test-ap-dotimes [] (defn test-ap-dotimes []
"NATIVE: testing anaphoric dotimes" "NATIVE: testing anaphoric dotimes"
(assert-equal (let [[n []]] (ap-dotimes 3 (.append n 3)) n) (assert-equal (let [n []] (ap-dotimes 3 (.append n 3)) n)
[3 3 3]) [3 3 3])
(assert-equal (let [[n []]] (ap-dotimes 3 (.append n it)) n) (assert-equal (let [n []] (ap-dotimes 3 (.append n it)) n)
[0 1 2])) [0 1 2]))
(defn test-ap-first [] (defn test-ap-first []

View File

@ -9,44 +9,44 @@
f))) f)))
(defn test_route [] (defn test_route []
(let [[app (FakeMeth)]] (let [app (FakeMeth)]
(route get-index "/" [] (str "Hy world!")) (route get-index "/" [] (str "Hy world!"))
(setv app-rules (getattr app "rules")) (setv app-rules (getattr app "rules"))
(assert (in "/" app-rules)) (assert (in "/" app-rules))
(let [[(, rule-fun rule-opt) (get app-rules "/")]] (let [(, rule-fun rule-opt) (get app-rules "/")]
(assert (not (empty? rule-opt))) (assert (not (empty? rule-opt)))
(assert (in "GET" (get rule-opt "methods"))) (assert (in "GET" (get rule-opt "methods")))
(assert (= (getattr rule-fun "__name__") "get_index")) (assert (= (getattr rule-fun "__name__") "get_index"))
(assert (= "Hy world!" (rule-fun)))))) (assert (= "Hy world!" (rule-fun))))))
(defn test_post_route [] (defn test_post_route []
(let [[app (FakeMeth)]] (let [app (FakeMeth)]
(post-route get-index "/" [] (str "Hy world!")) (post-route get-index "/" [] (str "Hy world!"))
(setv app-rules (getattr app "rules")) (setv app-rules (getattr app "rules"))
(assert (in "/" app-rules)) (assert (in "/" app-rules))
(let [[(, rule-fun rule-opt) (get app-rules "/")]] (let [(, rule-fun rule-opt) (get app-rules "/")]
(assert (not (empty? rule-opt))) (assert (not (empty? rule-opt)))
(assert (in "POST" (get rule-opt "methods"))) (assert (in "POST" (get rule-opt "methods")))
(assert (= (getattr rule-fun "__name__") "get_index")) (assert (= (getattr rule-fun "__name__") "get_index"))
(assert (= "Hy world!" (rule-fun)))))) (assert (= "Hy world!" (rule-fun))))))
(defn test_put_route [] (defn test_put_route []
(let [[app (FakeMeth)]] (let [app (FakeMeth)]
(put-route get-index "/" [] (str "Hy world!")) (put-route get-index "/" [] (str "Hy world!"))
(setv app-rules (getattr app "rules")) (setv app-rules (getattr app "rules"))
(assert (in "/" app-rules)) (assert (in "/" app-rules))
(let [[(, rule-fun rule-opt) (get app-rules "/")]] (let [(, rule-fun rule-opt) (get app-rules "/")]
(assert (not (empty? rule-opt))) (assert (not (empty? rule-opt)))
(assert (in "PUT" (get rule-opt "methods"))) (assert (in "PUT" (get rule-opt "methods")))
(assert (= (getattr rule-fun "__name__") "get_index")) (assert (= (getattr rule-fun "__name__") "get_index"))
(assert (= "Hy world!" (rule-fun)))))) (assert (= "Hy world!" (rule-fun))))))
(defn test_delete_route [] (defn test_delete_route []
(let [[app (FakeMeth)]] (let [app (FakeMeth)]
(delete-route get-index "/" [] (str "Hy world!")) (delete-route get-index "/" [] (str "Hy world!"))
(setv app-rules (getattr app "rules")) (setv app-rules (getattr app "rules"))
(assert (in "/" app-rules)) (assert (in "/" app-rules))
(let [[(, rule-fun rule-opt) (get app-rules "/")]] (let [(, rule-fun rule-opt) (get app-rules "/")]
(assert (not (empty? rule-opt))) (assert (not (empty? rule-opt)))
(assert (in "DELETE" (get rule-opt "methods"))) (assert (in "DELETE" (get rule-opt "methods")))
(assert (= (getattr rule-fun "__name__") "get_index")) (assert (= (getattr rule-fun "__name__") "get_index"))

View File

@ -15,17 +15,17 @@
walk-form))) walk-form)))
(defn test-walk [] (defn test-walk []
(let [[acc '()]] (let [acc '()]
(assert (= (walk (partial collector acc) identity walk-form) (assert (= (walk (partial collector acc) identity walk-form)
[nil nil])) [nil nil]))
(assert (= acc walk-form))) (assert (= acc walk-form)))
(let [[acc []]] (let [acc []]
(assert (= (walk identity (partial collector acc) walk-form) (assert (= (walk identity (partial collector acc) walk-form)
nil)) nil))
(assert (= acc [walk-form])))) (assert (= acc [walk-form]))))
(defn test-walk-iterators [] (defn test-walk-iterators []
(let [[acc []]] (let [acc []]
(assert (= (walk (fn [x] (* 2 x)) (fn [x] x) (assert (= (walk (fn [x] (* 2 x)) (fn [x] x)
(drop 1 [1 [2 [3 [4]]]])) (drop 1 [1 [2 [3 [4]]]]))
[[2 [3 [4]] 2 [3 [4]]]])))) [[2 [3 [4]] 2 [3 [4]]]]))))

View File

@ -592,7 +592,7 @@
(setv res (list (take-nth 3 [1 2 3 None 5 6]))) (setv res (list (take-nth 3 [1 2 3 None 5 6])))
(assert-equal res [1 None]) (assert-equal res [1 None])
;; using 0 should raise ValueError ;; using 0 should raise ValueError
(let [[passed false]] (let [passed false]
(try (try
(setv res (list (take-nth 0 [1 2 3 4 5 6 7]))) (setv res (list (take-nth 0 [1 2 3 4 5 6 7])))
(except [ValueError] (setv passed true))) (except [ValueError] (setv passed true)))

View File

@ -36,7 +36,7 @@
(+ self.x value))]) (+ self.x value))])
(assert (= B.x 42)) (assert (= B.x 42))
(assert (= (.y (B) 5) 47)) (assert (= (.y (B) 5) 47))
(let [[b (B)]] (let [b (B)]
(setv B.x 0) (setv B.x 0)
(assert (= (.y b 1) 1)))) (assert (= (.y b 1) 1))))

View File

@ -355,7 +355,7 @@
(try (do) (except [IOError]) (except)) (try (do) (except [IOError]) (except))
;; Test correct (raise) ;; Test correct (raise)
(let [[passed false]] (let [passed false]
(try (try
(try (try
(raise IndexError) (raise IndexError)
@ -365,7 +365,7 @@
(assert passed)) (assert passed))
;; Test incorrect (raise) ;; Test incorrect (raise)
(let [[passed false]] (let [passed false]
(try (try
(raise) (raise)
;; Python 2 raises TypeError ;; Python 2 raises TypeError
@ -374,16 +374,15 @@
(setv passed true))) (setv passed true)))
(assert passed)) (assert passed))
;; Test (finally) ;; Test (finally)
(let [[passed false]] (let [passed false]
(try (try
(do) (do)
(finally (setv passed true))) (finally (setv passed true)))
(assert passed)) (assert passed))
;; Test (finally) + (raise) ;; Test (finally) + (raise)
(let [[passed false]] (let [passed false]
(try (try
(raise Exception) (raise Exception)
(except) (except)
@ -392,8 +391,8 @@
;; Test (finally) + (raise) + (else) ;; Test (finally) + (raise) + (else)
(let [[passed false] (let [passed false
[not-elsed true]] not-elsed true]
(try (try
(raise Exception) (raise Exception)
(except) (except)
@ -460,13 +459,13 @@
(setv foobar42ofthebaz 42) (setv foobar42ofthebaz 42)
(assert (= foobar42ofthebaz 42)))) (assert (= foobar42ofthebaz 42))))
(let [[passed false]] (let [passed false]
(try (try
(try (do) (except) (else (bla))) (try (do) (except) (else (bla)))
(except [NameError] (setv passed true))) (except [NameError] (setv passed true)))
(assert passed)) (assert passed))
(let [[x 0]] (let [x 0]
(try (try
(raise IOError) (raise IOError)
(except [IOError] (except [IOError]
@ -474,7 +473,7 @@
(else (setv x 44))) (else (setv x 44)))
(assert (= x 45))) (assert (= x 45)))
(let [[x 0]] (let [x 0]
(try (try
(raise KeyError) (raise KeyError)
(except [] (except []
@ -482,7 +481,7 @@
(else (setv x 44))) (else (setv x 44)))
(assert (= x 45))) (assert (= x 45)))
(let [[x 0]] (let [x 0]
(try (try
(try (try
(raise KeyError) (raise KeyError)
@ -561,7 +560,7 @@
(defn test-yield-in-try [] (defn test-yield-in-try []
"NATIVE: test yield in try" "NATIVE: test yield in try"
(defn gen [] (defn gen []
(let [[x 1]] (let [x 1]
(try (yield x) (try (yield x)
(finally (print x))))) (finally (print x)))))
(setv output (list (gen))) (setv output (list (gen)))
@ -631,13 +630,13 @@
(defn test-for-else [] (defn test-for-else []
"NATIVE: test for else" "NATIVE: test for else"
(let [[x 0]] (let [x 0]
(for* [a [1 2]] (for* [a [1 2]]
(setv x (+ x a)) (setv x (+ x a))
(else (setv x (+ x 50)))) (else (setv x (+ x 50))))
(assert (= x 53))) (assert (= x 53)))
(let [[x 0]] (let [x 0]
(for* [a [1 2]] (for* [a [1 2]]
(setv x (+ x a)) (setv x (+ x a))
(else)) (else))
@ -751,28 +750,28 @@
(defn test-let [] (defn test-let []
"NATIVE: test let works rightish" "NATIVE: test let works rightish"
;; TODO: test sad paths for let ;; TODO: test sad paths for let
(assert (= (let [[x 1] [y 2] [z 3]] (+ x y z)) 6)) (assert (= (let [x 1 y 2 z 3] (+ x y z)) 6))
(assert (= (let [[x 1] a [y 2] b] (if a 1 2)) 2)) (assert (= (let [x 1 a nil y 2 b nil] (if a 1 2)) 2))
(assert (= (let [x] x) nil)) (assert (= (let [x nil] x) nil))
(assert (= (let [[x "x not bound"]] (setv x "x bound by setv") x) (assert (= (let [x "x not bound"] (setv x "x bound by setv") x)
"x bound by setv")) "x bound by setv"))
(assert (= (let [[x "let nests scope correctly"]] (assert (= (let [x "let nests scope correctly"]
(let [y] x)) (let [y nil] x))
"let nests scope correctly")) "let nests scope correctly"))
(assert (= (let [[x 999999]] (assert (= (let [x 999999]
(let [[x "x being rebound"]] x)) (let [x "x being rebound"] x))
"x being rebound")) "x being rebound"))
(assert (= (let [[x "x not being rebound"]] (assert (= (let [x "x not being rebound"]
(let [[x 2]] nil) (let [x 2] nil)
x) x)
"x not being rebound")) "x not being rebound"))
(assert (= (let [[x (set [3 2 1 3 2])] [y x] [z y]] z) (set [1 2 3]))) (assert (= (let [x (set [3 2 1 3 2]) y x z y] z) (set [1 2 3])))
(import math) (import math)
(let [[cos math.cos] (let [cos math.cos
[foo-cos (fn [x] (cos x))]] foo-cos (fn [x] (cos x))]
(assert (= (cos math.pi) -1.0)) (assert (= (cos math.pi) -1.0))
(assert (= (foo-cos (- math.pi)) -1.0)) (assert (= (foo-cos (- math.pi)) -1.0))
(let [[cos (fn [_] "cos has been locally rebound")]] (let [cos (fn [_] "cos has been locally rebound")]
(assert (= (cos cos) "cos has been locally rebound")) (assert (= (cos cos) "cos has been locally rebound"))
(assert (= (-> math.pi (/ 3) foo-cos (round 2)) 0.5))) (assert (= (-> math.pi (/ 3) foo-cos (round 2)) 0.5)))
(setv cos (fn [_] "cos has been rebound by setv")) (setv cos (fn [_] "cos has been rebound by setv"))
@ -792,9 +791,9 @@
(defn test-let-scope [] (defn test-let-scope []
"NATIVE: test let works rightish" "NATIVE: test let works rightish"
(setv y 123) (setv y 123)
(assert (= (let [[x 1] (assert (= (let [x 1
[y 2] y 2
[z 3]] z 3]
(+ x y z)) (+ x y z))
6)) 6))
(try (try
@ -805,31 +804,31 @@
(defn test-symbol-utf-8 [] (defn test-symbol-utf-8 []
"NATIVE: test symbol encoded" "NATIVE: test symbol encoded"
(let [[ "love"] (let [ "love"
[ "flower"]] "flower"]
(assert (= (+ ) "flowerlove")))) (assert (= (+ ) "flowerlove"))))
(defn test-symbol-dash [] (defn test-symbol-dash []
"NATIVE: test symbol encoded" "NATIVE: test symbol encoded"
(let [[- "doublelove"] (let [- "doublelove"
[-_- "what?"]] -_- "what?"]
(assert (= - "doublelove")) (assert (= - "doublelove"))
(assert (= -_- "what?")))) (assert (= -_- "what?"))))
(defn test-symbol-question-mark [] (defn test-symbol-question-mark []
"NATIVE: test foo? -> is_foo behavior" "NATIVE: test foo? -> is_foo behavior"
(let [[foo? "nachos"]] (let [foo? "nachos"]
(assert (= is_foo "nachos")))) (assert (= is_foo "nachos"))))
(defn test-and [] (defn test-and []
"NATIVE: test the and function" "NATIVE: test the and function"
(let [[and123 (and 1 2 3)] (let [and123 (and 1 2 3)
[and-false (and 1 False 3)] and-false (and 1 False 3)
[and-true (and)] and-true (and)
[and-single (and 1)]] and-single (and 1)]
(assert (= and123 3)) (assert (= and123 3))
(assert (= and-false False)) (assert (= and-false False))
(assert (= and-true True)) (assert (= and-true True))
@ -842,11 +841,11 @@
(defn test-or [] (defn test-or []
"NATIVE: test the or function" "NATIVE: test the or function"
(let [[or-all-true (or 1 2 3 True "string")] (let [or-all-true (or 1 2 3 True "string")
[or-some-true (or False "hello")] or-some-true (or False "hello")
[or-none-true (or False False)] or-none-true (or False False)
[or-false (or)] or-false (or)
[or-single (or 1)]] or-single (or 1)]
(assert (= or-all-true 1)) (assert (= or-all-true 1))
(assert (= or-some-true "hello")) (assert (= or-some-true "hello"))
(assert (= or-none-true False)) (assert (= or-none-true False))
@ -861,12 +860,12 @@
(defn test-if-return-branching [] (defn test-if-return-branching []
"NATIVE: test the if return branching" "NATIVE: test the if return branching"
; thanks, algernon ; thanks, algernon
(assert (= 1 (let [[x 1] (assert (= 1 (let [x 1
[y 2]] y 2]
(if true (if true
2) 2)
1))) 1)))
(assert (= 1 (let [[x 1] [y 2]] (assert (= 1 (let [x 1 y 2]
(do) (do)
(do) (do)
((fn [] 1)))))) ((fn [] 1))))))
@ -915,9 +914,9 @@
(defn test-eval-globals [] (defn test-eval-globals []
"NATIVE: test eval with explicit global dict" "NATIVE: test eval with explicit global dict"
(assert (= 'bar (eval (quote foo) {'foo 'bar}))) (assert (= 'bar (eval (quote foo) {'foo 'bar})))
(assert (= 1 (let [[d {}]] (eval '(setv x 1) d) (eval (quote x) d)))) (assert (= 1 (let [d {}] (eval '(setv x 1) d) (eval (quote x) d))))
(let [[d1 {}] (let [d1 {}
[d2 {}]] d2 {}]
(eval '(setv x 1) d1) (eval '(setv x 1) d1)
(try (try
(do (do
@ -998,7 +997,7 @@
(defn test-if-let-mixing [] (defn test-if-let-mixing []
"NATIVE: test that we can now mix if and let" "NATIVE: test that we can now mix if and let"
(assert (= 0 (if true (let [[x 0]] x) 42)))) (assert (= 0 (if true (let [x 0] x) 42))))
(defn test-if-in-if [] (defn test-if-in-if []
"NATIVE: test that we can use if in if" "NATIVE: test that we can use if in if"

View File

@ -69,73 +69,73 @@
(defn test-augassign-add [] (defn test-augassign-add []
"NATIVE: test augassign add" "NATIVE: test augassign add"
(let [[x 1]] (let [x 1]
(+= x 41) (+= x 41)
(assert (= x 42)))) (assert (= x 42))))
(defn test-augassign-sub [] (defn test-augassign-sub []
"NATIVE: test augassign sub" "NATIVE: test augassign sub"
(let [[x 1]] (let [x 1]
(-= x 41) (-= x 41)
(assert (= x -40)))) (assert (= x -40))))
(defn test-augassign-mult [] (defn test-augassign-mult []
"NATIVE: test augassign mult" "NATIVE: test augassign mult"
(let [[x 1]] (let [x 1]
(*= x 41) (*= x 41)
(assert (= x 41)))) (assert (= x 41))))
(defn test-augassign-div [] (defn test-augassign-div []
"NATIVE: test augassign div" "NATIVE: test augassign div"
(let [[x 42]] (let [x 42]
(/= x 2) (/= x 2)
(assert (= x 21)))) (assert (= x 21))))
(defn test-augassign-floordiv [] (defn test-augassign-floordiv []
"NATIVE: test augassign floordiv" "NATIVE: test augassign floordiv"
(let [[x 42]] (let [x 42]
(//= x 2) (//= x 2)
(assert (= x 21)))) (assert (= x 21))))
(defn test-augassign-mod [] (defn test-augassign-mod []
"NATIVE: test augassign mod" "NATIVE: test augassign mod"
(let [[x 42]] (let [x 42]
(%= x 2) (%= x 2)
(assert (= x 0)))) (assert (= x 0))))
(defn test-augassign-pow [] (defn test-augassign-pow []
"NATIVE: test augassign pow" "NATIVE: test augassign pow"
(let [[x 2]] (let [x 2]
(**= x 3) (**= x 3)
(assert (= x 8)))) (assert (= x 8))))
(defn test-augassign-lshift [] (defn test-augassign-lshift []
"NATIVE: test augassign lshift" "NATIVE: test augassign lshift"
(let [[x 2]] (let [x 2]
(<<= x 2) (<<= x 2)
(assert (= x 8)))) (assert (= x 8))))
(defn test-augassign-rshift [] (defn test-augassign-rshift []
"NATIVE: test augassign rshift" "NATIVE: test augassign rshift"
(let [[x 8]] (let [x 8]
(>>= x 1) (>>= x 1)
(assert (= x 4)))) (assert (= x 4))))
(defn test-augassign-bitand [] (defn test-augassign-bitand []
"NATIVE: test augassign bitand" "NATIVE: test augassign bitand"
(let [[x 8]] (let [x 8]
(&= x 1) (&= x 1)
(assert (= x 0)))) (assert (= x 0))))
(defn test-augassign-bitor [] (defn test-augassign-bitor []
"NATIVE: test augassign bitand" "NATIVE: test augassign bitand"
(let [[x 0]] (let [x 0]
(|= x 2) (|= x 2)
(assert (= x 2)))) (assert (= x 2))))
(defn test-augassign-bitxor [] (defn test-augassign-bitxor []
"NATIVE: test augassign bitand" "NATIVE: test augassign bitand"
(let [[x 1]] (let [x 1]
(^= x 1) (^= x 1)
(assert (= x 0)))) (assert (= x 0))))
@ -147,13 +147,13 @@
(defclass HyTestMatrix [list] (defclass HyTestMatrix [list]
[--matmul-- [--matmul--
(fn [self other] (fn [self other]
(let [[n (len self)] (let [n (len self)
[m (len (. other [0]))] m (len (. other [0]))
[result []]] result []]
(for [i (range m)] (for [i (range m)]
(let [[result-row []]] (let [result-row []]
(for [j (range n)] (for [j (range n)]
(let [[dot-product 0]] (let [dot-product 0]
(for [k (range (len (. self [0])))] (for [k (range (len (. self [0])))]
(+= dot-product (* (. self [i] [k]) (+= dot-product (* (. self [i] [k])
(. other [k] [j])))) (. other [k] [j]))))
@ -179,15 +179,15 @@
(assert (= (@ first-test-matrix second-test-matrix) (assert (= (@ first-test-matrix second-test-matrix)
product-of-test-matrices)) product-of-test-matrices))
;; Python <= 3.4 ;; Python <= 3.4
(let [[matmul-attempt (try (@ first-test-matrix second-test-matrix) (let [matmul-attempt (try (@ first-test-matrix second-test-matrix)
(except [e [Exception]] e))]] (except [e [Exception]] e))]
(assert (isinstance matmul-attempt NameError))))) (assert (isinstance matmul-attempt NameError)))))
(defn test-augassign-matmul [] (defn test-augassign-matmul []
"NATIVE: test augmented-assignment matrix multiplication" "NATIVE: test augmented-assignment matrix multiplication"
(let [[matrix first-test-matrix] (let [matrix first-test-matrix
[matmul-attempt (try (@= matrix second-test-matrix) matmul-attempt (try (@= matrix second-test-matrix)
(except [e [Exception]] e))]] (except [e [Exception]] e))]
(if PY35 (if PY35
(assert (= product-of-test-matrices matrix)) (assert (= product-of-test-matrices matrix))
(assert (isinstance matmul-attempt NameError))))) (assert (isinstance matmul-attempt NameError)))))

View File

@ -107,8 +107,8 @@
(import [astor.codegen [to_source]]) (import [astor.codegen [to_source]])
(import [hy.importer [import_buffer_to_ast]]) (import [hy.importer [import_buffer_to_ast]])
(setv macro1 "(defmacro nif [expr pos zero neg] (setv macro1 "(defmacro nif [expr pos zero neg]
(let [[g (gensym)]] (let [g (gensym)]
`(let [[~g ~expr]] `(let [~g ~expr]
(cond [(pos? ~g) ~pos] (cond [(pos? ~g) ~pos]
[(zero? ~g) ~zero] [(zero? ~g) ~zero]
[(neg? ~g) ~neg])))) [(neg? ~g) ~neg]))))
@ -133,7 +133,7 @@
(import [hy.importer [import_buffer_to_ast]]) (import [hy.importer [import_buffer_to_ast]])
(setv macro1 "(defmacro nif [expr pos zero neg] (setv macro1 "(defmacro nif [expr pos zero neg]
(with-gensyms [a] (with-gensyms [a]
`(let [[~a ~expr]] `(let [~a ~expr]
(cond [(pos? ~a) ~pos] (cond [(pos? ~a) ~pos]
[(zero? ~a) ~zero] [(zero? ~a) ~zero]
[(neg? ~a) ~neg])))) [(neg? ~a) ~neg]))))
@ -155,7 +155,7 @@
(import [astor.codegen [to_source]]) (import [astor.codegen [to_source]])
(import [hy.importer [import_buffer_to_ast]]) (import [hy.importer [import_buffer_to_ast]])
(setv macro1 "(defmacro/g! nif [expr pos zero neg] (setv macro1 "(defmacro/g! nif [expr pos zero neg]
`(let [[~g!res ~expr]] `(let [~g!res ~expr]
(cond [(pos? ~g!res) ~pos] (cond [(pos? ~g!res) ~pos]
[(zero? ~g!res) ~zero] [(zero? ~g!res) ~zero]
[(neg? ~g!res) ~neg]))) [(neg? ~g!res) ~neg])))

View File

@ -15,14 +15,14 @@
(defn test-kwonly [] (defn test-kwonly []
"NATIVE: test keyword-only arguments" "NATIVE: test keyword-only arguments"
;; keyword-only with default works ;; keyword-only with default works
(let [[kwonly-foo-default-false (fn [&kwonly [foo false]] foo)]] (let [kwonly-foo-default-false (fn [&kwonly [foo false]] foo)]
(assert (= (apply kwonly-foo-default-false) false)) (assert (= (apply kwonly-foo-default-false) false))
(assert (= (apply kwonly-foo-default-false [] {"foo" true}) true))) (assert (= (apply kwonly-foo-default-false [] {"foo" true}) true)))
;; keyword-only without default ... ;; keyword-only without default ...
(let [[kwonly-foo-no-default (fn [&kwonly foo] foo)] (let [kwonly-foo-no-default (fn [&kwonly foo] foo)
[attempt-to-omit-default (try attempt-to-omit-default (try
(kwonly-foo-no-default) (kwonly-foo-no-default)
(except [e [Exception]] e))]] (except [e [Exception]] e))]
;; works ;; works
(assert (= (apply kwonly-foo-no-default [] {"foo" "quux"}) "quux")) (assert (= (apply kwonly-foo-no-default [] {"foo" "quux"}) "quux"))
;; raises TypeError with appropriate message if not supplied ;; raises TypeError with appropriate message if not supplied
@ -30,9 +30,9 @@
(assert (in "missing 1 required keyword-only argument: 'foo'" (assert (in "missing 1 required keyword-only argument: 'foo'"
(. attempt-to-omit-default args [0])))) (. attempt-to-omit-default args [0]))))
;; keyword-only with other arg types works ;; keyword-only with other arg types works
(let [[function-of-various-args (let [function-of-various-args
(fn [a b &rest args &kwonly foo &kwargs kwargs] (fn [a b &rest args &kwonly foo &kwargs kwargs]
(, a b args foo kwargs))]] (, a b args foo kwargs))]
(assert (= (apply function-of-various-args (assert (= (apply function-of-various-args
[1 2 3 4] {"foo" 5 "bar" 6 "quux" 7}) [1 2 3 4] {"foo" 5 "bar" 6 "quux" 7})
(, 1 2 (, 3 4) 5 {"bar" 6 "quux" 7}))))) (, 1 2 (, 3 4) 5 {"bar" 6 "quux" 7})))))

View File

@ -1,6 +1,6 @@
(defn test-shadow-addition [] (defn test-shadow-addition []
"NATIVE: test shadow addition" "NATIVE: test shadow addition"
(let [[x +]] (let [x +]
(assert (try (assert (try
(x) (x)
(except [TypeError] True) (except [TypeError] True)
@ -21,7 +21,7 @@
(defn test-shadow-subtraction [] (defn test-shadow-subtraction []
"NATIVE: test shadow subtraction" "NATIVE: test shadow subtraction"
(let [[x -]] (let [x -]
(assert (try (assert (try
(x) (x)
(except [TypeError] True) (except [TypeError] True)
@ -33,7 +33,7 @@
(defn test-shadow-multiplication [] (defn test-shadow-multiplication []
"NATIVE: test shadow multiplication" "NATIVE: test shadow multiplication"
(let [[x *]] (let [x *]
(assert (= (x) 1)) (assert (= (x) 1))
(assert (= (x 3) 3)) (assert (= (x 3) 3))
(assert (= (x 3 3) 9)))) (assert (= (x 3 3) 9))))
@ -41,7 +41,7 @@
(defn test-shadow-division [] (defn test-shadow-division []
"NATIVE: test shadow division" "NATIVE: test shadow division"
(let [[x /]] (let [x /]
(assert (try (assert (try
(x) (x)
(except [TypeError] True) (except [TypeError] True)
@ -71,12 +71,12 @@
[1 1] [1 1]
[2 2]]] [2 2]]]
(assert (= (apply x args) (not (apply y args)))))) (assert (= (apply x args) (not (apply y args))))))
(let [[s-lt <] (let [s-lt <
[s-gt >] s-gt >
[s-le <=] s-le <=
[s-ge >=] s-ge >=
[s-eq =] s-eq =
[s-ne !=]] s-ne !=]
(assert (apply s-lt [1 2 3])) (assert (apply s-lt [1 2 3]))
(assert (not (apply s-lt [3 2 1]))) (assert (not (apply s-lt [3 2 1])))
(assert (apply s-gt [3 2 1])) (assert (apply s-gt [3 2 1]))