<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2016-09-29 7:33 GMT+02:00 H. Hirzel <span dir="ltr">&lt;<a target="_blank" href="mailto:hannes.hirzel@gmail.com">hannes.hirzel@gmail.com</a>&gt;</span>:<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><span class="gmail-">On 9/28/16, Nicolas Cellier &lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com">nicolas.cellier.aka.nice@<wbr>gmail.com</a>&gt; wrote:<br>
&gt; Since we are at reviewing Environment, here is a small detail that bothers<br>
&gt; me. I already asked some months ago, but silence was the only response, so<br>
&gt; ping.<br>
&gt;<br>
&gt; Implementation of Environment is sometimes not obvious:<br>
&gt; - Environment&gt;&gt;associationAt: uses declarations inst.var..<br>
&gt; - Environment&gt;&gt;<wbr>associationOrUndeclaredAt: uses bindings inst.var.<br>
&gt; How can it be so different, the selector does not speak, does it?<br>
&gt;<br>
&gt; OK, there is a flag: #review in one of them, but that does not make code<br>
&gt; clearer, it&#39;s just a smell of over-complexity or ill-naming.<br>
&gt;<br>
&gt; Whatever the reason (self explaining code?) Colin does not comment<br>
&gt; class/methods, that&#39;s a fact.<br>
<br>
</span>Alternatively a description of the general ideas and the mechanism would help.<br>
<br>
After all Environments is just a clever combination of a few<br>
dictionaries  to look up class names? Isn&#39;t it?  ;-)<br>
<br>
However the fact that people did not move on much finalising the<br>
implementation of environments  since 2012 shows that it is hard to<br>
reverse-engineer the intentions from the (incomplete) code.<br>
<span class="gmail-"><br>
<br></span></blockquote><div>More than that: we only get core functionalities, the intentions are not written here.<br></div><div>IOW things still are very open.<br> <br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><span class="gmail-">
<br>
<br>
<br>
&gt; Chris made the effort of commenting Environment but then came this<br>
&gt; declarations/bindings split, and the comment did rapidly rot.<br>
&gt; We have here an un-healthy statu quo crying for change.<br>
&gt;<br>
&gt; So if we want to at least comment the class with the<br>
&gt; meaning/role/responsibility of inst vars, here is my understanding:<br>
&gt;<br>
&gt; environment bind: #Foo to: 0. just add to the declarations.<br>
&gt; (You see how names are not obvious: bind does not bind the new binding to<br>
&gt; bindings).<br>
<br>
</span>Environments<br>
<br>
bind: aSymbol to: anObject<br>
        | binding newBinding |<br>
        newBinding := aSymbol =&gt; anObject.<br></blockquote><div>This creates either a Global or ClassBinding.<br></div><div>The first one is writeable, the second not.<br> <br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
<br>
        binding := declarations associationAt: aSymbol ifAbsent: [nil].<br></blockquote><div><div>A class points to its environment where it is declared.<br></div><div>So we expect this invariant:<br></div>    (Foo environment declarationOf: Foo name) value == Foo.<br><div>And of course:<br></div><div>    (declarations values select: [:c | c isBehavior]) allSatisfy: [:c | c environment == self].<br></div>For globals I don&#39;t know why they are attached to a specific environment.<br>Just because of mechanism for propagating changes?<br> <br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
        binding ifNotNil:<br>
                [binding class == newBinding class<br>
                        ifTrue: [binding value: anObject]<br>
                        ifFalse: [binding becomeForward: newBinding].<br>
                ^anObject].<br></blockquote><div><br><br></div><div>Since we different binding classes we cannot just change the value.<br></div><div>Since bindings are shared by bindings inst. var., CompiledMethods and other environments if we don&#39;t use value, we must preserve identity with a become...<br><br></div><div>Note: above code protects against Object := Array because ClassBinding cannot change value.<br>But not against Object := 1, become protects nothing. It must be handled somewhere else.<br></div><div> <br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
<br>
        binding := undeclared associationAt: aSymbol ifAbsent: [nil].<br>
        binding<br>
                ifNil: [binding := newBinding]<br>
                ifNotNil:<br>
                        [undeclared removeKey: aSymbol.<br>
                        binding class == newBinding class<br>
                                ifTrue: [binding value: anObject]<br>
                                ifFalse: [binding becomeForward: newBinding]].<br>
<br></blockquote><div>If we previously had some undeclared reference to such variable name (normally a Global with nil value), it&#39;s time to rebind it.<br> <br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
        declarations add: binding.<br>
        self binding: binding addedTo: self.<br></blockquote><div>Now propagate the change to every interested observer (those who import declarations from yourself). <br></div><div> </div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
        ^anObject<br></blockquote><div>like at:put: used to do, we still answer the put object.<br> <br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
<br>
<br>
Could you elaborate a bit please?<br>
<span class="gmail-"><br></span></blockquote><div><br></div><div>See above, by pure reverse engineering ;)</div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><span class="gmail-">
<br>
<br>
<br>
&gt; If the Environment importSelf, then the ClassBinding/Global also goes to<br>
&gt; bindings... (thru an observer pattern and the magic of naming policies)<br>
&gt;<br>
&gt; The bindings is what is used by the compiler, so what if an environment<br>
&gt; does not importSelf? It means that the variable it declares are not bound,<br>
&gt; so it is not reachable (kind of invisible class/Global).<br>
&gt;<br>
&gt; IOW, the bindings will contain all the imports, including self-imports.<br>
&gt; importSelf is generally what we want to do, unless weird cases of powerless<br>
&gt; environment for obfuscation or trustless sandboxing reason.<br>
&gt;<br>
&gt; Now, associationAt: does not speak for itself. It&#39;s too hard to decide if<br>
&gt; we&#39;re speaking of own declarations or bindings... Analyzing the usage is<br>
&gt; difficult. bindingAt: would be less ambiguous, so IMO we cannot fix without<br>
&gt; semantic shift.<br>
<br>
</span>This would need as well elaboration as well a separate thread.<br>
<span class="gmail-"><br>
<br>
&gt; The semantic will be carried by the senders (the Tools), and the tools by<br>
&gt; usage we want to make of Environment. So we first have to define that: what<br>
&gt; feature do we want to support? With which tool? That probably require yet<br>
&gt; another thread...<br>
<br>
</span>Yes<br></blockquote><div><br></div><div>already opened :)<br> <br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
<br>
--Hannes<br>
<br>
</blockquote></div><br></div></div>