Skip to content

Commit 52a6082

Browse files
committed
simplify implementation of do[]
1 parent 2ba12aa commit 52a6082

File tree

2 files changed

+8
-19
lines changed

2 files changed

+8
-19
lines changed

unpythonic/env.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ def set(self, name, value):
135135
"""
136136
if name not in self: # allow only rebinding
137137
raise AttributeError("name '{:s}' is not defined".format(name))
138+
return self._set(name, value)
139+
140+
# for co-operation with the do[] macro: internal function with no already-defined check.
141+
def _set(self, name, value):
138142
setattr(self, name, value)
139143
return value # for convenience
140144

unpythonic/syntax/letdo.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,15 @@
1515
BinOp, LShift, \
1616
FunctionDef, Return, \
1717
arguments, arg, \
18-
Load, \
19-
copy_location
18+
Load
2019
from .astcompat import AsyncFunctionDef
2120

2221
from macropy.core.quotes import macros, q, u, ast_literal, name
2322
from macropy.core.hquotes import macros, hq
2423
from macropy.core.walkers import Walker
2524

2625
from ..lispylet import let as letf, letrec as letrecf, _dlet as dletf, _blet as bletf
27-
from ..seq import begin as beginf, do as dof
26+
from ..seq import do as dof
2827
from ..dynassign import dyn
2928

3029
from .scoping import scoped_walker
@@ -243,29 +242,15 @@ def _dletseqimpl(bindings, fdef, kind):
243242
return _dletseqimpl(rest, outer, kind)
244243

245244
# -----------------------------------------------------------------------------
246-
# Imperative code in expresssion position. Uses the "let" machinery.
245+
# Imperative code in expression position. Uses the "let" machinery.
247246

248247
def do(tree):
249248
if type(tree) not in (Tuple, List):
250249
assert False, "do body: expected a sequence of comma-separated expressions"
251250

252251
gen_sym = dyn.gen_sym
253252
e = gen_sym("e")
254-
# We must use env.__setattr__ to allow defining new names; env.set only rebinds.
255-
# But to keep assignments chainable, the assignment must return the value.
256-
# Use a let[] to avoid recomputing it (could be expensive and/or have side effects).
257-
# So we need:
258-
# lambda k, expr: let((v, expr))[begin(e.__setattr__(k, v), v)]
259-
# ...but with gensym'd arg names to avoid spurious shadowing inside expr.
260-
# TODO: cache the setter in e? Or even provide a new method in env that does this?
261-
sa = Attribute(value=q[name[e]], attr="__setattr__", ctx=Load())
262-
k = gen_sym("k")
263-
expr = gen_sym("expr")
264-
envset = q[lambda: None]
265-
envset.args.args = [arg(arg=k), arg(arg=expr)]
266-
letbody = hq[beginf(ast_literal[sa](name[k], name["v"]), name["v"])]
267-
letbody = copy_location(letbody, tree)
268-
envset.body = let([q[(name["v"], name[expr])]], letbody)
253+
envset = Attribute(value=q[name[e]], attr="_set", ctx=Load()) # use internal _set to allow new definitions
269254

270255
def islocaldef(tree):
271256
return type(tree) is Call and type(tree.func) is Name and tree.func.id == "local"

0 commit comments

Comments
 (0)