proc closure {env params body} {
set ns [uplevel 1 { namespace current }]
set body [list with __scope__ $body]
set lambda [list $params $body $ns]
return [list $env $lambda]
}
proc with {scopeVar body} {
uplevel 1 [list upvar 1 $scopeVar __scope__]
uplevel 1 [list dict with __scope__ $body]
}
proc applyc {closureVar args} {
upvar 1 $closureVar closure
lassign $closure __scope__ lambda
try { apply $lambda {*}$args } on ok result { set closure [list $__scope__ $lambda]; return $result }
}
proc invokec {args} {
uplevel 1 {*}$args
}
set counter [closure {i 0} {{n 1}} { incr i $n }]
puts [applyc counter]
puts [applyc counter 3]
proc test {} {
return [list applyc counter 2]
}
puts [invokec [test]]
cHJvYyBjbG9zdXJlIHtlbnYgcGFyYW1zIGJvZHl9IHsKICAgIHNldCBucyBbdXBsZXZlbCAxIHsgbmFtZXNwYWNlIGN1cnJlbnQgfV0KICAgIHNldCBib2R5IFtsaXN0IHdpdGggX19zY29wZV9fICRib2R5XQogICAgc2V0IGxhbWJkYSBbbGlzdCAkcGFyYW1zICRib2R5ICRuc10KICAgIHJldHVybiBbbGlzdCAkZW52ICRsYW1iZGFdCn0KcHJvYyB3aXRoIHtzY29wZVZhciBib2R5fSB7CiAgICB1cGxldmVsIDEgW2xpc3QgdXB2YXIgMSAkc2NvcGVWYXIgX19zY29wZV9fXQogICAgdXBsZXZlbCAxIFtsaXN0IGRpY3Qgd2l0aCBfX3Njb3BlX18gJGJvZHldCn0KcHJvYyBhcHBseWMge2Nsb3N1cmVWYXIgYXJnc30gewogICAgdXB2YXIgMSAkY2xvc3VyZVZhciBjbG9zdXJlCiAgICBsYXNzaWduICRjbG9zdXJlIF9fc2NvcGVfXyBsYW1iZGEKICAgIHRyeSB7IGFwcGx5ICRsYW1iZGEgeyp9JGFyZ3MgfSBvbiBvayByZXN1bHQgeyBzZXQgY2xvc3VyZSBbbGlzdCAkX19zY29wZV9fICRsYW1iZGFdOyByZXR1cm4gJHJlc3VsdCB9Cn0KcHJvYyBpbnZva2VjIHthcmdzfSB7Cgl1cGxldmVsIDEgeyp9JGFyZ3MKfQpzZXQgY291bnRlciBbY2xvc3VyZSB7aSAwfSB7e24gMX19IHsgaW5jciBpICRuIH1dCgpwdXRzIFthcHBseWMgY291bnRlcl0KcHV0cyBbYXBwbHljIGNvdW50ZXIgM10KCnByb2MgdGVzdCB7fSB7CglyZXR1cm4gW2xpc3QgYXBwbHljIGNvdW50ZXIgMl0KfQoKcHV0cyBbaW52b2tlYyBbdGVzdF1d