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

Eliot Miranda eliot.miranda at gmail.com
Wed Mar 21 02:58:22 UTC 2018



> On Mar 20, 2018, at 4:03 PM, Levente Uzonyi <leves at caesar.elte.hu> wrote:
> 
>> 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.

:-). systemNavigation should use it at the very least.  I'll take a look tomorrow.


> 
> 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