[squeak-dev] Preferences revamp redux

Eliot Miranda eliot.miranda at gmail.com
Mon Dec 19 20:24:14 UTC 2016


Hi All,

    replying to an earlier message now we have a good subject line :-)


On Sat, Dec 17, 2016 at 2:25 PM, Chris Muller <asqueaker at gmail.com> wrote:

> Gentlemen, may I ask what you thought of my list of requirements?
>
>    http://lists.squeakfoundation.org/pipermail/squeak-dev/2016-
> March/188486.html


I like some of them.  To be specific...

1.  I see no need for Preferences except as a UI tool.  Preferences are
used to control parts of the system that can have useful alternative
behaviors.  Having a Preferences UI is useful as it
- informs the user of the set of available preferences and documents them
- provides a convenient UI for setting them
But it is /much/ more preferable for the code that is affected by a given
preference to use its own state to determine the value of the preference:
- the application can continue to work if Preferences is unloaded
- the application does not have to restrict itself to the Preferences style
and can use something it finds convenient

2. very useful; can easily be derived from pragma preferences

3. Not sure symbolic names are useful.  A user readable name is useful, but
an additional symbolic name is just cruft

4. OK, again something that can be included in pragma preferences (and
indeed derived from code if the pragma method is stereotypical enough;
which it should be)

5. Not sure preferences need to specify the domain of values; boolean
preferences are easy, but, take, say, a repository URL.  I don't think it
makes sense to restrict this to a fixed set of valid URLs.  So not too sure
about 5.

6. Sure.  Again something that can be done with pragma preferences

7. Sure.  Can be constructed from 2. 4. and ability to access current value.

7.5, 7.6 why?  Don't see any pressing need for these.  Seem to be forcing a
Dictionary implementation.

8.  Sure.  Again a preference saving/loading mechanism is not antithetical
to pragma preferences.

9.  Sure

10.  That's what pragma preferences do.  That's one of the major advantages
of pragmas in general.  They allow code to be labelled with semantic
information that applies not to the code's function, but to its context in
a broader system.  They allow that labelling to be associated with the code
to be labelled, not be in a collection of labelling that collide when
considering different sets of code to be labelled.

These were derived through careful consideration of the real-world use
> cases, both for Squeak and external applications.  They are open for
> discussion, of course!
>
> We don't need a special language feature to provide a simple and
> elegant wrapping of a Dictionary.  We just need to get back to
> Smalltalk and objects.
>

Um, why is a Dictionary a valid representation of preferences?  A
dictionary might adequately tell us the current state of the system's
preferences.  But as we've seen above we need a lot more, default value,
documentation, UI for changing, save/load framework.


> We're in agreement.  The pragma approach has two main advantages; one it
> to
> > identify and allow documenting methods that provide preferences,
>
> I honestly think we don't need pragmas to do it.
>

I was agreeing with Bert, not you.  You and I clearly disagree.


> > the other
> > is in being modular, in that the pragma method can live in the package to
> > which it belongs.
>
> Let's not let package concerns dictate the design.  Let's make the
> right design for users, *then* optimize out any packaging issues that
> may arise.  There's no reason Preference accessors can't just as
> easily live in the package they belong without needing to use pragma's
> and class-vars.
>

This is not about Monticello packages.  It is about complex systems being
composed of components.  Of course I want to deploy a system which is a
subset of a more complex one.  Of course I should be able to discard the
Preference UI if my application doesn't (or more importantly, can't or
shouldn't) support it.

>> But having to implement preference storage over and over again is not the
> >> best solution. But that's what the current pragma prefs require - a
> setter
> >> and a getter and a class var and logic for initialization and if a
> class has
> >> many prefs then maybe a prefs dictionary because too many class vars are
> >> annoying etc. pp.
> >
> >
> > Well, in the case where code wants to update the preference I think the
> > setter is acceptable,.  But it ould be nice if the Preferences package
> could
> > infer how to set the variable from the getter, something i think is
> fairly
> > trivial if the getter returns a class var (or even a class inst var?).
> > Also, the getter can (and should) provide the initialization if the body
> is
> > written as
> >
> >     ^Var ifNil: [Var := true/false/aSymbol]
>
> That's what I thought too, and why I originally argued against
> answering arbitrary default value of false, before agreeing, but then
> someone mentioned that the developer could have easily misspelled it,
> causing a hidden bug.  I couldn't agree more, and that seems like it
> really dilutes any net gain for the user.  Its complex and magic,
> instead of just simple.
>

It's not complex or magic.  It's code.  It's an assignment.  The "magic" is
the ability to decorate that code with information that
- states that this is a system preference
- documents its purpose
- identifies it to tools that want to collect the set of system preferences
- etc

> So with this approach and help from the Preferences framework one should
> be
> > able to get away with just the getter, whose pragma should; include the
> > help[ text, etc, and the revised class definition to declare the class
> var.
> > I'm happy to pay that cost for the modularity and documentation.
> >
> >> Having actual Preference objects managed by a Preferences class takes
> care
> >> of all of that, once and for all.
> >
> >
> > The main problem is that while a preference object can encapsulate the
> same
> > state as the pragma preference getter method, one also needs code to
> create
> > the object and add it to the framework.  It's that that makes the two
> > essentially similar in cost, and makes me dislike the preference objects.
> > The preference getter method stands alone, and so can be added and
> removed
> > freely.  In a class such as Compiler or Parser where one may have several
> > preferences, one ends up having to edit the method that adds preferences
> > whenever adding or removing a preference.  There's a collision.  The
> pragma
> > approach solves these collisions by providing an implicit way to add a
> > complex object.  Its analogous to how pragma menu actions allow menus to
> be
> > extended without collision between different extensions.
>
> A pure-Smalltalk pattern can do it.  If we want to co-locate access
> and the default value in a lazy accessor like this.
>
>   somePreference
>      ^ (Preferences somePreference ifNil:
>             [ Preferences
>                  addPreferenceNamed: #somePreference
>                  description: 'When true it means...'
>                  default: theDefaultValueForSomePreference ]) value
>

As others have said the above is way more complex than a pragma
preference.  It also ties the application to the Preference UI.


>
> #somePreference resides in the package it lives in, of course.
>
> Okay, accessing the list of all preferences (requirement 2, from my
> list) could be done by enumerating all the methods in the system which
> are in a 'preferences' category, or something like that.
>

Um, no.  Enumerating all classes and looking for methods with the relevant
pragma(s), yes.


> Protocols is something that's part of Smalltalk forever, we should
> leverage it more.  We could bring more power to the system with some
> simple toolage over of our "protocols" that can browse such
> programmatic usages..
>

Dangerous.  Smalltalk/V doesn't have them.  They're not in the ANSI
standard.  I've used them and like the power, but they can be like perform
on constructed strings, non-obvious.

The current pragma approach with class-vars makes it impossible to
> meet the basic requirements at all.
>

No it does not.


> It also takes our deployment image from being a pure-and-simple,
> traditional Smalltalk -- of just classes, objects and messages -- and
> tacks on a new computery whiz-bang concept called a Pragma.  Now, a
> lot of users' eyes are gonna glaze over.  They're done.  Their hope
> that Squeak was an empowering application tool-kit for non-nerds has
> been quashed.  It's in-the-weeds programming afterall.   :(
>

Um, pragmas are in the base system for things like unwind-protect and
primitives.  The syntax has been there since Smalltalk-80 (or even 76?).
Message has been there from the get-go.  Pragmas are proving themselves
useful in many contexts.  They can no longer be considered whizz-bang
magic.  We use them a lot.  They're nice exactly because one mechanism has
general uses, unlike, for example, the Preferences framework, which ties
code to a clumsy "wrapping of a dictionary", instead of allowing code to
express itself as it chooses, and identify its choices to external tools to
operate upn it only when desirable..

> But to achieve
> > this elegance the pragma scheme must be thought through; for example
> > extending the Preference system to allow preferences to be set without
> > needing preference setter methods (and maybe even modifying the compiler
> to
> > declare variables in pragma preference methods as class vars?).
>
> It's just a wrapped Dictionary!  Isn't it?
>

No.  Not at all.  A Dictionary may be a useful thing to present in response
to 2. but other than that its implementation driving design.


>
> Friends, IMO, Squeak's potential beyond our little group of developer
> dudes lies in the how well we can bring the power of the class library
> to regular, non-programmer *users*.  People who don't identify
> themselves as programmers, but want something more powerful than a
> spreadsheet.  Right now, I believe that's still possible.  But I
> believe designing Squeak around our developer-centric selves,
> increasing usage of whiz-bang language features will not get us there.
> IMO the philosophy of staying as simple and traditional and fighting
> complexity as long as we possibly can, will improve chances of wider
> adoption.
>

Um, pragmas are in quite a few Smalltalks now.  And I've already defended
them against the whizz-bang accusation.


>
> IMO, we should just do Smalltalk and objects.  1) Get rid of teh class
> vars, 2) change the getter/setters to access Preferences
> wrapped-dictionary, which still compiles dynamic accessors, if
> necessary, and 3) hopefully also ditch the pragmas in favor of a
> protocol selection.
>

Couldn't disagree more :-)


>
> Best.
>

_,,,^..^,,,_
best, Eliot

On Mon, Dec 19, 2016 at 10:21 AM, Chris Muller <ma.chris.m at gmail.com> wrote:

> >> Gentlemen, may I ask what you thought of my list of requirements?
> >>
> >>   http://lists.squeakfoundation.org/pipermail/squeak-dev/2016-
> March/188486.html
> > IMHO the first point is not a requirement (what?) at all but a solution
> (how?).
>
> It depends on who your actor is.  I get your point when the
> actor is an end user playing with an iPad, but requirement #1 is
> trying to assert that the type of actor for *these* requirements is a
> non-programmer user who wants to write a little code or make a little
> application that might have a Preference or two.  In that case, the
> requirement is that we have a simple, easy to understand English-based
> class hierarchy, and not computery terms.
>
> We already have it anyway, so we don't even need to discuss this..
>
> >> I honestly think we don’t need pragmas to do it.
> > I agree but I cannot understand why you seem to hate pragmas.
>
> Whoa, I don't "hate" pragma's at all, they're an important capability,
> I'm simply saying that using them for our Preferences system makes a
> design that is not only unnecessarily complex and confusing but
> embarassingly bad and incapable.  We're supposed to be the language of
> "objects" but can't even represent a template of Preferences to solve
> the most basic of requirements, like #7..!
>
> Meanwhile, Marcel's new Themeing implementation solves the same
> problem with a fraction of the code and complexity, and yet is 10X
> more powerful.  Its a leveraged design based on objects, instead of
> diluted based on dozens of global variables..
>
> >>> the other
> >>> is in being modular, in that the pragma method can live in the package
> to
> >>> which it belongs.
> >>
> >> Let’s not let package concerns dictate the design.
> > IMHO packaging concerns are very important design drivers. I consider
> missing modularity one of the main problems with Smalltalk.
>
> Don't worry, our packaging system is flexible enough that we don't
> need to limit our design because of packaging (a developer activity,
> BTW).  As I showed earlier in this thread, Pragma preferences provide
> no benefit in the area of packaging, every preference accessor can
> still be in its own package.  The new theming implementation proves
> this, too.
>
> >> snip...
>
> > I don’t understand why you consider pragma more computery whihz-bang
> than classes, objects and messages. I’d even say they are much simpler to
> understand than metaclasses. And pragmas are in all commonly used Smalltalk
> implementations by now.
>
> Because they represent metadata about something "in the computer"
> rather than a description of the domain which the power-user actor
> cares about.
>
> They're supposed to represent information about methods of the system.
> Using them for the user domain models is a confusing mis-use.
>
> We *really should* try harder to target users besides our developer
> selves.  Please?  Smalltalk was the only system in which users can
> learn to program without learning or caring anything about computers.
> If they have to become programmers, then suddenly the whole menu of
> more popular languages like Python or Ruby becomes just as accessible
> to them.  We keep trying to nullify our Smalltalk advantage..  :(
>
> >> IMO, we should just do Smalltalk and objects.  1) Get rid of teh class
> >> vars, 2) change the getter/setters to access Preferences
> >> wrapped-dictionary, which still compiles dynamic accessors, if
> >> necessary, and 3) hopefully also ditch the pragmas in favor of a
> >> protocol selection.
> > Please no.
>
> What about requirement #7?
>
>


-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20161219/4777c725/attachment.html>


More information about the Squeak-dev mailing list