Skip to content

Commit f772df4

Browse files
committed
improve example
1 parent 56368db commit f772df4

1 file changed

Lines changed: 41 additions & 19 deletions

File tree

unpythonic/syntax/tests/test_conts.py

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -832,45 +832,67 @@ def f():
832832
# k2, x = k1(None) # multi-shotting from earlier resume point
833833
# test[x == "cont 2 first time"]
834834

835-
# If you need to scope like `nonlocal`, use the classic solution: box the value
836-
# to avoid the need to overwrite the name.
835+
# If you need to scope like `nonlocal`, use the classic solution: box the value,
836+
# so you have no need to overwrite the name; you can replace the thing in the box.
837837
#
838838
# (Classic from before `nonlocal` declarations were a thing. They were added in 3.0;
839839
# for historical interest, see https://www.python.org/dev/peps/pep-3104/ )
840840
with testset("scoping, using a box"):
841-
# TODO: better example
842841
with continuations:
843-
def f():
844-
# original function scope
845-
x = box(None)
842+
# poor man's execution trace
843+
def make_tracing_box_updater(thebox, trace):
844+
def update(value):
845+
trace.append(f"old: {unbox(thebox)}")
846+
thebox << value
847+
trace.append(f"new: {unbox(thebox)}")
848+
return value
849+
return update
850+
851+
# If we wanted to replace the list instance later, we could pass the list in a box, too.
852+
def f(lst):
853+
# Now there is just one `x`, which is the box; we just update the contents.
854+
# Original function scope
855+
x = box("f")
856+
lst.append(f"initial: {unbox(x)}")
857+
update = make_tracing_box_updater(x, lst)
846858

847-
# continuation 1 scope begins here
859+
# Continuation 1 scope begins here
848860
# (from the statement following `call_cc` onward, but including the `k1`)
849861
k1 = call_cc[get_cc()]
850862
if iscontinuation(k1):
851-
# Now there is just one `x`, which is the box; we just update the contents.
852-
x << "cont 1 first time"
853-
return k1, unbox(x)
863+
return k1, update("k1 first")
864+
update("k1 again")
854865

855-
# continuation 2 scope begins here
866+
# Continuation 2 scope begins here
856867
k2 = call_cc[get_cc()]
857868
if iscontinuation(k2):
858-
x << "cont 2 first time"
859-
return k2, unbox(x)
869+
return k2, update("k2 first")
870+
update("k2 again")
860871

861-
x << "cont 2 second time"
862872
return None, unbox(x)
863873

864-
k1, x = f()
865-
test[x == "cont 1 first time"]
874+
trace = []
875+
k1, x = f(trace)
876+
test[x == "k1 first"]
877+
test[trace == ['initial: f', 'old: f', 'new: k1 first']]
866878
k2, x = k1(None) # when resuming, send `None` as the new value of variable `k1` in continuation 1
867-
test[x == "cont 2 first time"]
879+
test[x == "k2 first"]
880+
test[trace == ['initial: f', 'old: f', 'new: k1 first',
881+
'old: k1 first', 'new: k1 again', 'old: k1 again', 'new: k2 first']]
868882
k3, x = k2(None)
869883
test[k3 is None]
870-
test[x == "cont 2 second time"]
884+
test[x == "k2 again"]
885+
test[trace == ['initial: f', 'old: f', 'new: k1 first',
886+
'old: k1 first', 'new: k1 again', 'old: k1 again', 'new: k2 first',
887+
'old: k2 first', 'new: k2 again']]
871888

872889
k2, x = k1(None) # multi-shotting from earlier resume point
873-
test[x == "cont 2 first time"]
890+
test[x == "k2 first"]
891+
test[trace == ['initial: f', 'old: f', 'new: k1 first',
892+
'old: k1 first', 'new: k1 again', 'old: k1 again', 'new: k2 first',
893+
'old: k2 first', 'new: k2 again',
894+
'old: k2 again', 'new: k1 again', 'old: k1 again', 'new: k2 first']]
895+
# ^^^^^^^^^^^^^^^ state as left by `k2` before the multi-shot
874896

875897
if __name__ == '__main__': # pragma: no cover
876898
with session(__file__):

0 commit comments

Comments
 (0)