<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 29 September 2016 at 10:10, Nicolas Cellier <span dir="ltr">&lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span class="">2016-09-29 18:39 GMT+02:00 Jakob Reschke <span dir="ltr">&lt;<a href="mailto:jakob.reschke@student.hpi.de" target="_blank">jakob.reschke@student.hpi.de</a>&gt;</span><wbr>:<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">Many questions should be answered with tooling here, but in the<br>
particular case I mentioned, IMHO it is not about tooling. Until now,<br>
code that does `Smalltalk at: something` wants to look up something<br>
dynamically or it can&#39;t be sure that this class is actually loaded. As<br>
there was only one place to do such lookups, no differentiation about<br>
visibility or the source of a binding was necessary.<br>
<br>
Instances of `Smalltalk at: something` should either be replaced by an<br>
environment aware equivalent that makes clear if a name should be<br>
looked up *only* in the receiving environment (in its declarations),<br>
or if a name should be resolved, looking also in imported environments<br>
(in the bindings). </blockquote><div><br></div></span><div>Agree<br> <br></div><span class=""><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">As it is inconvenient to find all these pieces of<br>
code and change them all, `Smalltalk (globals)` could be the &quot;active&quot;<br>
environment (currently via dynamic scoping with `on:<br>
CurrentEnvironment do: ...`), not the original global environment.</blockquote></span><div><div><br>I don&#39;t like the idea of CurrentEnvironment at all. IMO global state stinks.<br></div><div>It would mean that a lotta behavior would change by simply switching one shared variable...<br></div><div>I see it more like a not so clever workaround to make tools still work in presence of environments with minimal changes.</div></div></div></div></div></blockquote><div><br></div><div>Global state does indeed stink, which is why Environments is so nice, because &quot;global&quot; isn&#39;t global anymore.</div><div><br></div><div>But that&#39;s the whole point of CurrentEnvironment - it&#39;s a _delimited dynamic variable_, turning formerly actually global state into something context sensitive.</div><div><br></div><div>frank</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">But<br>
then Environment&gt;&gt;at: must behave sensibly. I would expect that I can<br>
always do `Smalltalk at: #Object` to retrieve `Object` in any<br>
environment (under the assumption that every environment would import<br>
the &quot;Kernel&quot; or original environment). This is currently not the case,<br>
because Environment&gt;&gt;at: looks only into an environment&#39;s (own)<br>
declarations, not the imported bindings.<br>
<span><br></span></blockquote><div><br></div></span><div>I don&#39;t know. Maybe (Smalltalk at: #Foo) is questionable by itself.<br></div><div>VW did introduce #{Foo} ifPresent: [:foo | ] or something like that for deferred bindings.<br></div><div>I remind you that Smalltalk itself is a global variable created with a different instance for each environment.<br></div><br><div>Object is in the superclass chain, so we can still access with superclass superclass ... environment.<br></div><div><div class="h5"><div><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"><span>
2016-09-29 17:30 GMT+02:00 Nicolas Cellier &lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmai<wbr>l.com</a>&gt;:<br>
&gt;<br>
&gt;<br>
&gt; 2016-09-29 15:15 GMT+02:00 Jakob Reschke &lt;<a href="mailto:jakob.reschke@student.hpi.de" target="_blank">jakob.reschke@student.hpi.de</a>&gt;<wbr>:<br>
&gt;&gt;<br>
</span><span>&gt;&gt; Hi,<br>
&gt;&gt;<br>
&gt;&gt; Environment&gt;&gt;associationAt: is part of the Smalltalk globals<br>
&gt;&gt; Dictionary compatibility interface, right? As a quick and dirty fix, I<br>
&gt;&gt; changed instances of Smalltalk at: xyz in Monticello code to<br>
&gt;&gt; CurrentEnvironment signal at: xyz, but #at: also only reads in the<br>
&gt;&gt; declarations, so myEnvironment at: #MCWriter or myEnvironment at:<br>
&gt;&gt; #Object returns nil by default. It would make more sense to perform a<br>
&gt;&gt; full lookup via #valueOf:ifAbsent: in #at: and its cousins, wouldn&#39;t<br>
&gt;&gt; it?<br>
&gt;&gt;<br>
&gt;&gt; Best,<br>
&gt;&gt; Jakob<br>
&gt;&gt;<br>
&gt;<br>
</span><span>&gt; I imagine that the question is about tools.<br>
&gt; For now Smalltalk importSelf, so bindings and declarations do agree.<br>
&gt; If an Environment does not importSelf, then some variables will be<br>
&gt; invisibles (unbounds). Do we still want to see them in some tool, or not?<br>
&gt; What&#39;s going on if we play with Alias? Do we want to see the Alias in some<br>
&gt; browser? If not, then we&#39;d better stick with declarations.<br>
&gt; There is no easy solution. A single facade for two dictionaries cannot fit<br>
&gt; all, so we need several different messages.<br>
&gt; But it&#39;s much about what we want to do with those environments.<br>
&gt;<br>
&gt;<br>
&gt;&gt;<br>
</span><div><div>&gt;&gt; 2016-09-29 7:33 GMT+02:00 H. Hirzel &lt;<a href="mailto:hannes.hirzel@gmail.com" target="_blank">hannes.hirzel@gmail.com</a>&gt;:<br>
&gt;&gt; &gt; On 9/28/16, Nicolas Cellier &lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmai<wbr>l.com</a>&gt; wrote:<br>
&gt;&gt; &gt;&gt; Since we are at reviewing Environment, here is a small detail that<br>
&gt;&gt; &gt;&gt; bothers<br>
&gt;&gt; &gt;&gt; me. I already asked some months ago, but silence was the only response,<br>
&gt;&gt; &gt;&gt; so<br>
&gt;&gt; &gt;&gt; ping.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Implementation of Environment is sometimes not obvious:<br>
&gt;&gt; &gt;&gt; - Environment&gt;&gt;associationAt: uses declarations inst.var..<br>
&gt;&gt; &gt;&gt; - Environment&gt;&gt;associationOrUnde<wbr>claredAt: uses bindings inst.var.<br>
&gt;&gt; &gt;&gt; How can it be so different, the selector does not speak, does it?<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; OK, there is a flag: #review in one of them, but that does not make<br>
&gt;&gt; &gt;&gt; code<br>
&gt;&gt; &gt;&gt; clearer, it&#39;s just a smell of over-complexity or ill-naming.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Whatever the reason (self explaining code?) Colin does not comment<br>
&gt;&gt; &gt;&gt; class/methods, that&#39;s a fact.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Alternatively a description of the general ideas and the mechanism would<br>
&gt;&gt; &gt; help.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; After all Environments is just a clever combination of a few<br>
&gt;&gt; &gt; dictionaries  to look up class names? Isn&#39;t it?  ;-)<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; However the fact that people did not move on much finalising the<br>
&gt;&gt; &gt; implementation of environments  since 2012 shows that it is hard to<br>
&gt;&gt; &gt; reverse-engineer the intentions from the (incomplete) code.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; Chris made the effort of commenting Environment but then came this<br>
&gt;&gt; &gt;&gt; declarations/bindings split, and the comment did rapidly rot.<br>
&gt;&gt; &gt;&gt; We have here an un-healthy statu quo crying for change.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; So if we want to at least comment the class with the<br>
&gt;&gt; &gt;&gt; meaning/role/responsibility of inst vars, here is my understanding:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; environment bind: #Foo to: 0. just add to the declarations.<br>
&gt;&gt; &gt;&gt; (You see how names are not obvious: bind does not bind the new binding<br>
&gt;&gt; &gt;&gt; to<br>
&gt;&gt; &gt;&gt; bindings).<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Environments<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; bind: aSymbol to: anObject<br>
&gt;&gt; &gt;         | binding newBinding |<br>
&gt;&gt; &gt;         newBinding := aSymbol =&gt; anObject.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;         binding := declarations associationAt: aSymbol ifAbsent: [nil].<br>
&gt;&gt; &gt;         binding ifNotNil:<br>
&gt;&gt; &gt;                 [binding class == newBinding class<br>
&gt;&gt; &gt;                         ifTrue: [binding value: anObject]<br>
&gt;&gt; &gt;                         ifFalse: [binding becomeForward: newBinding].<br>
&gt;&gt; &gt;                 ^anObject].<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;         binding := undeclared associationAt: aSymbol ifAbsent: [nil].<br>
&gt;&gt; &gt;         binding<br>
&gt;&gt; &gt;                 ifNil: [binding := newBinding]<br>
&gt;&gt; &gt;                 ifNotNil:<br>
&gt;&gt; &gt;                         [undeclared removeKey: aSymbol.<br>
&gt;&gt; &gt;                         binding class == newBinding class<br>
&gt;&gt; &gt;                                 ifTrue: [binding value: anObject]<br>
&gt;&gt; &gt;                                 ifFalse: [binding becomeForward:<br>
&gt;&gt; &gt; newBinding]].<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;         declarations add: binding.<br>
&gt;&gt; &gt;         self binding: binding addedTo: self.<br>
&gt;&gt; &gt;         ^anObject<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Could you elaborate a bit please?<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; If the Environment importSelf, then the ClassBinding/Global also goes<br>
&gt;&gt; &gt;&gt; to<br>
&gt;&gt; &gt;&gt; bindings... (thru an observer pattern and the magic of naming policies)<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; The bindings is what is used by the compiler, so what if an environment<br>
&gt;&gt; &gt;&gt; does not importSelf? It means that the variable it declares are not<br>
&gt;&gt; &gt;&gt; bound,<br>
&gt;&gt; &gt;&gt; so it is not reachable (kind of invisible class/Global).<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; IOW, the bindings will contain all the imports, including self-imports.<br>
&gt;&gt; &gt;&gt; importSelf is generally what we want to do, unless weird cases of<br>
&gt;&gt; &gt;&gt; powerless<br>
&gt;&gt; &gt;&gt; environment for obfuscation or trustless sandboxing reason.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Now, associationAt: does not speak for itself. It&#39;s too hard to decide<br>
&gt;&gt; &gt;&gt; if<br>
&gt;&gt; &gt;&gt; we&#39;re speaking of own declarations or bindings... Analyzing the usage<br>
&gt;&gt; &gt;&gt; is<br>
&gt;&gt; &gt;&gt; difficult. bindingAt: would be less ambiguous, so IMO we cannot fix<br>
&gt;&gt; &gt;&gt; without<br>
&gt;&gt; &gt;&gt; semantic shift.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; This would need as well elaboration as well a separate thread.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; The semantic will be carried by the senders (the Tools), and the tools<br>
&gt;&gt; &gt;&gt; by<br>
&gt;&gt; &gt;&gt; usage we want to make of Environment. So we first have to define that:<br>
&gt;&gt; &gt;&gt; what<br>
&gt;&gt; &gt;&gt; feature do we want to support? With which tool? That probably require<br>
&gt;&gt; &gt;&gt; yet<br>
&gt;&gt; &gt;&gt; another thread...<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Yes<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; --Hannes<br>
&gt;&gt; &gt;<br>
&gt;&gt;<br>
&gt;<br>
<br>
</div></div></blockquote></div></div></div><br></div></div>
<br><br>
<br></blockquote></div><br></div></div>