{"id":6,"date":"2008-06-07T19:52:01","date_gmt":"2008-06-08T02:52:01","guid":{"rendered":"http:\/\/cogblog.mirandabanda.org\/?p=4"},"modified":"2017-03-09T13:16:46","modified_gmt":"2017-03-09T21:16:46","slug":"closures-part-i","status":"publish","type":"post","link":"http:\/\/www.mirandabanda.org\/cogblog\/2008\/06\/07\/closures-part-i\/","title":{"rendered":"Closures Part I"},"content":{"rendered":"<p><a href=\"http:\/\/www.mirandabanda.org\/bluebook\/bluebook_chapter26.html#BlockContexts26\">BlueBook BlockContexts<\/a> are nearly closures.\u00c2\u00a0 They close-over their enclosing environment, providing access to an enclosing method&#8217;s arguments and temporary variables.\u00c2\u00a0 But they lack their own local environment, hijacking their method activation&#8217;s (or home context&#8217;s) temps to store their own arguments and temporaries (let&#8217;s call these locals).\u00c2\u00a0 Worse still, they&#8217;re not reentrant. \u00c2\u00a0BTW, &#8220;the home context&#8221; is the terminology for the activation record of a method. \u00c2\u00a0All blocks get created within some method activation (or within a block activation nested within a method activation). \u00c2\u00a0The method activation in which a block is created is called the block&#8217;s home context.<\/p>\n<p>Try the following in <a href=\"http:\/\/www.squeak.org\/Download\">Squeak<\/a> prior to Squeak 4.x, and in <a href=\"http:\/\/www.cincomsmalltalk.com\/userblogs\/cincom\/blogView?content=smalltalk\">VisualWorks<\/a>:<\/p>\n<p><body><font face=\"serif\">\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| factorial |<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factorial := [:n| n = 1 ifTrue: [1] ifFalse: [(factorial value: n &#8211; 1) * n]].<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1 to: 10) collect: factorial<\/font><BR><\/body><br \/>\nIn VisualWorks you get #(1 2 6 24 120 720 5040 40320 362880 3628800).\u00c2\u00a0 In Squeak you get a Notifier proclaiming &#8220;Error: Attempt to evaluate a block that is already being evaluated.&#8221;\u00c2\u00a0 The Squeak code fails because in a Blue Book VM an unevaluated block is an activation record, a BlockContext, that has a sender field used to refer to the block&#8217;s caller.\u00c2\u00a0 You can inspect or explore the block to see it.\u00c2\u00a0 Here&#8217;s an explorer on it:<\/p>\n<p><img loading=\"lazy\" style=\"vertical-align: middle;\" src=\"http:\/\/mirandabanda.org\/images\/factblock080607.jpeg\" alt=\"\" width=\"551\" height=\"275\" \/><\/p>\n<p>You can see the block is referrered to from the first temporary of the home context &#8220;| factorial |&#8221;.\u00c2\u00a0 You can see its sender field which is used to refer to the calling context, the context that sends value: to the block to evaluate it. The block can&#8217;t be reentered without overwriting the sender field, preventing return to the first caller.<\/p>\n<p>OK, let&#8217;s deal with the reentrancy problem.\u00c2\u00a0 Simply evaluating a copy of the block instead of the original produces a fresh activation record for each activation of the block.\u00c2\u00a0 This is what Allen Wirfs-Brock&#8217;s team did in the Tektronix implementation on the 4404 back in the &#8217;80&#8217;s.\u00c2\u00a0 They modified the BlockContext&gt;&gt;value[:value:&#8230;] primitives to activate a copy of the receiver.\u00c2\u00a0 Let&#8217;s try modifying the example with explicit copies:<\/p>\n<p><body><font face=\"serif\">\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| factorial |<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factorial := [:n| n = 1 ifTrue: [1] ifFalse: [(factorial copy value: n &#8211; 1) * n]].<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1 to: 10) collect: factorial copy #(1 1 1 1 1 1 1 1 1 1)<\/font><BR><\/body><br \/>\nwhich answers&#8230; #(1 1 1 1 1 1 1 1 1 1) <strong>?!?!<\/strong><\/p>\n<p>That&#8217;s because the above is actually compiled to code equivalent to<\/p>\n<p><body><font face=\"serif\">\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| factorial n |<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factorial := [:factorialsArgument|<br \/>\n   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n := factorialsArgument.<br \/>\n   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n = 1 ifTrue: [1] ifFalse: [(factorial copy value: n &#8211; 1) * n]].<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1 to: 10) collect: factorial copy<\/font><BR><\/body><br \/>\nbecause with BlueBook BlockContexts all temporaries are stored in the temporary frame of the home context.\u00c2\u00a0 In the explorer above the &#8220;2: nil&#8221; field in the home context is the slot used to store the block&#8217;s argument &#8220;:n|&#8221;.<\/p>\n<p>By the time we&#8217;ve recursed to the base case with n = 1 we&#8217;ve overwritten n with 1 in all the &#8221; * n&#8221;&#8216;s, and so end up evaluating 1 * 1 * 1 &#8230;.<\/p>\n<p>This way round works as intended:<\/p>\n<p><body><font face=\"serif\">\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| factorial n |<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factorial := [:factorialsArgument|<br \/>\n   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n := factorialsArgument.<br \/>\n   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n = 1 ifTrue: [1] ifFalse: [n * (factorial copy value: n &#8211; 1)]].<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1 to: 10) collect: factorial copy<\/font><BR><\/body><br \/>\nanswers #(1 2 6 24 120 720 5040 40320 362880 3628800), because in &#8220;n * (factorial copy value: n &#8211; 1)&#8221; n is pushed on the stack before the recursion due to Smalltalk&#8217;s strict left-to-right evaluation rule.<\/p>\n<p>Whether you think this is a big deal or not its not ANSI-compliant so we&#8217;ve got to fix it right? \u00c2\u00a0I&#8217;m all for standards, and for me not having closures is an issue.\u00c2\u00a0 It gets in the way of self-expression. \u00c2\u00a0It is useful to have recursive blocks.\u00c2\u00a0 And with Smalltalk&#8217;s system building machinery it is easy to fix. \u00c2\u00a0But its not a huge issue; Squeak has done without closures for thirty years. \u00c2\u00a0However,\u00c2\u00a0there are also pragmatic reasons for fixing this. \u00c2\u00a0Closures are an enabler for efficient implementation of context-to-stack mapping, something to be explained in an upcoming post, which will speed-up the interpreter as well as the fast VM.\u00c2\u00a0 In fact so effective is the form of this optimization that I plan to implement that when I reimplemented VisualWorks&#8217; closures using it execution of block-intensive code such as exception handling sped up by a factor of two. \u00c2\u00a0These specifics are why I chose to do my own closure implementation instead of reusing <a href=\"http:\/\/wiki.squeak.org\/squeak\/2981\">Anthony Hannan&#8217;s one<\/a>.<\/p>\n<h3><strong>Implementing Closures<\/strong><\/h3>\n<p>Implementing closures is straight-forward.\u00c2\u00a0 We need three things.\u00c2\u00a0 One is to defer creating the activation of the block until we send value:.\u00c2\u00a0 So creating the block results in creating something, a BlockClosure, from which we can create an activation later on.\u00c2\u00a0 Another is the ability for a block activation to hold local arguments and temporaries.\u00c2\u00a0 We already have something that can do this, its called MethodContext :).\u00c2\u00a0 Finally we need a way of accessing locals in enclosing block or method activations.\u00c2\u00a0 This has already been done for Squeak.\u00c2\u00a0 Anthony Hannan did a closure implementation which exists in a rump form in 3.8.\u00c2\u00a0 But I didn&#8217;t use it because for efficient context-to-stack mapping I want one key ingredient which is to implement access to locals in enclosing activations without access through those activations.<\/p>\n<p>To explain the scheme, which is used in some Lisp compilers, let&#8217;s look at the following:<\/p>\n<p><body><font face=\"serif\"><b>counterBlock<\/b><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| count |<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count := 0.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ count := count + 1].<\/font><BR><\/body><br \/>\nIf counter is stored on the stack of the method activation of counterBlock then there&#8217;s a problem if activations are mapped to stack frames for the duration of their execution.\u00c2\u00a0 Up until the block is returned counter can live happily on some native stack frame created when counterBlock was sent.\u00c2\u00a0 But since the block [counter := counter + 1] outlives the execution of counterBlock we must preserve the value of counter for subsequent evaluations of the block.\u00c2\u00a0 Since we have contexts the thing to do is to create a context object and associate it with the frame when creating a block that accesses the frame, and to write back the contents of the stack frame into its context when a frame that has a context is returned from.\u00c2\u00a0 The sad thing is that this return-time processing is very slow.<\/p>\n<p>What we need to do is to break the dependency between the block activation and its enclosing contexts for accessing locals.\u00c2\u00a0 I&#8217;m going to use Collection&gt;&gt;inject:into: as an example.<\/p>\n<p><body><font face=\"serif\"><i>Collection methods for enumerating<\/i><br \/>\n<b>inject:<\/b> <font color=\"#00007F\">thisValue<\/font> <b>into:<\/b> <font color=\"#00007F\">binaryBlock<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#007F7F\">&quot;Accumulate a running value associated with evaluating the argument,<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;binaryBlock, with the current value of the argument, thisValue, and the<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;receiver as block arguments. For instance, to sum the numeric elements of<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a collection, aCollection inject: 0 into: [:subTotal :next | subTotal + next].&quot;<\/font><font color=\"#000000\"><\/p>\n<p>\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">nextValue<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">nextValue<\/font><font color=\"#000000\"> <\/font><b>:=<\/b><font color=\"#000000\"> <\/font><font color=\"#00007F\">thisValue<\/font><font color=\"#000000\">.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F0000\">self<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">do:<\/font><font color=\"#000000\"> [:<\/font><font color=\"#00007F\">each<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">nextValue<\/font><font color=\"#000000\"> <\/font><b>:=<\/b><font color=\"#000000\"> <\/font><font color=\"#00007F\">binaryBlock<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">value:<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">nextValue<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">value:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">each<\/font><font color=\"#000000\">].<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F0000\">^<\/font><font color=\"#3F3F3F\">nextValue<\/font><\/font><BR><\/body><br \/>\nThe block\u00c2\u00a0 [:each | nextValue := binaryBlock value: nextValue value: each] reads the method argument binaryBlock and reads and writes nextValue.\u00c2\u00a0 If we allocate an explicit array to hold nextValue indirectly (something I&#8217;m going to call an &#8220;indirect temp vector&#8221;) we can avoid writing the local in the method activation:<\/p>\n<p><body><font face=\"serif\"><b>inject:<\/b> <font color=\"#00007F\">thisValue<\/font><font color=\"#000000\"> <\/font><font color=\"#000000\"><b>into:<\/b><\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">binaryBlock<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#000000\"> <\/font><b>:=<\/b><font color=\"#000000\"> Array <\/font><font color=\"#00007F\">new:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\">.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">put:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">thisValue<\/font><font color=\"#000000\">. <\/font><font color=\"#007F7F\">&quot; was nextValue := thisValue.&quot;<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F0000\">self<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">do:<\/font><font color=\"#000000\"> [:<\/font><font color=\"#00007F\">each<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">put:<\/font><font color=\"#000000\"> <\/font><font color=\"#007F00\">(<\/font><font color=\"#00007F\">binaryBlock<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">value:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F007F\">(<\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#7F007F\">)<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">value:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">each<\/font><font color=\"#007F00\">)<\/font><font color=\"#000000\">].<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F0000\">^<\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><\/font><BR><\/body><br \/>\nNow the block only reads the locals of the method activation, and none of the locals it reads changes value after the block is created.\u00c2\u00a0 So the block can keep a private copy of those values without affecting semantics.\u00c2\u00a0 The compiler does this behind the scenes but the code is somewhat equivalent to<\/p>\n<p><body><font face=\"serif\"><b>inject:<\/b> <font color=\"#00007F\">thisValue<\/font><font color=\"#000000\"> <\/font><font color=\"#000000\"><b>into:<\/b><\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">binaryBlock<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#000000\"> <\/font><b>:=<\/b><font color=\"#000000\"> Array <\/font><font color=\"#00007F\">new:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\">.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">put:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">thisValue<\/font><font color=\"#000000\">.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F0000\">self<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">do:<\/font><font color=\"#000000\"> (<\/font><font color=\"#7F0000\">thisContext<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">closureCopy:<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#007F00\">[<\/font><font color=\"#000000\">:<\/font><font color=\"#00007F\">each<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">binaryBlockCopy<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">indirectTempsCopy<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F7F7F\">indirectTempsCopy<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">put:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F007F\">(<\/font><font color=\"#7F7F7F\">binaryBlockCopy<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">value:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">(<\/font><font color=\"#7F7F7F\">indirectTempsCopy<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1)<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">value:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">each<\/font><font color=\"#7F007F\">)<\/font><font color=\"#007F00\">]<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">copiedValues:<\/font><font color=\"#000000\"> <\/font><font color=\"#007F00\">(<\/font><font color=\"#000000\">Array <\/font><font color=\"#00007F\">with:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">binaryBlock<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">with:<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#007F00\">)<\/font><font color=\"#000000\">).<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F0000\">^<\/font><font color=\"#3F3F3F\">indirectTemps<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><\/font><BR><\/body><br \/>\nclosureCopy:copiedValues: answers a BlockClosure that holds the pc in the method to start executing the block&#8217;s code (just like BlockContext&#8217;s startpc) and the array of copiedValues.\u00c2\u00a0 When the block is activated the copiedValues are pushed onto the activation&#8217;s stack after any block arguments, becoming locals of the activation.\u00c2\u00a0 Now there is no dependency on the enclosing activation for local access.\u00c2\u00a0 Nothing needs to happen when returning from an activation that encloses some closure so returns are simple and hence fast.<\/p>\n<p>The compiler analysis to do this is extremely simple.\u00c2\u00a0 Any local that is accessed by an inner scope must either be copied or put in an indirect temp vector.\u00c2\u00a0 If a local is assigned to after it is closed over (after a block is created that accesses the local) then the local must be made indirect.\u00c2\u00a0 We can do slightly better than this, but its not worth the effort.\u00c2\u00a0 This simple analysis works fine.\u00c2\u00a0 I&#8217;ll detail the analysis in a post on the closure compiler and its resultant bytecodes.\u00c2\u00a0 Note that we only need one indirect temp vector per scope, it needs an element to each indirect local.<\/p>\n<h3>Prototyping The Implementation<\/h3>\n<p>The above facilities, creating a closure, creating an indirect temp vector and reading and writing from it, and the evaluation primitives all make sense when implemented in the VM with specific bytecodes and primitives.\u00c2\u00a0 But one thing that&#8217;s very nice about Smalltalk is that one can prototype the above scheme _without_ any VM modifications.\u00c2\u00a0 We can&#8217;t prototype non-local return wthout trickery but blocks like factorial above work fine.\u00c2\u00a0 I did just this before I implemented the closure bytecodes.\u00c2\u00a0 For example here&#8217;s the implementations of closureCopy:copiedValues:, the message one can use to create Closures, and value:, one of the evaluation primitives that can be written in pure Smalltalk due to it having first-class activation records.\u00c2\u00a0 Neat!<\/p>\n<p><body><font face=\"serif\">Object <font color=\"#00007F\">subclass:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">#BlockClosure<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">instanceVariableNames:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F007F\">&#8216;outerContext startpc numArgs copiedValues&#8217;<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">classVariableNames:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F007F\">&#8221;<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">poolDictionaries:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F007F\">&#8221;<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">category:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F007F\">&#8216;Kernel-Methods&#8217;<\/p>\n<p><\/font><i>ContextPart methods for controlling<\/i><br \/>\n<b>closureCopy:<\/b><font color=\"#000000\"> <\/font><font color=\"#00007F\">numArgs<\/font><font color=\"#000000\"> <\/font><b>copiedValues:<\/b><font color=\"#000000\"> <\/font><font color=\"#00007F\">anArray<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#007F7F\">&quot;Distinguish a block of code from its enclosing method by<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; creating a BlockClosure for that block. The compiler inserts into all<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; methods that contain blocks the bytecodes to send the message<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closureCopy:copiedValues:. Do not use closureCopy:copiedValues: in code that you write! Only the<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compiler can decide to send the message closureCopy:copiedValues:.&quot;<\/font><font color=\"#000000\"><\/p>\n<p>\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F0000\">^<\/font><font color=\"#000000\">BlockClosure <\/font><font color=\"#00007F\">new<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">outerContext:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">self<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">startpc:<\/font><font color=\"#000000\"> pc <\/font><font color=\"#00007F\">+<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">2<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">numArgs:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">numArgs<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">copiedValues:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">anArray<\/font><\/p>\n<p><i>BlockClosure methods for evaluating<\/i><br \/>\n<b>value:<\/b><font color=\"#000000\"> <\/font><font color=\"#00007F\">anArg<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#007F7F\">&quot;Activate the receiver, creating a closure activation (MethodContext)<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; whose closure is the receiver and whose caller is the sender of this message.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Supply the argument and copied values to the activation as its arguments and copied temps.&quot;<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">newContext<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">sz<\/font><font color=\"#000000\"> <\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;numArgs <\/font><font color=\"#00007F\">~=<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">ifTrue:<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[<\/font><font color=\"#7F0000\">self<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">numArgsError:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\">].<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">newContext<\/font><font color=\"#000000\"> <\/font><b>:=<\/b><font color=\"#000000\"> <\/font><font color=\"#7F0000\">self<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">asContextWithSender:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">thisContext<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">sender<\/font><font color=\"#000000\">.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">sz<\/font><font color=\"#000000\"> <\/font><b>:=<\/b><font color=\"#000000\"> copiedValues <\/font><font color=\"#00007F\">basicSize<\/font><font color=\"#000000\">.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">newContext<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">stackp:<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">sz<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">+<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\">.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">newContext<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">put:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">anArg<\/font><font color=\"#000000\">.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#3F3F3F\">sz<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">&gt;<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">0<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">ifTrue:<\/font><font color=\"#000000\"> <\/font><font color=\"#007F7F\">&quot;nil basicSize = 0&quot;<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[<\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">to:<\/font><font color=\"#000000\"> copiedValues <\/font><font color=\"#00007F\">basicSize<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">do:<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#007F00\">[<\/font><font color=\"#000000\">:<\/font><font color=\"#00007F\">i<\/font><font color=\"#7F7F7F\">|<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">newContext<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">i<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">+<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">1<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">put:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F007F\">(<\/font><font color=\"#000000\">copiedValues <\/font><font color=\"#00007F\">at:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">i<\/font><font color=\"#7F007F\">)<\/font><font color=\"#007F00\">]<\/font><font color=\"#000000\">].<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F0000\">thisContext<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">privSender:<\/font><font color=\"#000000\"> <\/font><font color=\"#3F3F3F\">newContext<\/p>\n<p><\/font><i>BlockClosure methods for private<\/i><br \/>\n<b>asContextWithSender:<\/b><font color=\"#000000\"> <\/font><font color=\"#00007F\">aContext<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#007F7F\">&quot;Inner private support method for evauation.  Do not use unless you know what you&#8217;re doing.&quot;<\/font><font color=\"#000000\"><\/p>\n<p>\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#7F0000\">^<\/font><font color=\"#000000\">(MethodContext <\/font><font color=\"#00007F\">newForMethod:<\/font><font color=\"#000000\"> outerContext <\/font><font color=\"#00007F\">method<\/font><font color=\"#000000\">)<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">setSender:<\/font><font color=\"#000000\"> <\/font><font color=\"#00007F\">aContext<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">receiver:<\/font><font color=\"#000000\"> outerContext <\/font><font color=\"#00007F\">receiver<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">method:<\/font><font color=\"#000000\"> outerContext <\/font><font color=\"#00007F\">method<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">closure:<\/font><font color=\"#000000\"> <\/font><font color=\"#7F0000\">self<\/font><font color=\"#000000\"><br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/font><font color=\"#00007F\">startpc:<\/font><font color=\"#000000\"> startpc<\/font><\/font><BR><\/body><br \/>\n\u00c2\u00a0<br \/>\nand here&#8217;s the decompilation of factorial compiled using the prototype compiler:<\/p>\n<p><body><font face=\"serif\">\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| t1 |<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t1 := Array new: 1.<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t1<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at: 1<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;put: [:t2 | t2 = 1<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ifTrue: [1]<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ifFalse: [t2<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* ((t1 at: 1)<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: t2 &#8211; 1)]].<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1 to: 10)<br \/>\n\t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;collect: (t1 at: 1)<\/font><BR><\/body><br \/>\nand its opcodes:<\/p>\n<p><body><font face=\"serif\"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushLit: Array<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushConstant: 1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #new:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;popIntoTemp: 0<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushTemp: 0<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushConstant: 1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushThisContext<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushConstant: 1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushLit: Array<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushTemp: 0<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #braceWith:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #closureCopy:copiedValues:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jumpTo: L3<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushTemp: 0<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushConstant: 1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #=<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jumpFalseTo: L1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushConstant: 1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jumpTo: L2<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;L1:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushTemp: 0<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushTemp: 1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushConstant: 1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #at:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushTemp: 0<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushConstant: 1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #-<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #value:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #*<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;L2:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;blockReturn<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;L3:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #at:put:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushConstant: 1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushConstant: 10<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #to:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushTemp: 0<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pushConstant: 1<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #at:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send: #collect:<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop<br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;returnSelf<BR><\/body><\/font><br \/>\n\u00c2\u00a0<\/p>\n<p>and it works \ud83d\ude42<\/p>\n<p>Next post, the closure bytecodes, costs, etc.<\/p>\n<div class=\"pdf24Plugin-cp\"> \t<form name=\"pdf24Form0\" method=\"post\" action=\"https:\/\/doc2pdf.pdf24.org\/wordpress.php\" target=\"pdf24PopWin\" onsubmit=\"var pdf24Win = window.open('about:blank', 'pdf24PopWin', 'resizable=yes,scrollbars=yes,width=600,height=250,left='+(screen.width\/2-300)+',top='+(screen.height\/3-125)+''); pdf24Win.focus(); if(typeof pdf24OnCreatePDF === 'function'){void(pdf24OnCreatePDF(this,pdf24Win));}\"> \t\t<input type=\"hidden\" name=\"blogCharset\" value=\"Cw1x07UAAA==\" \/><input type=\"hidden\" name=\"blogPosts\" value=\"MwQA\" \/><input type=\"hidden\" name=\"blogUrl\" value=\"yygpKbDS1y8vL9fLzSxKzEtJTAIRevlF6frJ+elJOfnpAA==\" \/><input type=\"hidden\" name=\"blogName\" value=\"c85PV3DKyU8HAA==\" \/><input type=\"hidden\" name=\"blogValueEncoding\" value=\"gzdeflate base64\" \/><input type=\"hidden\" name=\"postId_0\" value=\"MwMA\" \/><input type=\"hidden\" name=\"postTitle_0\" value=\"c87JLy4tSi1WCEgsKlHwBAA=\" \/><input type=\"hidden\" name=\"postLink_0\" value=\"yygpKbDS1y8vL9fLzSxKzEtJTAIRevlF6frJ+elJOfnp+kYGBhb6Bmb6Bub6yTn5xaVFqcW6BYlFJbqZ+gA=\" \/><input type=\"hidden\" name=\"postAuthor_0\" value=\"S0zJzcwDAA==\" \/><input type=\"hidden\" name=\"postDateTime_0\" value=\"MzIwsNA1MNM1MFcwtLQyMLMyMAQA\" \/><input type=\"hidden\" name=\"postContent_0\" value=\"7T3tchu3dr97nwKRZzJSIlGk7NguLTFjO\/VEc53kzrVrT0fjZsBdkIS1XGz2QzQznv64b9Ff7bO0L9RH6PkAsLvihyiSoiSbcWxRXOAAODjfwDl7nHSOpRikqneyM8jzpH14OBqNGkOdyjiUXfynYdL+YTcqVNeYc\/\/h92Agk1ylR48bg3wYPXgRmeD8pYlz9SnPjh7vdF5AwxfQUNSeHB\/KjpCpErGSaTQWQWSyIlVZ43\/\/8T\/\/Ld4OFH+lDsyFSkU+UDoVKsavdNyHTxc6NfFQxfm+SFJzoUP8WgaByjKRGyHjSuuhygcm\/PbB06PWk2cZjNovsCd8ikORq2FiUpmOxYVMtexGbg4vihzHHYtIBud2BmYUC1iFjOozGOiP0AaH4mY8IEwn1xcy1yb2Y++aVAzMUImA8eAe7NE8aOpZbgAt5XjTp6sVAIuUByBgUhH2yhTPMNvjZbw3KXyV5TqK9mk9tgei3uQiVQAa9jhvCGz+4u37fYEtjprPoPHEXI9az4TOEA7MJB3q2ESmPxY9Q3tUWTEADkwaCtMT0uKDR3gO0+wiJWSir3IRpErmKhQjnQ90LDIcbwJ9hDbbQnLv6tNYZRUQcrL\/Hg8NVDUFNnQZDXQw8JBhfW5WmvEKn3B19NgjvIqaxvFh0vnLcdJ5C3SETXsmiswIKQLAT2Os7I9CyXNiqZ9glyMjw53OG\/qSWCNJNeLUCP5OPGp82icCmAEv0HFghtkQZpvL6LwBvxwWmUphzv3skJ8e4i\/vtBr9SNOO8xPffqfzTmeFjIBazok3225Fx10TjjvHPeghejJQJzsAVfd2Ov\/0bdzNkmeL\/\/sZ+wNxa2Cfz8fdVBx2\/nJtICWI9ok4a8efRSxOREvo3tu0UG1x1voAn18B\/eMvu2XzCxnh85iouwVk3NoT34n4w4fGslPZbcH+tEWruQdkAEQS5O1yhceHiLHO8Yu\/d44PGYU8zGksKqgWY1MQHzwAaEfisTh6JFpHTfEE\/v7QfNQUj5oP4ePDx0dPn7ofTcvZAMkShwMixa8m1z0NEhOEYhBJPUQStPz8L2lq0rZ4nqMMyZG2FCIFCN2Tfj6QORK9jIABwrHoKpK2tlnYsCLAyWg3fmBCIHmpowx6BBLoThAjougXJPvf\/YIiuYg9qJLX4PsJsbFPnUt1sc8zG0hoLjIVh7BCWGYUChgrxKUAPyjil0lGJQ5OGWf\/BpgKJDJ9lsCGCeAx9SmJrMR1WAAhrGAJOff5WaWqVB6x6wDSGeDkJaPoYV8gHwPKTnYi+ed4B8TuOAKOARWWa5jGgYx0P26LoQ7DSD2D52nguXhC1eqh7KvsEEmK5tV82nzcfNL4mKj+DuxQfrKzAzIvzAcnOz\/80NoRoDH6A\/j26MkPO0Bpbl5uybikco2AeEIZrIMR2EvNkEWXTrO8ohZBgl\/WBI6iahxtaaOOZ8ZjVt8zFrcwg6mbh9uFVBeUW18OTGSAwDLH0NUtr9E0bB\/RKD+Bydg9zIFGWe3R0lFrGFD1aGeMUp1bLV6bMdoY6gJ64MNU5UUau3EZW5bEHMp\/++u+qOrmUAGCcCDq4lRuMEYuBYNjyDh7o4cJWEJ2AWTPwLoTvwN242JQdjJ0XwLy+zoG8AAqLMD8gU49sKMGU3Qxamklg9qjKmxne8HOwP8jRDVoaxWL9zrtZQcv0ipXwSSGItSkkBDCW3Weg0GkPwlchkKLxY7Azx89aj4SXUkroC8spKdNB7Ji+g1NiGKM1W5VEHzbz5\/hX9r8szbTAAJ42Hz2AZXmEHbwQrENyKtUl9AIyFDQxAqE15VtylM78tgRgfokcTG8d8j3OtA5QgPz64vTkISkDatJHhSV38SfvZkq1JprcTZSaWY3fwYMcZwhVfY7P37z4zfHh\/YXb60Bifvdd5qL7NguiANSTkEOqhr9EzNMdMTiitSd+qMA6gLuQE16s6QQr40Y\/K\/Zc+tVOMhCiOvCvu6\/Mc5hcgaNTc7gbjPCTIp3tElyaLpDLcj\/q3iH6FyTL+lFdKnTe6kEbT5Fs3vLkqWfNXSYHZzQBsV\/BIjRkXMIWavbQWp2gnUVswg8TafsvX97yUxzfq4bAySXMykce71g5yrXMMTI2WQXJNKL1IInwDJDO8IhjLe92sEpe3CC4Ck1apHJyj60cCuDDbcfqe\/jZxk7YRnYGfCjSKraugXN+a+VSaVXiCp1JMciNQV0G5HlD7asRi8sVGF7Kz\/uvfyIYecXkCG3Iz+srryel7lfdeYsUy64Ssc\/MUqApMgGwJvWDsxytAG7quekADMvWooheIsY8XBBCS8aQG1rcNYi1csPcnOQop\/jOQ\/t2yJSntneDxSATckpxoAQerVs0YKXq\/tsjIMljNEvdE3w5\/Nf35weoIqPtATWA\/auSou+IW+5h7ZtLmj0HymgdGrbDElwoHkNqwP3LQ2tnMCvhhxoG8gL8mpsnNN6vjrLCmWFbo4+fObkKIoLENCZinoHIIihC+KIA1mnufWeekWEMwPYHo8XVq5ac\/p5zC7ONKyOwZMYim6hI4qeDsE10LEC9aAJvpLZ2K7bBgeLEmNSDIq+4vk\/c3EA9M9DEyvvVPnVcoBQp\/lYjJVMMwb4sxmBW5Xu42fcM0VKCxjKgCkv+0PY3QDWJTMTMwiYCpvm2kJ46Qagjhj0xQhuyq5OrwfmOmqUyx5JzykopCYmyKFMEgC9TxFIJJs+Lr3LSlACWkjBYQwjATrBx4nJwDllW3SkYf+zRKnwAHQCbh+K9hR2LUf1CcJfQQPJ2rAnwWN894tXtchOpFF6PYUui3JqExYxZCUNX5gE1J7+k1dAbvCpgJmRI+rXxw9GA1Brp4A4\/z3MvhJ0shRQ7k5BYXLYdfUJiMjhiMjogHQUkRWZvVmBpjcQx6dAJdRyAIRODjusn1Rid4w+KMkImv3I+PArRqITFYBvF\/CWjQZjmGkwMBmxfmjEcExRbzu3y1tX8X5TxdOeiIbqc10Nr\/LHw6N\/ftra6TyPgTDjsfhZxrEsw\/JAsxj0tDJk8LDj3IZTNzyO5Iit4kdAU5Q5tWZVFoeGEuXFAezlCOSCjcnjsQd5tykFZaCXZdffYt59QAXFRCgQ7bzRGW67KGDcCEiMYhZWHNuQgqlD4PYwtyJiSeOferIvQ2+8jH2ODFk6VxTV4fD4pchdJHOKiTm5Y0gKW1KWXR3pnA8KpkTwUYYZsCH5bGXmiYfHnotPkuCrcCxSP04wNMQ0+ySubAT\/F4r8W3NZtG0Q9RUGT8C\/G9ktkU7w8lkSQuXjFMRWeaTEKzBTjnqyShSF4pU+lKpiFo6IAxaYDlVVmqSYipxF\/7wN6pPOeP8k6L5hwpICfn3YeFoeXp0iqDLqRYo89zq9LiFnyUMAMkKNiPM+V6AZ4j44FNTFR\/FqAqg8gpuGtgqavI5wPQZgHPcxQoayoIpPb0UbJ4zZkAgGMOT+pWiiO0N6rbPEOe1pVg\/HReg8ybx+UHO1DX7c7QRgvwOVE3+AhdVZ1pT7LAjS8nY5dwd7uLm0OXkmPBD+8L1ogXE689yiJ+zqWa6RY1mz6axMmjxhM77rC3vKoKhfNazuQqFgUdeoBJUE0qLzHXEg8l4zf+gYFmlVKOJBsVNjzAz\/mlgReSn8jXFcgOuWhYIjQkU3QNoHmWAsLcWStHJl8PLYEpdSW9xIUrQ7L\/kQKD+oht7P3IAO8\/ARcS+AGyIOXpLzXVHF9REAIwWYEGgTqtQ65iT1K03ZGi26mQJJE1et5WxKzPcNTXGkWKAGLqRAzrazhUCmMrM76e+9fNP9iGcpKKxllplAc\/i9jHgzzhhXTuHUjpxYBtiVU2u2n2E0dNMVB479QQCqBruI6qaAqWJY4tuJ0YjSPq2cIFXCE54KUMv5CLTIZGhXTgqMhIVvfUABCDxhsxoCnlyg3ZyBKKn4IWiKOU1fwV83RVuZKFcl6P\/jSUBX5SPFbDGpHuncF9ZVClK\/RaRQL6kqa1l656Rv7Bai3H\/JriNeSrCxdB3j9rURe2007eiIi+Lejatlou6UAC3r86RUDDo8pb0+PtROioAMtcOh+BQMEbxZk57sPGjCf09e7XQQ1e+Qnq0wEtQLZjenTxf0eDq2gplF2ES7ZnNnaYk9A+iTVzj4t38UJn\/2PAiKYRExb6RFHCPWmS89W1hnrBI1IuvIGjz7y86usvr9ku3AH0yR971sqI0lPJotrw3UssO7IxWkHku8zoRriFdADGi2SxAx+yTECz5oJAIBB0+x6YAsvewEpIuIABXCaiokaalNNAXT91kbhOJbk2NEK0YZ8Fn4L74X+M2HBm\/nfDKyjLEeOkIqQjr6PHdMMfXpw1f4Z6eDU68yzXVgLDb+WllnyWl3O+0TMryusbpZYmU6jMZal\/nkFUPFMM4SG+OmHqLsm9f7rD23P5763hhdiLuywYvqgPlQ2H++JU5ceRIL7\/iHmyH0f78eamZ5G\/7iBpkyZ226tvBZ+P5oO1e228eg\/XP7Bfb7gCHEMKs5J+6sqQoDlSC3xE9kd2YlRGtU9dCkkxEaWhwB8bcCZJrKsY9klDPRcahBQebgUOyWoYop1hnd4JQ+1O76UQAE7EuMp9m4+p4LxMgLo3mqzpTgCIp1kSdcsYWc3OsbaNclUNYmpU23Ap3fit23Drnotvct3vu9Xzp7ialfIdafE+\/M3ehYjdpLoYmftjao9Ne1xW7pMr+5lc8fOSnyVZTQghaXWMC5orhKTfx74AvZ61ujbjOC47Y4aGPzXVfk4OZZ+56iZGmZg1jZ6ezeqrnwJXS4GccEdwcB7N5blelWsLelnI1SzgL6jll\/7+45vHeMnme527+aUeXkwcTgq5Y+sz3InXW8x9HjGE+IbRN38ptbIMFAxn2VuVh4L+eMzol0O39nIa+mbYhzpRI6IOTb\/OVdfjwoJpiVw2S+Q4MXGtRQxrkOyrQCfxwsQkNHTRovfYM3HtrzZBXD111O++TbLnjSCS47pUJc78L31o\/e+tFbP3rrR2\/Sj76XTu7u3NFx5fbK1tdidc1Fp70W9hJ0YHtrhl73rB4RczYXbXfuGG0dfSu6\/WUlS2AJSDVJvCKsz1v6XcZWut4WfM1o3Ebqvr5dWtLQmh+cWkaObrf0K4lpzo45r1NprkkKbUOX22jqVbbsVWFuNqM\/bN0xdMewEkhIrnl2M4dW+HSBqA7GP9sbCP\/dzCyuE+hZJNS\/tw31zwz1VyMINfJ1BVUu5f\/ZvAkT2dOAJLh0u4zTclKfPFpNNSxrcGE0ffcjpq1E+vxSTZ8yzRvAJMGeu45ur9RRUks5UZsEOKglS3CpFjogCG34vuxBSUQ+C93WiJhSnJFzSfh8Qsbjy1fZKR+ec3\/rRyIlKJ6bPU1J6fwgNtU0D5swNS0jjrImbAIkJXQ4YHxhENNIMk72TgAc57ZwPgo+piTNekImbRyPpPgcw2cVZsZ2tWVCKH+P0A5QA05RrlSvqBydyFhG48ymqBqfWg\/bmKqhisYWlstsHNsV+cJynOgTUpIw3s6PAWYGm2VzmpSmrNGu20BMsUww7Tzm5pNXIv29TOnuPmJpjUz3Y0674e3kjHZCRUjVP8Su3efJoo+TGUkEeM\/nrdmBaMJdTE8Ly1uePkXVpqFmEab\/RpTgw+demLJNuandSjr9yKQ2aUP1gA7yShKp3xyLeK4e0tOxquf5RBEQWi5tmptvTkmimKvuaM\/RQGVLObuI04Ix27M7zhVybEmCVgyMFB8OUk4TnvhN2xGRuD3F\/FtLuHhT1uWoG65C5vsSOsvc67+lJjf5mNJPkfZOaymwPuf6ra\/T1JMBZhdrBUit5JcFLoG5\/G46Cfmbv9ymvFBLTKVznx9TrTlRqTWG93aH8pzyrzOb51ZNvbfy8t0vnJrjMuBLNBP8EmCZOogoLlObvaCiZLNYB4QAaOZrO\/hsNeyIFJhYXFbLWnHirPjdnpn+TrIOJsdF14JqFjPTsU8hLqHFJj5gLrDl8EZ8\/oqFOs5xdkjctswrCfyyZghPAqm4SsSU9kz6wZ7LUn2Q0xoeq9R7iURfUSFHLtZWSyylWgw1AiKxPVML7lvVlmWyrzwaCy5PYDMfXR0Apgu2xPdF5QB8Opn47HSQGa74EJBGgsspd9AWQdG+YghVGDwIIhBqkzX9HIfCvL658kz6N87TnG52ZEWXxljFinxQNRw2mYbHw7sss3e2kPOvmCa8SjjIFn0CwlapKxxgjRTMXnue9rOaoWGpbvMrp51b67KPWrewjMSY6CdNiXtU7+FeLgITQ\/omHa+B8P6q0lhFB1y5oqQuy+YWAGbgEmn+DY3wagouJgmnhqqp1lNw66eIyyVbWfpf9NrCJU95uTFlTK7wbSX4\/qQzNAsKnZXFwsk5werHbCpkE2XnQVMtO6WqMVNzybjygbQatlG\/3ARSUKVUHQSt3yhaenRHSqy3AC1YecPqdPK8vPlCBZOtiWRV5\/JrnqWZG+InQ7YyKuPZXiwWtcENoVljDTBK5PpG\/IZ26wo5ziWCybIHEy5U0xY+ZwG3kFc8L3DhxqyR1lV3h1awDqpqdJUQx4o3UqwCv2IGoOHnQvl+hQUcrTB7K3bbq4NYAcLqYc+p8twXUq+TZK2qhC+cUNdoLhy+vF7p317ZCFumulqcepojW3shRq2a1d7SQm1El2h9samsNgn2hbkFFTj39Vy5NrorTWcl39JBV\/GmSBKWzmVmLo5tY0D2ju9E4I5KqOaXX+hiO9H7VG4hNWwdGfOjRa68zQeS\/XnnruY4j2kuK\/7HyS1d0bRVXe\/GsdbZTSpAuw\/8OpAbw\/aHxg3VC7kecyxTT2JNeJbu5up7nQ\/ekMhcBd2LXoW9wvqhedzCJe5FBdIVG1Y715l\/pCkzHbzRf6pbWOxKIrxiqAbnSXvTSmAdFm7rvuL83qYIXG3C3i5bT500Vp9bAd3NG1b3i9QliHUkvKQRJ6J5gxbnms2IVag1vyqtY91yerUsk3uXCr96roK+m\/7JaoJ2\/uJuW6+JzV9Ndn0XZ7ebQPw6rgzeUHr2eqxmzD1e3oKfxjiXz3BmRrxs2nM93DXdtVgy+HWT+XULaNBTugPksruzIkmMP8dyMT8+TG+I6hFAEUdYNxxD\/OexGfH76uC38v22IVZWu6tR93oE78q4+yuTcocrCLB2Vj0XKGN4\/j3K260CVPqs+fLMtxEyX+96Xfx1bVvtAN6DtQ83TuR3Y902BH+j52J3hJsXOn+zra66zYy3n\/w7rsLJq1+h4mNb\/4KA6rur7Bsd+TUydLfZ329zh7038ma2vLX8ix+gb\/vE1nnAUg6i1Vge1MYIAoxOsbnR0NIWZ+38SACuj\/CdbV9QPkrl7XNf1Krce\/Tyo20a2jU6fCd2d0EmEIPtbTF3pzq4N5Qfrfv9j0sftC\/xniH7oskKkc1+ySTnEZiEboVdrTqv\/b5OcX1NkA1ea5g23zOxLwrdyLBgnuJt5Iriu\/lx8XCvLR5QiaeNrdUkp3FuMOutLZobRfFtjHkb20prrcSxvob13hLXbpqkLMd2U5CL7yl7dsMjz7yturGJfCyGyVvQa68fbmzIe0Ea94ZdlyW9k7s7Q6RJckiIMFvbPV8flx8tO8fXrfZWQKxpkluKXpsUw\/PULVl+TTt+cOdnaLMh7vo0v1taFRzd4cVRhtzfKSt+6fU93LgfAGKMLqhsMGzwVfixlXE37lXiJb1tPOaL0PzOW7fh2C+STbmSyBs8xa7Ell1aQHnca8PKHG625XD+77\/+8x\/uwa94KwAr3uxPrxiyLwJ4CD9UHnDVmf8H\" \/> \t\t<a href=\"https:\/\/www.pdf24.org\" target=\"_blank\" title=\"www.pdf24.org\" rel=\"nofollow\"><img src=\"http:\/\/www.mirandabanda.org\/cogblog\/wp-content\/plugins\/pdf24-post-to-pdf\/img\/pdf_32x32.png\" alt=\"\" border=\"0\" height=\"32\" \/><\/a> \t\t<span class=\"pdf24Plugin-cp-space\">&nbsp;&nbsp;<\/span> \t\t<span class=\"pdf24Plugin-cp-text\">Send article as PDF<\/span> \t\t<span class=\"pdf24Plugin-cp-space\">&nbsp;&nbsp;<\/span> \t\t<input class=\"pdf24Plugin-cp-input\" style=\"margin: 0px;\" type=\"text\" name=\"sendEmailTo\" placeholder=\"Enter email address\" \/> \t\t<input class=\"pdf24Plugin-cp-submit\" style=\"margin: 0px;\" type=\"submit\" value=\"Send\" \/> \t<\/form> <\/div>","protected":false},"excerpt":{"rendered":"<p>BlueBook BlockContexts are nearly closures.\u00c2\u00a0 They close-over their enclosing environment, providing access to an enclosing method&#8217;s arguments and temporary variables.\u00c2\u00a0 But they lack their own local environment, hijacking their method activation&#8217;s (or home context&#8217;s) temps to store their own arguments and temporaries (let&#8217;s call these locals).\u00c2\u00a0 Worse still, they&#8217;re not reentrant. \u00c2\u00a0BTW, &#8220;the home context&#8221; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/posts\/6"}],"collection":[{"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/comments?post=6"}],"version-history":[{"count":4,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/posts\/6\/revisions"}],"predecessor-version":[{"id":376,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/posts\/6\/revisions\/376"}],"wp:attachment":[{"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/media?parent=6"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/categories?post=6"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/tags?post=6"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}