[squeak-dev] Environment declarations vs bindings

H. Hirzel hannes.hirzel at gmail.com
Thu Sep 29 05:33:35 UTC 2016


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