[squeak-dev] Environment declarations vs bindings

H. Hirzel hannes.hirzel at gmail.com
Thu Sep 29 17:56:10 UTC 2016


If I inspect

    Environment current

I get an Enviroment instance with declarations, bindings, policies and
observers as instance variables.


If I do a printit on

    Environment current

I get Smalltalk. When I inspect that I get an instance of
SmalltalkImage. With the only instance variable 'globals' which is an
environment.

What is happening here? Relationship between Environment and
SmalltalkImage instance?


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


More information about the Squeak-dev mailing list