back let
with dict for better defclass behavior
This commit is contained in:
parent
3707681056
commit
e90f082baf
@ -224,10 +224,6 @@ Arguments in nested functions and bindings in nested ``let`` forms can shadow th
|
||||
6
|
||||
5
|
||||
|
||||
The ``global`` special form changes the meaning of names to refer to the
|
||||
module-level variables instead of locals, and this change still applies inside a ``let`` form,
|
||||
even if a global has the same name as a let binding.
|
||||
|
||||
Basic assignments (e.g. ``setv``, ``+=``) will update the local variable named by a let binding,
|
||||
when they assign to a let-bound name.
|
||||
|
||||
@ -238,9 +234,6 @@ even if it shares the name of a let binding.
|
||||
Use ``__import__`` and ``type`` (or whatever metaclass) instead,
|
||||
if you must avoid this hoisting.
|
||||
|
||||
When used in a nested function,
|
||||
nonlocal assignments to let-bound variables still require a ``nonlocal`` form.
|
||||
|
||||
The ``let`` macro takes two parameters: a list defining *variables*
|
||||
and the *body* which gets executed. *variables* is a vector of
|
||||
variable and value pairs.
|
||||
@ -254,4 +247,4 @@ variable and value pairs.
|
||||
... (print x y))
|
||||
5 6
|
||||
|
||||
|
||||
It is an error to use a let-bound name in a ``global`` or ``nonlocal`` form.
|
||||
|
@ -74,6 +74,7 @@
|
||||
(expand form))
|
||||
|
||||
;; TODO: move to hy.extra.reserved?
|
||||
(import hy)
|
||||
(setv special-forms (list-comp k
|
||||
[k (.keys hy.compiler._compile-table)]
|
||||
(isinstance k hy._compat.string-types)))
|
||||
@ -246,10 +247,9 @@ Arguments without a header are under None.
|
||||
(defn handle-call [self]
|
||||
(setv head (first self.form))
|
||||
(if (in head '[fn fn*]) (self.handle-fn)
|
||||
(in head '[import quote]) (self.handle-base)
|
||||
(in head '[import require quote]) (self.handle-base)
|
||||
(= head 'except) (self.handle-except)
|
||||
(= head ".") (self.handle-dot)
|
||||
(= head 'global) (self.handle-global)
|
||||
(= head 'defclass) (self.handle-defclass)
|
||||
(= head 'quasiquote) (self.+quote)
|
||||
;; must be checked last!
|
||||
@ -320,9 +320,10 @@ as can nested let forms.
|
||||
(if (in '. k)
|
||||
(macro-error k "binding target may not contain a dot")))
|
||||
(.append values (symbolexpand (macroexpand-all v &name) expander))
|
||||
(assoc replacements k (HySymbol (+ g!let "::" k))))
|
||||
(assoc replacements k `(get ~g!let ~(name k))))
|
||||
`(do
|
||||
(setv ~@(interleave (.values replacements) values))
|
||||
(setv ~g!let {}
|
||||
~@(interleave (.values replacements) values))
|
||||
~@(symbolexpand (macroexpand-all body &name) expander)))
|
||||
|
||||
;; (defmacro macrolet [])
|
||||
|
@ -158,8 +158,8 @@
|
||||
(do
|
||||
foo
|
||||
(assert False))
|
||||
(except [ne NameError]
|
||||
(setv error ne)))
|
||||
(except [le LookupError]
|
||||
(setv error le)))
|
||||
(setv foo 16)
|
||||
(assert (= foo 16))
|
||||
(setv [foo bar baz] [1 2 3])
|
||||
@ -217,7 +217,10 @@
|
||||
;; the name of the class is just a symbol, even if it's a let binding
|
||||
(defclass Foo [quux] ; let bindings apply in inheritance list
|
||||
;; let bindings apply inside class body
|
||||
(setv x Foo)))
|
||||
(setv x Foo)
|
||||
;; quux is not local
|
||||
(setv quux "quux"))
|
||||
(assert (= quux "quux")))
|
||||
;; defclass always creates a python-scoped variable, even if it's a let binding name
|
||||
(assert (= Foo.x 42)))
|
||||
|
||||
@ -307,33 +310,15 @@
|
||||
(, 1 6 2)))))
|
||||
|
||||
(defn test-let-closure []
|
||||
(let [count [0]]
|
||||
(let [count 0]
|
||||
(defn +count [&optional [x 1]]
|
||||
(+= (get count 0) x)
|
||||
(get count 0)))
|
||||
(+= count x)
|
||||
count))
|
||||
;; let bindings can still exist outside of a let body
|
||||
(assert (= 1 (+count)))
|
||||
(assert (= 2 (+count)))
|
||||
(assert (= 42 (+count 40))))
|
||||
|
||||
(defn test-let-global []
|
||||
(setv (get (globals)
|
||||
'let-global)
|
||||
"global")
|
||||
(let [let-global 1]
|
||||
(assert (= let-global 1))
|
||||
(defn foo []
|
||||
(assert (= let-global 1))
|
||||
(global let-global)
|
||||
(assert (= let-global "global"))
|
||||
(setv let-global "mutated")
|
||||
(assert (= let-global "mutated")))
|
||||
(foo)
|
||||
(assert (= let-global 1))
|
||||
(assert (= (get (globals)
|
||||
'let-global)
|
||||
"mutated"))))
|
||||
|
||||
(defmacro triple [a]
|
||||
(setv g!a (gensym a))
|
||||
`(do
|
||||
@ -353,4 +338,3 @@
|
||||
3))
|
||||
(assert (= b 3))
|
||||
(assert (= c 3))))
|
||||
|
||||
|
@ -72,19 +72,6 @@
|
||||
(assert (= (list (yield-from-test)) [0 1 2 1 2 3 4])))
|
||||
|
||||
(require [hy.contrib.walk [let]])
|
||||
(defn test-let-nonlocal []
|
||||
(let [a 88
|
||||
c 64]
|
||||
(defn foo [a b]
|
||||
(nonlocal c)
|
||||
(-= a 1)
|
||||
(-= c 1)
|
||||
(, a b c))
|
||||
(assert (= a 88))
|
||||
(assert (= (foo 1 2)
|
||||
(, 0 2 63)))
|
||||
(assert (= c 63))
|
||||
(assert (= a 88))))
|
||||
|
||||
(defn test-let-optional []
|
||||
(let [a 1
|
||||
|
Loading…
Reference in New Issue
Block a user