Burninate the synonyms `true`, `false`, and `nil`

Per the straw poll in #908, as an alternative to #1147.

Now you must use `True`, `False`, and `None`, as in Python. Or just assign `true` to `True`, etc.; the old synonyms aren't reserved words anymore.
This commit is contained in:
Kodi Arfer 2016-11-23 18:35:17 -08:00
parent f644dda0dd
commit ed8e37da62
23 changed files with 186 additions and 255 deletions

View File

@ -392,7 +392,7 @@ Some example usage:
.. code-block:: clj
=> (if true
=> (if True
... (do (print "Side effects rock!")
... (print "Yeah, really!")))
Side effects rock!
@ -589,7 +589,7 @@ Parameters may have the following keywords in front of them:
=> (apply compare ["lisp" "python"]
... {"keyfn" (fn [x y]
... (reduce - (map (fn [s] (ord (first s))) [x y])))
... "reverse" true})
... "reverse" True})
4
.. code-block:: python
@ -922,8 +922,8 @@ if / if* / if-not
if-not
``if / if* / if-not`` respect Python *truthiness*, that is, a *test* fails if it
evaluates to a "zero" (including values of ``len`` zero, ``nil``, and
``false``), and passes otherwise, but values with a ``__bool__`` method
evaluates to a "zero" (including values of ``len`` zero, ``None``, and
``False``), and passes otherwise, but values with a ``__bool__`` method
(``__nonzero__`` in Python 2) can overrides this.
The ``if`` macro is for conditionally selecting an expression for evaluation.
@ -931,7 +931,7 @@ The result of the selected expression becomes the result of the entire ``if``
form. ``if`` can select a group of expressions with the help of a ``do`` block.
``if`` takes any number of alternating *test* and *then* expressions, plus an
optional *else* expression at the end, which defaults to ``nil``. ``if`` checks
optional *else* expression at the end, which defaults to ``None``. ``if`` checks
each *test* in turn, and selects the *then* corresponding to the first passed
test. ``if`` does not evaluate any expressions following its selection, similar
to the ``if/elif/else`` control structure from Python. If no tests pass, ``if``
@ -944,7 +944,7 @@ generally no reason to use it directly.
``if-not`` is similar to ``if*`` but the second expression will be executed
when the condition fails while the third and final expression is executed when
the test succeeds -- the opposite order of ``if*``. The final expression is
again optional and defaults to ``nil``.
again optional and defaults to ``None``.
Example usage:
@ -974,7 +974,7 @@ lif and lif-not
lif-not
For those that prefer a more Lispy ``if`` clause, we have
``lif``. This *only* considers ``None`` / ``nil`` to be false! All other
``lif``. This *only* considers ``None`` to be false! All other
"false-ish" Python values are considered true. Conversely, we have
``lif-not`` in parallel to ``if`` and ``if-not`` which
reverses the comparison.
@ -988,12 +988,8 @@ reverses the comparison.
"true"
=> (lif 0 "true" "false")
"true"
=> (lif nil "true" "false")
"false"
=> (lif None "true" "false")
"false"
=> (lif-not nil "true" "false")
"true"
=> (lif-not None "true" "false")
"true"
=> (lif-not False "true" "false")

View File

@ -90,7 +90,7 @@ Checks whether *foo* is a :ref:`cons cell <hycons>`.
=> (cons? a)
True
=> (cons? nil)
=> (cons? None)
False
=> (cons? [1 2 3])
@ -137,7 +137,7 @@ is ``True``, the function prints Python code instead.
body=[
Expr(value=Call(func=Name(id='print'), args=[Str(s='Hello World!')], keywords=[], starargs=None, kwargs=None))])
=> (disassemble '(print "Hello World!") true)
=> (disassemble '(print "Hello World!") True)
print('Hello World!')
@ -595,36 +595,6 @@ Returns ``True`` if *x* is less than zero. Raises ``TypeError`` if
=> (neg? 0)
False
.. _nil?-fn:
nil?
----
Usage: ``(nil? x)``
Returns ``True`` if *x* is ``nil`` / ``None``.
.. code-block:: hy
=> (nil? nil)
True
=> (nil? None)
True
=> (nil? 0)
False
=> (setf x nil)
=> (nil? x)
True
=> ;; list.append always returns None
=> (nil? (.append [1 2 3] 4))
True
.. _none?-fn:
none?
@ -656,10 +626,10 @@ Returns ``True`` if *x* is ``None``.
nth
---
Usage: ``(nth coll n &optional [default nil])``
Usage: ``(nth coll n &optional [default None])``
Returns the *n*-th item in a collection, counting from 0. Return the
default value, ``nil``, if out of bounds (unless specified otherwise).
default value, ``None``, if out of bounds (unless specified otherwise).
Raises ``ValueError`` if *n* is negative.
.. code-block:: hy
@ -670,7 +640,7 @@ Raises ``ValueError`` if *n* is negative.
=> (nth [1 2 4 7] 3)
7
=> (nil? (nth [1 2 4 7] 5))
=> (none? (nth [1 2 4 7] 5))
True
=> (nth [1 2 4 7] 5 "default")
@ -807,23 +777,23 @@ some
Usage: ``(some pred coll)``
Returns the first logically-true value of ``(pred x)`` for any ``x`` in
*coll*, otherwise ``nil``. Return ``nil`` if *coll* is empty.
*coll*, otherwise ``None``. Return ``None`` if *coll* is empty.
.. code-block:: hy
=> (some even? [2 4 6])
True
=> (nil? (some even? [1 3 5]))
=> (none? (some even? [1 3 5]))
True
=> (nil? (some identity [0 "" []]))
=> (none? (some identity [0 "" []]))
True
=> (some identity [0 "non-empty-string" []])
'non-empty-string'
=> (nil? (some even? []))
=> (none? (some even? []))
True
@ -898,12 +868,12 @@ as an example of how to use some of these functions.
(defn fib []
(setv a 0)
(setv b 1)
(while true
(while True
(yield a)
(setv (, a b) (, b (+ a b)))))
Note the ``(while true ...)`` loop. If we run this in the REPL,
Note the ``(while True ...)`` loop. If we run this in the REPL,
.. code-block:: hy
@ -1140,7 +1110,7 @@ if *from-file* ends before a complete expression can be parsed.
=> ; (print "hyfriends!")
=> (with [f (open "example.hy")]
... (try
... (while true
... (while True
... (let [exp (read f)]
... (do
... (print "OHY" exp)

View File

@ -180,7 +180,7 @@ expressions are made of Python lists wrapped in a
``HyExpression``. However, the ``HyCons`` mimics the behavior of
"usual" Lisp variants thusly:
- ``(cons something nil)`` is ``(HyExpression [something])``
- ``(cons something None)`` is ``(HyExpression [something])``
- ``(cons something some-list)`` is ``((type some-list) (+ [something]
some-list))`` (if ``some-list`` inherits from ``list``).
- ``(get (cons a b) 0)`` is ``a``
@ -288,7 +288,7 @@ Second Stage Expression-Dispatch
The only special case is the ``HyExpression``, since we need to create different
AST depending on the special form in question. For instance, when we hit an
``(if true true false)``, we need to generate a ``ast.If``, and properly
``(if True True False)``, we need to generate a ``ast.If``, and properly
compile the sub-nodes. This is where the ``@builds()`` with a String as an
argument comes in.
@ -321,7 +321,7 @@ In Python, doing something like:
features, such as ``if``, ``for``, or ``while`` are statements.
Since they have no "value" to Python, this makes working in Hy hard, since
doing something like ``(print (if true true false))`` is not just common, it's
doing something like ``(print (if True True False))`` is not just common, it's
expected.
As a result, we auto-mangle things using a ``Result`` object, where we offer
@ -331,7 +331,7 @@ assignment to things while running.
As example, the Hy::
(print (if true true false))
(print (if True True False))
Will turn into::

View File

@ -138,13 +138,13 @@ Coding Style
(def *limit* 400000)
(defn fibs [a b]
(while true
(while True
(yield a)
(setv (, a b) (, b (+ a b)))))
;; Bad (and not preferred)
(defn fibs [a b]
(while true
(while True
(yield a)
(def (, a b) (, b (+ a b)))))

View File

@ -264,14 +264,14 @@ In Hy, you would do:
(print "That variable is too big!")]
[(< somevar 10)
(print "That variable is too small!")]
[true
[True
(print "That variable is jussssst right!")])
What you'll notice is that ``cond`` switches off between a statement
that is executed and checked conditionally for true or falseness, and
then a bit of code to execute if it turns out to be true. You'll also
notice that the ``else`` is implemented at the end simply by checking
for ``true`` -- that's because ``true`` will always be true, so if we get
for ``True`` -- that's because ``True`` will always be true, so if we get
this far, we'll always run that one!
You might notice above that if you have code like:

View File

@ -82,8 +82,7 @@ def load_stdlib():
# are assignable in Python 2.* but become
# keywords in Python 3.*
def _is_hy_builtin(name, module_name):
extras = ['True', 'False', 'None',
'true', 'false', 'nil']
extras = ['True', 'False', 'None']
if name in extras or keyword.iskeyword(name):
return True
# for non-Hy modules, check for pre-existing name in

View File

@ -39,7 +39,7 @@
((type form) (outer (HyExpression (map inner form))))]
[(coll? form)
(walk inner outer (list form))]
[true (outer form)]))
[True (outer form)]))
(defn postwalk [f form]
"Performs depth-first, post-order traversal of form. Calls f on each

View File

@ -64,7 +64,7 @@
"Decrement n by 1"
(- n 1))
(defn disassemble [tree &optional [codegen false]]
(defn disassemble [tree &optional [codegen False]]
"Return the python AST for a quoted Hy tree as a string.
If the second argument is true, generate python code instead."
(import astor)
@ -151,7 +151,7 @@
(defn drop [count coll]
"Drop `count` elements from `coll` and yield back the rest"
(islice coll count nil))
(islice coll count None))
(defn drop-last [n coll]
"Return a sequence of all but the last n elements in coll."
@ -225,7 +225,7 @@
(defn first [coll]
"Return first item from `coll`"
(next (iter coll) nil))
(next (iter coll) None))
(defn identity [x]
"Returns the argument unchanged"
@ -250,8 +250,8 @@
"Return True if char `x` parses as an integer"
(try
(integer? (int x))
(except [e ValueError] False)
(except [e TypeError] False)))
(except [ValueError] False)
(except [TypeError] False)))
(defn interleave [&rest seqs]
"Return an iterable of the first item in each of seqs, then the second etc."
@ -267,7 +267,7 @@
(defn iterate [f x]
(setv val x)
(while true
(while True
(yield val)
(setv val (f val))))
@ -324,17 +324,13 @@
"Return true if x is None"
(is x None))
(defn nil? [x]
"Return true if x is nil (None)"
(is x None))
(defn numeric? [x]
(import numbers)
(instance? numbers.Number x))
(defn nth [coll n &optional [default nil]]
(defn nth [coll n &optional [default None]]
"Return nth item in collection or sequence, counting from 0.
Return nil if out of bounds unless specified otherwise."
Return None if out of bounds unless specified otherwise."
(next (drop n coll) default))
(defn odd? [n]
@ -348,7 +344,7 @@
more to skip elements, or less for a sliding window with overlap."
(setv
step (or step n)
slices (genexpr (itertools.islice coll start nil step) [start (range n)]))
slices (genexpr (itertools.islice coll start None step) [start (range n)]))
(if (is fillvalue -sentinel)
(apply zip slices)
(apply zip-longest slices {"fillvalue" fillvalue})))
@ -363,7 +359,7 @@
(defn repeatedly [func]
"Yield result of running func repeatedly"
(while true
(while True
(yield (func))))
(defn second [coll]
@ -371,8 +367,8 @@
(nth coll 1))
(defn some [pred coll]
"Return the first logical true value of (pred x) for any x in coll, else nil"
(first (filter nil (map pred coll))))
"Return the first logical true value of (pred x) for any x in coll, else None"
(first (filter None (map pred coll))))
(defn string [x]
"Cast x as current string implementation"
@ -389,7 +385,7 @@
(defn take [count coll]
"Take `count` elements from `coll`, or the whole set if the total
number of entries in `coll` is less than `count`."
(islice coll nil count))
(islice coll None count))
(defn take-nth [n coll]
"Return every nth member of coll
@ -412,7 +408,7 @@
"Read from input and returns a tokenized string.
Can take a given input buffer to read from"
(def buff "")
(while true
(while True
(def inn (str (.readline from-file)))
(if (= inn eof)
(raise (EOFError "Reached end of file" )))
@ -465,6 +461,6 @@
group-by identity inc input instance? integer integer? integer-char?
interleave interpose islice iterable? iterate iterator? keyword keyword?
last list* macroexpand macroexpand-1 map merge-with multicombinations name
neg? nil? none? nth numeric? odd? partition permutations pos? product range
neg? none? nth numeric? odd? partition permutations pos? product range
read read-str remove repeat repeatedly rest reduce second some string
string? symbol? take take-nth take-while xor tee zero? zip zip-longest])

View File

@ -78,7 +78,7 @@
(if baz
quux))"
(if (empty? branches)
nil
None
(do
(setv branches (iter branches))
(setv branch (next branches))
@ -124,8 +124,8 @@
(macro-error None "`for' requires a body to evaluate")]
[(empty? args) `(do ~@body ~@belse)]
[(= (len args) 2) `(for* [~@args] (do ~@body) ~@belse)]
[true
(let [alist (cut args 0 nil 2)]
[True
(let [alist (cut args 0 None 2)]
`(for* [(, ~@alist) (genexpr (, ~@alist) [~@args])] (do ~@body) ~@belse))]))
@ -175,19 +175,19 @@
(defmacro lif [&rest args]
"Like `if`, but anything that is not None/nil is considered true."
"Like `if`, but anything that is not None is considered true."
(setv n (len args))
(if* n
(if* (= n 1)
(get args 0)
`(if* (is-not ~(get args 0) nil)
`(if* (is-not ~(get args 0) None)
~(get args 1)
(lif ~@(cut args 2))))))
(defmacro lif-not [test not-branch &optional yes-branch]
"Like `if-not`, but anything that is not None/nil is considered true."
`(if* (is ~test nil) ~not-branch ~yes-branch))
"Like `if-not`, but anything that is not None is considered true."
`(if* (is ~test None) ~not-branch ~yes-branch))
(defmacro when [test &rest body]
@ -226,19 +226,19 @@
(defmacro/g! yield-from [expr]
`(do (import types)
(setv ~g!iter (iter ~expr))
(setv ~g!return nil)
(setv ~g!message nil)
(while true
(setv ~g!return None)
(setv ~g!message None)
(while True
(try (if (isinstance ~g!iter types.GeneratorType)
(setv ~g!message (yield (.send ~g!iter ~g!message)))
(setv ~g!message (yield (next ~g!iter))))
(except [~g!e StopIteration]
(do (setv ~g!return (if (hasattr ~g!e "value")
(. ~g!e value)
nil))
None))
(break)))))
~g!return))
nil)
None)
(defmacro defmain [args &rest body]
@ -254,6 +254,6 @@
(defreader @ [expr]
(let [decorators (cut expr nil -1)
(let [decorators (cut expr None -1)
fndef (get expr -1)]
`(with-decorator ~@decorators ~fndef)))

View File

@ -301,15 +301,6 @@ def t_identifier(p):
except ValueError:
pass
table = {
"true": "True",
"false": "False",
"nil": "None",
}
if obj in table:
return HySymbol(table[obj])
if obj.startswith(":"):
return HyKeyword(obj)

View File

@ -102,7 +102,7 @@ def test_ast_invalid_unary_op():
def test_ast_bad_while():
"Make sure AST can't compile invalid while"
cant_compile("(while)")
cant_compile("(while (true))")
cant_compile("(while (True))")
def test_ast_good_do():
@ -175,7 +175,7 @@ def test_ast_good_assert():
can_compile("(assert 1 \"Assert label\")")
can_compile("(assert 1 (+ \"spam \" \"eggs\"))")
can_compile("(assert 1 12345)")
can_compile("(assert 1 nil)")
can_compile("(assert 1 None)")
can_compile("(assert 1 (+ 2 \"incoming eggsception\"))")
@ -337,7 +337,7 @@ def test_ast_valid_let():
"Make sure AST can compile valid let"
can_compile("(let [a b])")
can_compile("(let [a 1])")
can_compile("(let [a 1 b nil])")
can_compile("(let [a 1 b None])")
def test_ast_invalid_let():
@ -571,7 +571,7 @@ def test_defn():
def test_setv_builtins():
"""Ensure that assigning to a builtin fails, unless in a class"""
cant_compile("(setv nil 42)")
cant_compile("(setv None 42)")
cant_compile("(defn get [&rest args] 42)")
can_compile("(defclass A [] (defn get [self] 42))")
can_compile("""

View File

@ -19,8 +19,8 @@
(defn t= [a b]
(and (= a b) (= (type a) (type b))))
(assert (t= (cons 1 2) '(1 . 2)))
(assert (t= (cons 1 nil) '(1)))
(assert (t= (cons nil 2) '(nil . 2)))
(assert (t= (cons 1 None) '(1)))
(assert (t= (cons None 2) '(None . 2)))
(assert (t= (cons 1 []) [1]))
(setv tree (cons (cons 1 2) (cons 2 3)))
(assert (t= (car tree) (cons 1 2)))
@ -52,7 +52,7 @@
(assert (cons? '(1 2 3 . 4)))
(assert (cons? (list* 1 2 3)))
(assert (not (cons? (cons 1 [2]))))
(assert (not (cons? (list* 1 nil)))))
(assert (not (cons? (list* 1 None)))))
(defn test-list* []

View File

@ -35,11 +35,11 @@
(defn test-ap-if []
"NATIVE: testing anaphoric if"
(ap-if true (assert-true it))
(ap-if false true (assert-false it))
(try (macroexpand '(ap-if true))
(except [HyMacroExpansionError] true)
(else (assert false))))
(ap-if True (assert-true it))
(ap-if False True (assert-false it))
(try (macroexpand '(ap-if True))
(except [HyMacroExpansionError] True)
(else (assert False))))
(defn test-ap-each []
"NATIVE: testing anaphoric each"

View File

@ -19,15 +19,15 @@
(try
(setv n (non-tco-sum 100 10000))
(except [e RuntimeError]
(assert true))
(assert True))
(else
(assert false)))
(assert False)))
;; tco-sum should not fail
(try
(setv n (tco-sum 100 10000))
(except [e RuntimeError]
(assert false))
(assert False))
(else
(assert (= n 10100)))))
@ -41,6 +41,6 @@
(try
(bad-recur 3)
(except [e TypeError]
(assert true))
(assert True))
(else
(assert false))))
(assert False))))

View File

@ -8,7 +8,7 @@
(defn collector [acc x]
(.append acc x)
nil)
None)
(defn test-walk-identity []
(assert (= (walk identity identity walk-form)
@ -17,11 +17,11 @@
(defn test-walk []
(let [acc '()]
(assert (= (walk (partial collector acc) identity walk-form)
[nil nil]))
[None None]))
(assert (= acc walk-form)))
(let [acc []]
(assert (= (walk identity (partial collector acc) walk-form)
nil))
None))
(assert (= acc [walk-form]))))
(defn test-walk-iterators []

View File

@ -32,8 +32,8 @@
(defn assert-equal [x y]
(assert (= x y)))
(defn assert-nil [x]
(assert (is x nil)))
(defn assert-none [x]
(assert (is x None)))
(defn assert-requires-num [f]
(for [x ["foo" [] None]]
@ -130,7 +130,7 @@
(setv res (list (drop 0 [1 2 3 4 5])))
(assert-equal res [1 2 3 4 5])
(try (do (list (drop -1 [1 2 3 4 5])) (assert False))
(except [e [ValueError]] nil))
(except [e [ValueError]] None))
(setv res (list (drop 6 (iter [1 2 3 4 5]))))
(assert-equal res [])
(setv res (list (take 5 (drop 2 (iterate inc 0)))))
@ -408,32 +408,23 @@
(assert-false (none? 0))
(assert-false (none? "")))
(defn test-nil? []
"NATIVE: testing for `is nil`"
(assert-true (nil? nil))
(assert-true (nil? None))
(setv f nil)
(assert-true (nil? f))
(assert-false (nil? 0))
(assert-false (nil? "")))
(defn test-nth []
"NATIVE: testing the nth function"
(assert-equal 2 (nth [1 2 4 7] 1))
(assert-equal 7 (nth [1 2 4 7] 3))
(assert-nil (nth [1 2 4 7] 5))
(assert-none (nth [1 2 4 7] 5))
(assert-equal (nth [1 2 4 7] 5 "some default value")
"some default value") ; with default specified
(try (do (nth [1 2 4 7] -1) (assert False))
(except [e [ValueError]] nil))
(except [e [ValueError]] None))
;; now for iterators
(assert-equal 2 (nth (iter [1 2 4 7]) 1))
(assert-equal 7 (nth (iter [1 2 4 7]) 3))
(assert-nil (nth (iter [1 2 4 7]) 5))
(assert-none (nth (iter [1 2 4 7]) 5))
(assert-equal (nth (iter [1 2 4 7]) 5 "some default value")
"some default value") ; with default specified
(try (do (nth (iter [1 2 4 7]) -1) (assert False))
(except [e [ValueError]] nil))
(except [e [ValueError]] None))
(assert-equal 5 (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2)))
(defn test-numeric? []
@ -518,16 +509,16 @@
(defn test-some []
"NATIVE: testing the some function"
(assert-true (some even? [2 4 6]))
(assert-nil (some even? [1 3 5]))
(assert-none (some even? [1 3 5]))
(assert-true (some even? [1 2 3]))
(assert-nil (some even? []))
(assert-none (some even? []))
; 0, "" (empty string) and [] (empty list) are all logical false
(assert-nil (some identity [0 "" []]))
(assert-none (some identity [0 "" []]))
; non-empty string is logical true
(assert-equal (some identity [0 "this string is non-empty" []])
"this string is non-empty")
; nil if collection is empty
(assert-nil (some even? [])))
; None if collection is empty
(assert-none (some even? [])))
(defn test-string? []
"NATIVE: testing string?"
@ -546,7 +537,7 @@
(setv res (list (take 0 (repeat "s"))))
(assert-equal res [])
(try (do (list (take -1 (repeat "s"))) (assert False))
(except [e [ValueError]] nil))
(except [e [ValueError]] None))
(setv res (list (take 6 [1 2 None 4])))
(assert-equal res [1 2 None 4]))
@ -570,10 +561,10 @@
(setv res (list (take-nth 3 [1 2 3 None 5 6])))
(assert-equal res [1 None])
;; using 0 should raise ValueError
(let [passed false]
(let [passed False]
(try
(setv res (list (take-nth 0 [1 2 3 4 5 6 7])))
(except [ValueError] (setv passed true)))
(except [ValueError] (setv passed True)))
(assert passed)))
(defn test-take-while []
@ -606,7 +597,7 @@
(assert (not (keyword? "foo")))
(assert (not (keyword? ":foo")))
(assert (not (keyword? 1)))
(assert (not (keyword? nil))))
(assert (not (keyword? None))))
(defn test-import-init-hy []
"NATIVE: testing import of __init__.hy"

View File

@ -43,10 +43,10 @@
(defn test-defclass-dynamic-inheritance []
"NATIVE: test defclass with dynamic inheritance"
(defclass A [((fn [] (if true list dict)))]
(defclass A [((fn [] (if True list dict)))]
[x 42])
(assert (isinstance (A) list))
(defclass A [((fn [] (if false list dict)))]
(defclass A [((fn [] (if False list dict)))]
[x 42])
(assert (isinstance (A) dict)))
@ -58,7 +58,7 @@
(try
(do
(x)
(assert false))
(assert False))
(except [NameError])))
(defn test-defclass-docstring []
@ -110,8 +110,8 @@
(assert foo 2)
(assert (.greet a) "hello"))
(defn test-defclass-implicit-nil-for-init []
"NATIVE: test that defclass adds an implicit nil to --init--"
(defn test-defclass-implicit-none-for-init []
"NATIVE: test that defclass adds an implicit None to --init--"
(defclass A []
[--init-- (fn [self] (setv self.x 1) 42)])
(defclass B []

View File

@ -53,7 +53,7 @@
(defn test-setv-empty []
"NATIVE: test setv works with no arguments"
(assert (is (setv) nil)))
(assert (is (setv) None)))
(defn test-setv-get []
@ -71,12 +71,6 @@
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv None 1))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv false 1))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv true 0))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv nil 1))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(defn defclass [] (print "hello")))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(defn get [] (print "hello")))
@ -101,28 +95,28 @@
(try
(do
(eval '(setv (do 1 2) 1))
(assert false))
(assert False))
(except [e HyTypeError]
(assert (= e.message "Can't assign or delete a non-expression"))))
(try
(do
(eval '(setv 1 1))
(assert false))
(assert False))
(except [e HyTypeError]
(assert (= e.message "Can't assign or delete a HyInteger"))))
(try
(do
(eval '(setv {1 2} 1))
(assert false))
(assert False))
(except [e HyTypeError]
(assert (= e.message "Can't assign or delete a HyDict"))))
(try
(do
(eval '(del 1 1))
(assert false))
(assert False))
(except [e HyTypeError]
(assert (= e.message "Can't assign or delete a HyInteger")))))
@ -224,8 +218,8 @@
(defn test-not []
"NATIVE: test not"
(assert (not (= 1 2)))
(assert (= true (not false)))
(assert (= false (not 42))) )
(assert (= True (not False)))
(assert (= False (not 42))) )
(defn test-inv []
@ -266,22 +260,22 @@
(defn test-is []
"NATIVE: test is can deal with None"
(setv a nil)
(assert (is a nil))
(setv a None)
(assert (is a None))
(assert (is-not a "b"))
(assert (none? a)))
(defn test-branching []
"NATIVE: test if branching"
(if true
(if True
(assert (= 1 1))
(assert (= 2 1))))
(defn test-branching-with-do []
"NATIVE: test if branching (multiline)"
(if false
(if False
(assert (= 2 1))
(do
(assert (= 1 1))
@ -291,7 +285,7 @@
(defn test-branching-expr-count-with-do []
"NATIVE: make sure we execute the right number of expressions in the branch"
(setv counter 0)
(if false
(if False
(assert (= 2 1))
(do
(setv counter (+ counter 1))
@ -303,9 +297,9 @@
(defn test-cond []
"NATIVE: test if cond sorta works."
(cond
[(= 1 2) (assert (is true false))]
[(is None None) (setv x true) (assert x)])
(assert (= (cond) nil)))
[(= 1 2) (assert (is True False))]
[(is None None) (setv x True) (assert x)])
(assert (= (cond) None)))
(defn test-if []
@ -314,18 +308,18 @@
(assert (= 1 (if 1)))
(assert (= 1 (if 0 -1
1)))
;; with an even number of args, the default is nil
(assert (is nil (if)))
(assert (is nil (if 0 1)))
;; with an even number of args, the default is None
(assert (is None (if)))
(assert (is None (if 0 1)))
;; test deeper nesting
(assert (= 42
(if 0 0
nil 1
None 1
"" 2
1 42
1 43)))
;; test shortcutting
(setv x nil)
(setv x None)
(if 0 (setv x 0)
"" (setv x "")
42 (setv x 42)
@ -359,9 +353,9 @@
(defn test-imported-bits []
"NATIVE: test the imports work"
(assert (is (exists ".") true))
(assert (is (isdir ".") true))
(assert (is (isfile ".") false)))
(assert (is (exists ".") True))
(assert (is (isdir ".") True))
(assert (is (isfile ".") False)))
(defn test-kwargs []
@ -432,7 +426,7 @@
(defn test-bare-try [] (try
(try (raise ValueError))
(except [ValueError])
(else (assert false))))
(else (assert False))))
(defn test-exceptions []
@ -449,70 +443,70 @@
(try (do) (except [IOError]) (except))
;; Test correct (raise)
(let [passed false]
(let [passed False]
(try
(try
(raise IndexError)
(except [IndexError] (raise)))
(except [IndexError]
(setv passed true)))
(setv passed True)))
(assert passed))
;; Test incorrect (raise)
(let [passed false]
(let [passed False]
(try
(raise)
;; Python 2 raises TypeError
;; Python 3 raises RuntimeError
(except [[TypeError RuntimeError]]
(setv passed true)))
(setv passed True)))
(assert passed))
;; Test (finally)
(let [passed false]
(let [passed False]
(try
(do)
(finally (setv passed true)))
(finally (setv passed True)))
(assert passed))
;; Test (finally) + (raise)
(let [passed false]
(let [passed False]
(try
(raise Exception)
(except)
(finally (setv passed true)))
(finally (setv passed True)))
(assert passed))
;; Test (finally) + (raise) + (else)
(let [passed false
not-elsed true]
(let [passed False
not-elsed True]
(try
(raise Exception)
(except)
(else (setv not-elsed false))
(finally (setv passed true)))
(else (setv not-elsed False))
(finally (setv passed True)))
(assert passed)
(assert not-elsed))
(try
(raise (KeyError))
(except [[IOError]] (assert false))
(except [[IOError]] (assert False))
(except [e [KeyError]] (assert e)))
(try
(raise (KeyError))
(except [[IOError]] (assert false))
(except [[IOError]] (assert False))
(except [e [KeyError]] (assert e)))
(try
(get [1] 3)
(except [IndexError] (assert true))
(except [IndexError] (assert True))
(except [IndexError] (do)))
(try
(print foobar42ofthebaz)
(except [IndexError] (assert false))
(except [IndexError] (assert False))
(except [NameError] (do)))
(try
@ -553,10 +547,10 @@
(setv foobar42ofthebaz 42)
(assert (= foobar42ofthebaz 42))))
(let [passed false]
(let [passed False]
(try
(try (do) (except) (else (bla)))
(except [NameError] (setv passed true)))
(except [NameError] (setv passed True)))
(assert passed))
(let [x 0]
@ -648,7 +642,7 @@
(defn test-pass []
"NATIVE: Test pass worksish"
(if true (do) (do))
(if True (do) (do))
(assert (= 1 1)))
@ -687,7 +681,7 @@
(defn test-first []
"NATIVE: test firsty things"
(assert (= (first [1 2 3 4 5]) 1))
(assert (is (first []) nil))
(assert (is (first []) None))
(assert (= (car [1 2 3 4 5]) 1)))
@ -868,18 +862,18 @@
"NATIVE: test let works rightish"
;; TODO: test sad paths for let
(assert (= (let [x 1 y 2 z 3] (+ x y z)) 6))
(assert (= (let [x 1 a nil y 2 b nil] (if a 1 2)) 2))
(assert (= (let [x nil] x) nil))
(assert (= (let [x 1 a None y 2 b None] (if a 1 2)) 2))
(assert (= (let [x None] x) None))
(assert (= (let [x "x not bound"] (setv x "x bound by setv") x)
"x bound by setv"))
(assert (= (let [x "let nests scope correctly"]
(let [y nil] x))
(let [y None] x))
"let nests scope correctly"))
(assert (= (let [x 999999]
(let [x "x being rebound"] x))
"x being rebound"))
(assert (= (let [x "x not being rebound"]
(let [x 2] nil)
(let [x 2] None)
x)
"x not being rebound"))
(assert (= (let [x (set [3 2 1 3 2]) y x z y] z) (set [1 2 3])))
@ -897,7 +891,7 @@
(defn test-if-mangler []
"NATIVE: test that we return ifs"
(assert (= true (if true true true))))
(assert (= True (if True True True))))
(defn test-nested-mangles []
@ -966,7 +960,7 @@
(assert (= or-all-true 1))
(assert (= or-some-true "hello"))
(assert (= or-none-true False))
(assert (= or-false nil))
(assert (= or-false None))
(assert (= or-single 1)))
; short circuiting
(setv a 1)
@ -976,19 +970,19 @@
(defn test-xor []
"NATIVE: test the xor macro"
(let [xor-both-true (xor true true)
xor-both-false (xor false false)
xor-true-false (xor true false)]
(assert (= xor-both-true false))
(assert (= xor-both-false false))
(assert (= xor-true-false true))))
(let [xor-both-true (xor True True)
xor-both-false (xor False False)
xor-true-false (xor True False)]
(assert (= xor-both-true False))
(assert (= xor-both-false False))
(assert (= xor-true-false True))))
(defn test-if-return-branching []
"NATIVE: test the if return branching"
; thanks, algernon
(assert (= 1 (let [x 1
y 2]
(if true
(if True
2)
1)))
(assert (= 1 (let [x 1 y 2]
@ -1015,9 +1009,9 @@
(for [x (range 10)]
(if (in "foo" "foobar")
(do
(if true true true))
(if True True True))
(do
(if false false false)))))
(if False False False)))))
(defn test-eval []
@ -1057,8 +1051,8 @@
; yo dawg
(try (eval '(eval)) (except [e HyTypeError]) (else (assert False)))
(try (eval '(eval "snafu")) (except [e HyTypeError]) (else (assert False)))
(try (eval 'false []) (except [e HyTypeError]) (else (assert False)))
(try (eval 'false {} 1) (except [e HyTypeError]) (else (assert False))))
(try (eval 'False []) (except [e HyTypeError]) (else (assert False)))
(try (eval 'False {} 1) (except [e HyTypeError]) (else (assert False))))
(defn test-import-syntax []
@ -1122,7 +1116,7 @@
(defn test-if-let-mixing []
"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 []
"NATIVE: test that we can use if in if"
@ -1261,7 +1255,7 @@
(assert (= test [0 1 2 3]))
(del (get test 2))
(assert (= test [0 1 3]))
(assert (= (del) nil)))
(assert (= (del) None)))
(defn test-macroexpand []
@ -1279,7 +1273,7 @@
(defn test-merge-with []
"NATIVE: test merge-with"
(assert (= (merge-with + {} {}) nil))
(assert (= (merge-with + {} {}) None))
(assert (= (merge-with + {"a" 10 "b" 20} {}) {"a" 10 "b" 20}))
(assert (= (merge-with + {} {"a" 10 "b" 20}) {"a" 10 "b" 20}))
(assert (= (merge-with + {"a" 10 "b" 20} {"a" 1 "c" 30})
@ -1309,7 +1303,7 @@
"Module(\n body=[Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[])),\n Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[])),\n Expr(value=Call(func=Name(id='macros'), args=[], keywords=[]))])"))
(assert (= (disassemble '(do (leaky) (leaky) (macros)))
"Module(\n body=[\n Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[], starargs=None, kwargs=None)),\n Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[], starargs=None, kwargs=None)),\n Expr(value=Call(func=Name(id='macros'), args=[], keywords=[], starargs=None, kwargs=None))])")))
(assert (= (disassemble '(do (leaky) (leaky) (macros)) true)
(assert (= (disassemble '(do (leaky) (leaky) (macros)) True)
"leaky()\nleaky()\nmacros()")))

View File

@ -59,19 +59,19 @@
(eval '(defmacro f [&kwonly a b]))
(except [e HyTypeError]
(assert (= e.message "macros cannot use &kwonly")))
(else (assert false)))
(else (assert False)))
(try
(eval '(defmacro f [&kwargs kw]))
(except [e HyTypeError]
(assert (= e.message "macros cannot use &kwargs")))
(else (assert false)))
(else (assert False)))
(try
(eval '(defmacro f [&key {"kw" "xyz"}]))
(except [e HyTypeError]
(assert (= e.message "macros cannot use &key")))
(else (assert false))))
(else (assert False))))
(defn test-fn-calling-macro []
"NATIVE: test macro calling a plain function"
@ -208,16 +208,15 @@
:no))
(assert (= (if-not False :yes :no)
:yes))
(assert (nil? (if-not True :yes)))
(assert (none? (if-not True :yes)))
(assert (= (if-not False :yes)
:yes)))
(defn test-lif []
"test that lif works as expected"
;; nil is false
;; None is false
(assert (= (lif None "true" "false") "false"))
(assert (= (lif nil "true" "false") "false"))
;; But everything else is True! Even falsey things.
(assert (= (lif True "true" "false") "true"))
@ -226,21 +225,20 @@
(assert (= (lif "some-string" "true" "false") "true"))
(assert (= (lif "" "true" "false") "true"))
(assert (= (lif (+ 1 2 3) "true" "false") "true"))
(assert (= (lif nil "true" "false") "false"))
(assert (= (lif None "true" "false") "false"))
(assert (= (lif 0 "true" "false") "true"))
;; Test ellif [sic]
(assert (= (lif nil 0
nil 1
(assert (= (lif None 0
None 1
0 2
3)
2)))
(defn test-lif-not []
"test that lif-not works as expected"
; nil is false
; None is false
(assert (= (lif-not None "false" "true") "false"))
(assert (= (lif-not nil "false" "true") "false"))
; But everything else is True! Even falsey things.
(assert (= (lif-not True "false" "true") "true"))
@ -249,7 +247,7 @@
(assert (= (lif-not "some-string" "false" "true") "true"))
(assert (= (lif-not "" "false" "true") "true"))
(assert (= (lif-not (+ 1 2 3) "false" "true") "true"))
(assert (= (lif-not nil "false" "true") "false"))
(assert (= (lif-not None "false" "true") "false"))
(assert (= (lif-not 0 "false" "true") "true")))

View File

@ -15,9 +15,9 @@
(defn test-kwonly []
"NATIVE: test keyword-only arguments"
;; keyword-only with default works
(let [kwonly-foo-default-false (fn [&kwonly [foo false]] foo)]
(assert (= (apply kwonly-foo-default-false) false))
(assert (= (apply kwonly-foo-default-false [] {"foo" true}) true)))
(let [kwonly-foo-default-false (fn [&kwonly [foo False]] foo)]
(assert (= (apply kwonly-foo-default-false) False))
(assert (= (apply kwonly-foo-default-false [] {"foo" True}) True)))
;; keyword-only without default ...
(let [kwonly-foo-no-default (fn [&kwonly foo] foo)
attempt-to-omit-default (try

View File

@ -10,9 +10,9 @@
(defn test-quoted-hoistable []
"NATIVE: check whether quote works on hoisted things"
(setv f (quote (if true true true)))
(setv f (quote (if True True True)))
(assert (= (car f) (quote if)))
(assert (= (cdr f) (quote (true true true)))))
(assert (= (cdr f) (quote (True True True)))))
(defn test-quoted-macroexpand []

View File

@ -1,10 +1,8 @@
(defn test-unless []
"NATIVE: test unless"
(assert (= (unless false 1) 1))
(assert (= (unless false 1 2) 2))
(assert (= (unless false 1 3) 3))
(assert (= (unless true 2) None))
(assert (= (unless true 2) nil))
(assert (= (unless False 1) 1))
(assert (= (unless False 1 2) 2))
(assert (= (unless False 1 3) 3))
(assert (= (unless True 2) None))
(assert (= (unless (!= 1 2) 42) None))
(assert (= (unless (!= 1 2) 42) nil))
(assert (= (unless (!= 2 2) 42) 42)))

View File

@ -1,10 +1,8 @@
(defn test-when []
"NATIVE: test when"
(assert (= (when true 1) 1))
(assert (= (when true 1 2) 2))
(assert (= (when true 1 3) 3))
(assert (= (when false 2) None))
(assert (= (when True 1) 1))
(assert (= (when True 1 2) 2))
(assert (= (when True 1 3) 3))
(assert (= (when False 2) None))
(assert (= (when (= 1 2) 42) None))
(assert (= (when false 2) nil))
(assert (= (when (= 1 2) 42) nil))
(assert (= (when (= 2 2) 42) 42)))