PluggableListMorph

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

PluggableListMorph

Dan Norton
Greetings,

PluggableListMorph has valuable behavior but applying it in morphs with multiple lists can be
daunting because of the use of the dependency mechanism. AFAICT the tools do not display
dependencies and even if they did, it's not clear why some of them exist.

What is needed is a "PluggableListMorph Principles of Operation" doc, or something similar
that can be in the Terse Guide. It should show an example of selection in one list causing the
population of another list and selection in that list causing the population of some other
morph. Isn't that like FileList? Yes, but we need the whys and wherefors. For example, a
method sends #changed: with a parameter referring to another method - why? The design
needs to be explained.

 - Dan

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: PluggableListMorph

KenDickey
On Tue, 20 Oct 2015 16:43:02 -0400
"Dan Norton" <[hidden email]> wrote:

> PluggableListMorph has valuable behavior but applying it in morphs with multiple lists can be
> daunting because of the use of the dependency mechanism. AFAICT the tools do not display
> dependencies and even if they did, it's not clear why some of them exist.
>
> What is needed is a "PluggableListMorph Principles of Operation" doc, or something similar
> that can be in the Terse Guide. It should show an example of selection in one list causing the
> population of another list and selection in that list causing the population of some other
> morph. Isn't that like FileList? Yes, but we need the whys and wherefors. For example, a
> method sends #changed: with a parameter referring to another method - why? The design
> needs to be explained.

Dan,

+1

A tool to detect/show such "out of band" control/change linkages/dependencies would be most welcomed, as would a Principles of Operation.

Taking a quick look at my own code ("guilty as charged, sir")

>> grep "changed:" */*.st
Cuis-Smalltalk-BabySteps/PropertyEditor.pck.st:changed: myMorph
Cuis-Smalltalk-Ropes/Ropes.pck.st: self changed: #actualContents! !
Cuis-Smalltalk-Ropes/Ropes.pck.st: self changed: #refetched.
Cuis-Smalltalk-Unicode/UniCodes.pck.st: self changed: #actualContents! !
Cuis-Smalltalk-Unicode/UniCodes.pck.st: self changed: #refetched.

I see two cases where one wants to be notified of changes without adding specific code to individual morph instances.  In each case one wants to propagate updates to dependent views.

[1] Change in internal Morph state should update viewers onto that state.
[2] The special case of selection change in a list (PlugableListMorph) should update dependent viewers.

So the simple explanation for "WHY change notification" is to update (perhaps multiple) viewers without doing special notification code in the Morphs being viewed.  The target Morph should not have to know how many, if any, views onto its state exist.

HOW is the registration process:
   Class ActiveModel and its subclass: SystemChangeNotifier

I am a rare user of the change notification mechanism and would also benefit from good documentation and better tool(s) in this area.

Cheers,
KenD <[hidden email]>

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
-KenD
Reply | Threaded
Open this post in threaded view
|

Re: PluggableListMorph

Dan Norton
On 22 Oct 2015 at 15:39, KenD wrote:

> On Tue, 20 Oct 2015 16:43:02 -0400
> "Dan Norton" <[hidden email]> wrote:
>
> > PluggableListMorph has valuable behavior but applying it in morphs
> with multiple lists can be
> > daunting because of the use of the dependency mechanism. AFAICT
> the tools do not display
> > dependencies and even if they did, it's not clear why some of them
> exist.
> >
> > What is needed is a "PluggableListMorph Principles of Operation"
> doc, or something similar
> > that can be in the Terse Guide. It should show an example of
> selection in one list causing the
> > population of another list and selection in that list causing the
> population of some other
> > morph. Isn't that like FileList? Yes, but we need the whys and
> wherefors. For example, a
> > method sends #changed: with a parameter referring to another
> method - why? The design
> > needs to be explained.
>
> Dan,
>
> +1
>
> A tool to detect/show such "out of band" control/change
> linkages/dependencies would be most welcomed, as would a Principles
> of Operation.
>
> Taking a quick look at my own code ("guilty as charged, sir")
>
> >> grep "changed:" */*.st
> Cuis-Smalltalk-BabySteps/PropertyEditor.pck.st:changed: myMorph
> Cuis-Smalltalk-Ropes/Ropes.pck.st: self changed: #actualContents!
> !
> Cuis-Smalltalk-Ropes/Ropes.pck.st: self changed: #refetched.
> Cuis-Smalltalk-Unicode/UniCodes.pck.st: self changed:
> #actualContents! !
> Cuis-Smalltalk-Unicode/UniCodes.pck.st: self changed: #refetched.
>
Hi Ken,

In #actualContents: there is "self changed: #actualContents" which seems reasonable.

However, in #refetch there is "self changed: #refetch" which is perplexing because it looks
like infinite recursion, but it must be OK because similar examples appear in Browser.

 - Dan

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: PluggableListMorph

Juan Vuletich-4
In reply to this post by Dan Norton
Hi Dan,

On 20/10/2015 05:43 p.m., Dan Norton wrote:
> Greetings,
>
> PluggableListMorph has valuable behavior but applying it in morphs with multiple lists can be
> daunting because of the use of the dependency mechanism. AFAICT the tools do not display
> dependencies and even if they did, it's not clear why some of them exist.

Yes. Most tools are still using the changed:/update: dependency
mechanism that comes from MVC in Smalltalk-80.

Later, Squeak and Cuis also included the #when:send:to: event system. It
should replace changed:/update: in all client code because it helps
produce code that is easier to understand. This is something we should
do at some moment.

> What is needed is a "PluggableListMorph Principles of Operation" doc, or something similar
> that can be in the Terse Guide. It should show an example of selection in one list causing the
> population of another list and selection in that list causing the population of some other
> morph. Isn't that like FileList? Yes, but we need the whys and wherefors. For example, a
> method sends #changed: with a parameter referring to another method - why? The design
> needs to be explained.
>
>   - Dan

Most likely all the classic references apply (In the blue book? Or most
likely in Inside Smalltalk vol II). I'm sure there are others. Including
excepts and/or references to them in TerseGuide would indeed be great.

Please also keep in mind that this is not only for lists. It is
essentially the same mechanism used for text panes, buttons, lists, tree
lists, etc.

Thanks,
Juan Vuletich

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: PluggableListMorph

Juan Vuletich-4
In reply to this post by Dan Norton
On 23/10/2015 12:56 p.m., Dan Norton wrote:

> On 22 Oct 2015 at 15:39, KenD wrote:
>
>> On Tue, 20 Oct 2015 16:43:02 -0400
>> "Dan Norton"<[hidden email]>  wrote:
>>
>>> PluggableListMorph has valuable behavior but applying it in morphs
>> with multiple lists can be
>>> daunting because of the use of the dependency mechanism. AFAICT
>> the tools do not display
>>> dependencies and even if they did, it's not clear why some of them
>> exist.
>>> What is needed is a "PluggableListMorph Principles of Operation"
>> doc, or something similar
>>> that can be in the Terse Guide. It should show an example of
>> selection in one list causing the
>>> population of another list and selection in that list causing the
>> population of some other
>>> morph. Isn't that like FileList? Yes, but we need the whys and
>> wherefors. For example, a
>>> method sends #changed: with a parameter referring to another
>> method - why? The design
>>> needs to be explained.
>> Dan,
>>
>> +1
>>
>> A tool to detect/show such "out of band" control/change
>> linkages/dependencies would be most welcomed, as would a Principles
>> of Operation.
>>
>> Taking a quick look at my own code ("guilty as charged, sir")
>>
>>>> grep "changed:" */*.st
>> Cuis-Smalltalk-BabySteps/PropertyEditor.pck.st:changed: myMorph
>> Cuis-Smalltalk-Ropes/Ropes.pck.st: self changed: #actualContents!
>> !
>> Cuis-Smalltalk-Ropes/Ropes.pck.st: self changed: #refetched.
>> Cuis-Smalltalk-Unicode/UniCodes.pck.st: self changed:
>> #actualContents! !
>> Cuis-Smalltalk-Unicode/UniCodes.pck.st: self changed: #refetched.
>>
> Hi Ken,
>
> In #actualContents: there is "self changed: #actualContents" which seems reasonable.
>
> However, in #refetch there is "self changed: #refetch" which is perplexing because it looks
> like infinite recursion, but it must be OK because similar examples appear in Browser.
>
>   - Dan

Just look at senders of #refetched . (not refetch!) It is quite simple,
actually.

To see a bit more on how lists are used, see references to
PluggableListMorph. The second is #buildMorphicMessageCatList. See how
it parametrizes the instance it builds. These methods that create
various lists are quite similar, and all they do is to bind each list
with a different aspect of the model. In this case, with
#messageCategoryList. See implementors and senders. It is clear that the
implementors are methods in models that answer (guess what!!!!) a list
of message categories. When you look at senders senders, you can see
that some are in the model, doing things like 'self changed:
#messageCategoryList'. It is easy to see that this means that the list
of message categories have changed, and anybody depending on that should
update itself.

Now we have a detail that is not that obvious, and most likely the clue
you need to understand this all. See implementors of #update: in
PluggableListMorph and the other PluggableMorph classes. #update:
compares the argument with the listGetter (or the appropriate ivar for
each morph). So, when the model does 'self changed:
#messageCategoryList', all dependent morphs get  message 'eachMorph
update: #messageCategoryList'. And only those morphs that were
configured to watch on this symbol with react.

As I said before, this is the changed/update mechanism in MVC in
Smalltlk-80. Using #when:send:to: insted would lead to better code. But
documenting the current state of the system is needed and important,

Cheers,
Juan Vuletich

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: PluggableListMorph

Dan Norton
On 23 Oct 2015 at 13:59, Juan Vuletich wrote:

> On 23/10/2015 12:56 p.m., Dan Norton wrote:
> > On 22 Oct 2015 at 15:39, KenD wrote:
> >
> >> On Tue, 20 Oct 2015 16:43:02 -0400
> >> "Dan Norton"<[hidden email]>  wrote:
> >>
> >>> PluggableListMorph has valuable behavior but applying it in
> morphs
> >> with multiple lists can be
> >>> daunting because of the use of the dependency mechanism.
> AFAICT
> >> the tools do not display
> >>> dependencies and even if they did, it's not clear why some of
> them
> >> exist.
> >>> What is needed is a "PluggableListMorph Principles of
> Operation"
> >> doc, or something similar
> >>> that can be in the Terse Guide. It should show an example of
> >> selection in one list causing the
> >>> population of another list and selection in that list causing
> the
> >> population of some other
> >>> morph. Isn't that like FileList? Yes, but we need the whys and
> >> wherefors. For example, a
> >>> method sends #changed: with a parameter referring to another
> >> method - why? The design
> >>> needs to be explained.
> >> Dan,
> >>
> >> +1
> >>
> >> A tool to detect/show such "out of band" control/change
> >> linkages/dependencies would be most welcomed, as would a
> Principles
> >> of Operation.
> >>
> >> Taking a quick look at my own code ("guilty as charged, sir")
> >>
> >>>> grep "changed:" */*.st
> >> Cuis-Smalltalk-BabySteps/PropertyEditor.pck.st:changed: myMorph
> >> Cuis-Smalltalk-Ropes/Ropes.pck.st: self changed:
> #actualContents!
> >> !
> >> Cuis-Smalltalk-Ropes/Ropes.pck.st: self changed: #refetched.
> >> Cuis-Smalltalk-Unicode/UniCodes.pck.st: self changed:
> >> #actualContents! !
> >> Cuis-Smalltalk-Unicode/UniCodes.pck.st: self changed:
> #refetched.
> >>
> > Hi Ken,
> >
> > In #actualContents: there is "self changed: #actualContents" which
> seems reasonable.
> >
> > However, in #refetch there is "self changed: #refetch" which is
> perplexing because it looks
> > like infinite recursion, but it must be OK because similar
> examples appear in Browser.
> >
> >   - Dan
>
> Just look at senders of #refetched . (not refetch!) It is quite
> simple,
> actually.
>
> To see a bit more on how lists are used, see references to
> PluggableListMorph. The second is #buildMorphicMessageCatList. See
> how
> it parametrizes the instance it builds. These methods that create
> various lists are quite similar, and all they do is to bind each
> list
> with a different aspect of the model. In this case, with
> #messageCategoryList. See implementors and senders. It is clear that
> the
> implementors are methods in models that answer (guess what!!!!) a
> list
> of message categories. When you look at senders senders, you can see
> that some are in the model, doing things like 'self changed:
> #messageCategoryList'. It is easy to see that this means that the
> list
> of message categories have changed, and anybody depending on that
> should
> update itself.
>
> Now we have a detail that is not that obvious, and most likely the
> clue
> you need to understand this all. See implementors of #update: in
> PluggableListMorph and the other PluggableMorph classes. #update:
> compares the argument with the listGetter (or the appropriate ivar
> for
> each morph). So, when the model does 'self changed:
> #messageCategoryList', all dependent morphs get  message 'eachMorph
> update: #messageCategoryList'. And only those morphs that were
> configured to watch on this symbol with react.
>
> As I said before, this is the changed/update mechanism in MVC in
> Smalltlk-80.

Ah. That's the key - I haven't looked at MVC in years. The model need not know about any
view. It is the dependee, signalling happenings that the dependents might like to know. What
dependents do starts with their #update: message which may take action after looking at the
parameter (or not). The views are dependents of the model.

It's misleading when parameters of #changed: look just like message selectors in the model.
It gives the impression that those messages are to be sent or invoked, when all that's
necessary is that the parameter be understood by the model. That is why it looks like infinite
recursion when a method says:

refetched
        ...
        self changed: #refetched.

Far better if the parameter was "foobar or #putDataInTheTextMorphs or the like.

> Using #when:send:to: insted would lead to better code.

I will definitely start doing that.

> But
> documenting the current state of the system is needed and
> important,

With this insight, I may be able to do that now.

 - Dan

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: PluggableListMorph

Dan Norton
In reply to this post by Dan Norton
Hello All,

Please review the following for accuracy. It's not complete. It's a start on a "Principles of
Operation" for applying PluggableListMorph for fun and profit. Maybe it should be called
"PluggableListMorph for Dummies". I'm especially interested in whether you agree with the
"coincidental" statement.

PluggableListMorph is designed to work as part of one or more views on a model in the MVC
paradigm (Note 1). The model is not directly aware of the existence of any view; instead, it
signals changes in itself by broadcasting symbols with the #changed: method. In this way,
any view which is related to the model can detect the changes by examining the symbol in its
#update: method. Thus while the model is not explicitly aware of a view, there is an implicit
relationship in that a view must know the significance of the symbols broadcast by the model
in order to respond appropriately. Views are dependents of a model and therefore the model
is a sponsor of views. Use of the #changed: and #update: methods is the essence of the
Smalltalk dependency mechanism (Inside II).

The model sends #changed: and as a result, all dependents (e.g. views) on it receive
#update:. In the #update: method, the view examines the symbol and decides what, if
anything, to do. While the symbol  is, in practice, often identical to the name of a method, this
is coincidental and unfortunately a source of confusion and misdirection.

Note 1. The MVC paradigm is mentioned here for historical context. PluggableListMorph can
also be employed in other design schemes.

Inside II. LaLonde and Pugh, "Inside Smalltalk, Volume II"

Thanks,
 - Dan



_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: PluggableListMorph

KenDickey
Hi Dan,

Good explanation.  I like good explanations.  8)

You might be interested in the code examples in:

http://stackoverflow.com/questions/17082576/implementing-the-observer-pattern-in-smalltalk-visualworks

I would note that the observer pattern discussion might be better served by the more modern #when:send:to: idiom.  [E.g. look at when:send:to: senders; Check the TaskBar for simple usage].

In particular, an observer can register for event updates and get a specific message.

IMHO we should rewrite PluggableListMorph to use when:send:to:

$0.02
-KenD

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
-KenD