[squeak-dev] The Trunk: Environments-dtl.72.mcz

Levente Uzonyi leves at caesar.elte.hu
Tue Mar 20 23:03:33 UTC 2018


On Tue, 20 Mar 2018, Jakob Reschke wrote:

> Note that the following also results in ClassBinding:
> Smalltalk globals at: #Foo put: ProtoObject.
> (Smalltalk globals associationAt: #Foo) class
>
> ...so distinguishing globals that are classes from proper classes is
> not that easy.

Well, that's because #at:put: is the legacy API that should have been 
removed by now. But we're still very far from that, because there are so 
many questions to answer.

>
> Environment>>allClassesAndTraitsDo: uses the same [key == value name]
> condition that Eliot proposed earlier, so it is probably unjustified
> that I avoid it. But note further that Environment>>allClassesDo: uses
> #isKindOf: to separate classes from traits...

More things to iron out.

>
> And for the [each environment == self] bit in my code snippet: each
> class (and trait) "has" an environment. Since self in this case is the
> environment to which #rootClasses was sent, the condition was intended
> to filter out those behaviors that are not indigenous to the queried
> environment, but bound there nevertheless (myEnv at: #Foo put:
> ProtoObject). Additional globals for root classes would be filtered
> out by asSet.

I never said it was wrong. My only problem with it, other than not being 
supported out of the box, is that it's creating way too many intermediate 
collections.
Anyway, I think we're spending way too much time on a method that doesn't 
even have senders.

Levente

>
> 2018-03-20 22:49 GMT+01:00 Eliot Miranda <eliot.miranda at gmail.com>:
>> Hi Levente,
>>
>> On Tue, Mar 20, 2018 at 2:38 PM, Levente Uzonyi <leves at caesar.elte.hu>
>> wrote:
>>>
>>> On Tue, 20 Mar 2018, Eliot Miranda wrote:
>>>
>>>> Hi Jacob,
>>>> On Tue, Mar 20, 2018 at 9:06 AM, Jakob Reschke <forums.jakob at resfarm.de>
>>>> wrote:
>>>>       Hi Eliot,
>>>>
>>>>       ok, from your answers, it should access the declarations, not the
>>>>       bindings of an environment.
>>>>
>>>>       With your requirement, that could be:
>>>>          (self select: [:each | each isBehavior and: [each superclass
>>>> isNil
>>>>       and: [each environment == self "not misplaced via at:put:"]]])
>>>> asSet
>>>>       asArray
>>>>
>>>>
>>>> I don't understand "each environment == self".  A comment as to how this
>>>> works would be good.  Further, is it not possible to declare a variable
>>>> whose value is a root class?
>>>
>>>
>>> With Environments came a new class hierarchy to replace Associations
>>> holding bindings: Binding and its subclasses: Alias, ClassBinding and
>>> Global.
>>
>>
>> Thanks.  Now I get it.
>>
>>>
>>>
>>> A class's binding is always a ClassBinding, a global variable's binding is
>>> always a Global, even if it points to a class. Alias wraps another binding
>>> and gives it a different name.
>>> So, it is fairly easy to detect if a binding is a class, a variable or a
>>> "renamed" class or variable.
>>> This also means that having an Association in an environment is a bug: an
>>> Association is not a Binding.
>>> So, the following should only ever return classes declared in the
>>> environment:
>>>
>>>         | roots |
>>>         roots := IdentitySet new.
>>>         declarations associationsDo: [ :binding |
>>>                 binding class == ClassBinding ifTrue: [
>>>                         | class |
>>>                         (class := binding value) superclass ifNil: [
>>>                                 roots add: class ] ] ].
>>>         ^roots asArray
>>
>>
>> OK, but a bit hacky.  As you point out below...
>>
>>>
>>>
>>> Another way to write it (though it uses a less up-to-date mechanism) if
>>> you're only interested in Classes (and not other kinds of Behavior):
>>>
>>>         | roots |
>>>         roots := IdentitySet new.
>>>         self allClassesDo: [ :class |
>>>                 class superclass ifNil: [ roots add: class ] ].
>>>         ^roots asArray
>>
>>
>> Ah, lovely.  This is the right way to write it.
>>
>>>>       I removed the #value sends because select: only iterates over the
>>>>       values of a dictionary(-like object).
>>>>
>>>>
>>>> Good point.
>>>>
>>>>       I do not like the dependency on
>>>>       the names of things, but that could also be an overreaction as the
>>>>       result of my endeavor to make the tools work across environments.
>>>> ;-)
>>>>
>>>>
>>>> However it works the issue is avoiding duplicates caused by defining
>>>> variables whose values are classes.  I used #name as that's the hammer I
>>>> know.  I hope there's a better way :-)  Further, I hope you'll
>>>> find it :-)
>>>
>>>
>>> See above.
>>>
>>> Levente
>>>
>>>
>>>>
>>>>
>>>>       Kind regards,
>>>>       Jakob
>>>>
>>>>
>>>>       2018-03-18 17:02 GMT+01:00 Eliot Miranda <eliot.miranda at gmail.com>:
>>>>       > Hi Jacob,
>>>>       >
>>>>       >> On Mar 18, 2018, at 3:40 AM, Jakob Reschke
>>>> <forums.jakob at resfarm.de> wrote:
>>>>       >>
>>>>       >> Hi Eliot,
>>>>       >>
>>>>       >> Note that self bindings select: is not the same as self select:
>>>> for an
>>>>       >> Environment, as the latter only enumerates the declarations (its
>>>> "own"
>>>>       >> bindings).
>>>>       >>
>>>>       >> Seems like the only sender is Class rootsOfTheWorld, which
>>>> itself is
>>>>       >> unsent. In that case, the Smalltalk "root" environment is
>>>> hard-coded
>>>>       >> and the specifics of bindings vs. declarations do not really
>>>> matter.
>>>>       >> But what should #rootClasses answer for other, possibly isolated
>>>>       >> environments? What does the sender want to know?
>>>>       >> - For an empty environment (no classes contained), should it
>>>> answer an
>>>>       >> empty collection?
>>>>       >
>>>>       > Yes
>>>>       >
>>>>       >> - Should the answer change if the "root" environment is
>>>> imported?
>>>>       >
>>>>       > No
>>>>       >
>>>>       >> - For an environment that a) does not contain ProtoObject or
>>>> Object,
>>>>       >> but other classes deriving from them, and b) does not import the
>>>>       >> "root" environment, should it answer an empty collection,
>>>>       >> {ProtoObject} (although it is not imported) via superclass
>>>> relations,
>>>>       >> or something else?
>>>>       >
>>>>       > Empty
>>>>       >
>>>>       >> - Should the answer change if the "root" environment is
>>>> imported?
>>>>       >>
>>>>       >> By the way, would it work to have a second (different)
>>>> ProtoObject
>>>>       >> class in the image (in a different environment or under a
>>>> different
>>>>       >> name)?
>>>>       >
>>>>       > It should, right?
>>>>       >
>>>>       > the rootsOfTheWorld are easy to understand and hence to extend to
>>>> environments.  Pre environments theRootsOfTheWorld are the classes that have
>>>> no superclass (have nil as their superclass).
>>>>       theRootsOfTheWorld is a set (has no duplicates) but can be a
>>>> sequence.  Hence, given that Smalltalk can contain user defined variables,
>>>> and the values of these variables can be anything, including
>>>>       classes, the computation of theRootsOfTheWorld should filter out
>>>> variables that just happen to refer to root classes to ensure that a set is
>>>> answered.
>>>>       >
>>>>       > Extending this to environments then is straight forward.
>>>> theRootsOfTheWorld in an environment is a set of the classes defined in that
>>>> environment that have no superclass. The computation should
>>>>       not be confusable by variables whose values just happen to be toot
>>>> classes.
>>>>       >
>>>>       > Now, given that theRootsOfTheWorld are used as the roots of code
>>>> search (allImplementosOf: et al) the notion of a pet-environment
>>>> theRootsOfTheWorld is suspect, given that code search should be
>>>>       able to search all code.  But let's at least get the
>>>> per-environment definition correct before we try and define a system-wide
>>>> one.
>>>>       >
>>>>       >>
>>>>       >> Best regards,
>>>>       >> Jakob
>>>>       >>
>>>>       >> 2018-03-18 9:18 GMT+01:00 Eliot Miranda
>>>> <eliot.miranda at gmail.com>:
>>>>       >>> Hi David,
>>>>       >>>
>>>>       >>>>> On Mar 17, 2018, at 8:19 PM, David T. Lewis
>>>> <lewis at mail.msen.com> wrote:
>>>>       >>>>>
>>>>       >>>>> On Sat, Mar 17, 2018 at 04:54:36PM -0700, Eliot Miranda
>>>> wrote:
>>>>       >>>>> Hi David,
>>>>       >>>>>
>>>>       >>>>>> On Sat, Mar 17, 2018 at 12:10 PM,
>>>> <commits at source.squeak.org> wrote:
>>>>       >>>>>>
>>>>       >>>>>> David T. Lewis uploaded a new version of Environments to
>>>> project The Trunk:
>>>>       >>>>>> http://source.squeak.org/trunk/Environments-dtl.72.mcz
>>>>       >>>>>>
>>>>       >>>>>> ==================== Summary ====================
>>>>       >>>>>>
>>>>       >>>>>> Name: Environments-dtl.72
>>>>       >>>>>> Author: dtl
>>>>       >>>>>> Time: 17 March 2018, 3:09:49.564301 pm
>>>>       >>>>>> UUID: e9aed004-8798-41c0-83f9-a04f5963dd55
>>>>       >>>>>> Ancestors: Environments-jr.71, Environments-fbs.27
>>>>       >>>>>>
>>>>       >>>>>> Merge Environments-fbs.27
>>>>       >>>>>>
>>>>       >>>>>> =============== Diff against Environments-jr.71
>>>> ===============
>>>>       >>>>>>
>>>>       >>>>>> Item was added:
>>>>       >>>>>> + ----- Method: Environment>>rootClasses (in category
>>>> 'accessing') -----
>>>>       >>>>>> + rootClasses
>>>>       >>>>>> +       "return a collection of classes which have a nil
>>>> superclass"
>>>>       >>>>>> +       ^ (self select: [:each | each isBehavior and: [each
>>>> superclass
>>>>       >>>>>> isNil]]) asOrderedCollection.!
>>>>       >>>>>>
>>>>       >>>>>
>>>>       >>>>> At least for me this isn't quite good enough.  There's a
>>>> possibility that
>>>>       >>>>> someone could establish a variable whose value is a root,
>>>> e.g. by
>>>>       >>>>>
>>>>       >>>>> Smalltalk at: #MyRootClass put: ProtoObject
>>>>       >>>>>
>>>>       >>>>> and that would cause rootClasses to answer a duplicate.  So
>>>> IMO it needs to
>>>>       >>>>> do one of
>>>>       >>>>> - convert to a set and then back to a collection
>>>>       >>>>> - answer a set
>>>>       >>>>> - enumerate over associations, selecting those classes whose
>>>> key is the
>>>>       >>>>> same as their name
>>>>       >>>>>
>>>>       >>>>> _,,,^..^,,,_
>>>>       >>>>> best, Eliot
>>>>       >>>>
>>>>       >>>> Hi Eliot,
>>>>       >>>>
>>>>       >>>> Do you mean this?
>>>>       >>>>
>>>>       >>>> Environment>>rootClasses
>>>>       >>>>   "return a collection of classes which have a nil superclass"
>>>>       >>>>   ^ (self select: [:each | each isBehavior and: [each
>>>> superclass isNil]]) asSet asOrderedCollection.
>>>>       >>>
>>>>       >>> That'll do but perhaps better is
>>>>       >>>
>>>>       >>>          self bindings select: [:each | each value isBehavior
>>>> and: [each value superclass isNil and: [each value name == each key]]])
>>>> collect:  [:each | each value]
>>>>       >>>
>>>>       >>>>
>>>>       >>>>
>>>>       >>>> Note, I am not the author here, just tending to the inbox :-)
>>>>       >>>>
>>>>       >>>> Thanks,
>>>>       >>>> Dave
>>>>       >>>>
>>>>       >>>>
>>>>       >>>
>>>>       >>
>>>>       >
>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> _,,,^..^,,,_
>>>> best, Eliot
>>>>
>>>
>>>
>>>
>>
>>
>>
>> --
>> _,,,^..^,,,_
>> best, Eliot
>>
>>
>>


More information about the Squeak-dev mailing list