4.5 -- how should we proceed then?

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

4.5 -- how should we proceed then?

Chris Muller-4
It's fascinating how my compadres whom I've known on-line for so long
would stretch their logic so thin just to pile-on Chris.

I'm kind of stunned.  I'm just trying to get 4.5 ready and asking for
help with Environments because that's what's been holding up the
release.  I have little interest in Environments myself, but after no
progress for the last two months, I figure for the sake of the release
I'll work to fix it up myself.

This VERY FIRST tiny little refactoring improvement simply to help me
read and understand the code, and bring it to consistent standard and
quality with the rest of the image, is met with confused resistance
from Frank.  He _totally_ misunderstood and misstated what was being
done (he thought it was set:, set:, set:, which is wrong).  Suddenly,
Colin is alive and jumps in with "Frank is right" and confirms his own
mutual mis-understanding.  After banging my head on the wall for 3
days showing why Frank was NOT right, now Levente piles on.

Do you all understand you're actually fighting to _defactor_ the code?
 My god who are you poeple?!

I thought we had settled this issue about #new and #initailize YEARS
ago!  Let's see, yep.  Behavior>>#new:

   "Noury Bouraqadi 8/23/2003 14:51 · instance creation · 93
implementors · in no change set · "

But hey, if you guys want to lurch back to 2002 and your code repeat
itself over and over again with ^self basicNew initializeWith... or
^self basicNew initialize in every constructor, go right ahead.
There's nothing like "standards" especially when there are so many to
choose from, huh?

I just want to make progress on 4.5.  Am I the only one?  Now I feel
handcuffed -- so what now?

Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Frank Shearar-3
On 23 December 2013 17:31, Chris Muller <[hidden email]> wrote:
> It's fascinating how my compadres whom I've known on-line for so long
> would stretch their logic so thin just to pile-on Chris.
>
> I'm kind of stunned.  I'm just trying to get 4.5 ready and asking for
> help with Environments because that's what's been holding up the
> release.  I have little interest in Environments myself, but after no
> progress for the last two months, I figure for the sake of the release
> I'll work to fix it up myself.

And I appreciate it - your first touching of the Environment code -
making that unit test pass - spurred me on to actually try use it. As
a result, we have a first draft of loading Monticello definitions into
an Environment, and it's your commit (Monticello-cmm.579) that started
the ball rolling.

I don't know quite what you mean by "no progress": I don't know if you
mean around Environments, or around fixing bugs in 4.5. We've
certainly made a fair amount of progress in untangling module
dependencies!

Why do you think Environments is holding up the release? No one is
seriously using Environments yet, so if we released 4.5 right now, no
one would run into the limitations the tooling (Browser, etc) have
around Environments.

> This VERY FIRST tiny little refactoring improvement simply to help me
> read and understand the code, and bring it to consistent standard and
> quality with the rest of the image, is met with confused resistance
> from Frank.  He _totally_ misunderstood and misstated what was being
> done (he thought it was set:, set:, set:, which is wrong).  Suddenly,
> Colin is alive and jumps in with "Frank is right" and confirms his own
> mutual mis-understanding.  After banging my head on the wall for 3
> days showing why Frank was NOT right, now Levente piles on.

I'm sorry that you feel that way, Chris. I find your taste in UI
design impeccable. I just happen to disagree with part of the changes
in Environments.

> Do you all understand you're actually fighting to _defactor_ the code?
>  My god who are you poeple?!
>
> I thought we had settled this issue about #new and #initailize YEARS
> ago!  Let's see, yep.  Behavior>>#new:
>
>    "Noury Bouraqadi 8/23/2003 14:51 · instance creation · 93
> implementors · in no change set · "
>
> But hey, if you guys want to lurch back to 2002 and your code repeat
> itself over and over again with ^self basicNew initializeWith... or
> ^self basicNew initialize in every constructor, go right ahead.
> There's nothing like "standards" especially when there are so many to
> choose from, huh?

Do you mean "initialize" or "initializeWithSomething" in the "in every
constructor" part? Because as has been said a few times, _you don't
call initialize all over the place_. You call it _once_, from your
#initializeWith:all:the:things:.

It would be a very sad state of affairs if best practice didn't ever
improve! And I view the basicNew initializeWith: idiom _as_ an
improvement, because it makes it clear that you have, halfway through
the process, a semi/uninitialised object. If I could, I'd get rid of
setters entirely, and you could only ever construct a valid object.
Smalltalk just doesn't work that way, and you can only set instvars
through setting a message, so I make do with the closest I can get:
basicNew initializeWith:.

> I just want to make progress on 4.5.  Am I the only one?  Now I feel
> handcuffed -- so what now?

I can sympathise with your feelings of frustration. What stops you
from simply doing other stuff on 4.5? There's oodles to do. I wouldn't
mind some playing with Monticello-fbs.581 in the Inbox: getting that
working will also flush out Environment bugs.

One thing no one's ever discussed yet, and an area in which you happen
to excel, is thinking about how the tools should look when dealing
with Environments. For instance, if you import the Control package
into an Environment, and browse something in that package -
DelimitedDynamicVariable, say - the Browser shows only that
Environment. It doesn't show any imported classes. Is this a good
thing? If we should see imported classes, how should we indicate the
declared versus referenced classes in the tooling?

But if you feel like you've hit a complete brick wall, why not switch
focus for a while? Grab one of the other things we want for 4.5, and
hack on that. Or squash a bug on bugs.squeak.org.

frank

Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Colin Putney-3
In reply to this post by Chris Muller-4



On Mon, Dec 23, 2013 at 12:31 PM, Chris Muller <[hidden email]> wrote:
I just want to make progress on 4.5.  Am I the only one?  Now I feel
handcuffed -- so what now?

Let's keep arguing. Seriously! I know it's frustrating—I've been grinding my teeth over some of your posts myself. But as long as we stay focused on the substance of the issue, and don't let the frustration translate into personal antagonism, we could gain something from the collision of ideas here.  This list is a lot more harmonious these days than it has been in the past, so we can afford a bit of debate. I'm sure Frank feels that way too. 

Have a look at the example code I posted, and tell me what's wrong with it, and we'll go from there.

Colin


Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Chris Muller-3
In reply to this post by Frank Shearar-3
>> But hey, if you guys want to lurch back to 2002 and your code repeat
>> itself over and over again with ^self basicNew initializeWith... or
>> ^self basicNew initialize in every constructor, go right ahead.
>> There's nothing like "standards" especially when there are so many to
>> choose from, huh?
>
> Do you mean "initialize" or "initializeWithSomething" in the "in every
> constructor" part? Because as has been said a few times, _you don't
> call initialize all over the place_. You call it _once_, from your
> #initializeWith:all:the:things:.

But there are initializeWith:all:the:things: method in each class
(that have parameterized constructors).  You don't get call that
"once".  "Once" means, truly, just _ONCE_ for all classes.  Uno.  From
Behavior>>#new.

"Once per class" is exactly what I mean by, "from all over the place".
 It denies to newbies reading class-side Constructor Methods that we
have resolved this issue about how default values of inst-vars (not
constructor parameters) should be initialized.

> It would be a very sad state of affairs if best practice didn't ever
> improve!

It's obvious you don't know me well when you think you have to tell me
that.  I'm the most rebellious one here..  :)

> And I view the basicNew initializeWith: idiom _as_ an
> improvement, because it makes it clear that you have, halfway through
> the process, a semi/uninitialised object. If I could, I'd get rid of
> setters entirely, and you could only ever construct a valid object.

You mention setters again but a Constructor Parameter Method is no
more a "setter" than a #printString is an "accessor".

Smalltalk's simplicity and unity means we have to rely more on
_conventions_, rather than language constructs, to delineate our
pattern language.

> Smalltalk just doesn't work that way, and you can only set instvars
> through setting a message, so I make do with the closest I can get:
> basicNew initializeWith:.
>
>> I just want to make progress on 4.5.  Am I the only one?  Now I feel
>> handcuffed -- so what now?
>
> I can sympathise with your feelings of frustration. What stops you
> from simply doing other stuff on 4.5? There's oodles to do. I wouldn't
> mind some playing with Monticello-fbs.581 in the Inbox: getting that
> working will also flush out Environment bugs.

My interest in is in getting the 4.5 _release_ done ASAP.  The only
tests which are faliing at this point seem to be the Environments ones
and a couple of Obsolete classes I think.  That's what led me here.

Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Frank Shearar-3
On 23 December 2013 21:43, Chris Muller <[hidden email]> wrote:

>>> But hey, if you guys want to lurch back to 2002 and your code repeat
>>> itself over and over again with ^self basicNew initializeWith... or
>>> ^self basicNew initialize in every constructor, go right ahead.
>>> There's nothing like "standards" especially when there are so many to
>>> choose from, huh?
>>
>> Do you mean "initialize" or "initializeWithSomething" in the "in every
>> constructor" part? Because as has been said a few times, _you don't
>> call initialize all over the place_. You call it _once_, from your
>> #initializeWith:all:the:things:.
>
> But there are initializeWith:all:the:things: method in each class
> (that have parameterized constructors).  You don't get call that
> "once".  "Once" means, truly, just _ONCE_ for all classes.  Uno.  From
> Behavior>>#new.

I fail to see how that (#initialize only ever being called from
Behaviour>>#new) is useful. #initialize can't initialise an object
properly, because it doesn't have the info that the constructor
methods give.

Setting these instvars post initialisation is, in my opinion, a smell.

Because "initialisation" in my book means setting the instvars of an
instance to the values they should be: "initialise a Point" means
setting its x and y instvars, for instance. #initialize cannot do
this, so is largely useless except in the rather special case of inst
vars not being set by constructor methods. (A class that memoised
calls might initialise its cache to Dictionary new, for instance.)

> "Once per class" is exactly what I mean by, "from all over the place".
>  It denies to newbies reading class-side Constructor Methods that we
> have resolved this issue about how default values of inst-vars (not
> constructor parameters) should be initialized.

You'll need to explain further what you mean here. I don't understand
what the distinction between default value of inst vars and of
constructor parameters might be. I guess you're saying that the
default values of instvars get set in #initialize while the default
values of constructor parameters are set by the way the various
constructor methods call each other? In that case my counterargument
is to not set the instvars in #initialize because you set them twice.

>> It would be a very sad state of affairs if best practice didn't ever
>> improve!
>
> It's obvious you don't know me well when you think you have to tell me
> that.  I'm the most rebellious one here..  :)

I suspect we might be fighting for that prize!

>> And I view the basicNew initializeWith: idiom _as_ an
>> improvement, because it makes it clear that you have, halfway through
>> the process, a semi/uninitialised object. If I could, I'd get rid of
>> setters entirely, and you could only ever construct a valid object.
>
> You mention setters again but a Constructor Parameter Method is no
> more a "setter" than a #printString is an "accessor".

The reason I keep dissing them as setters is because they only set
_some_ state. Now, granted, some like Point >> #setX:setY: happen to
fully initialize an instance, but the name does not make this
responsibility clear. But (the nonexistent) Point >>
#initializeWithX:y: tells you loudly and clearly that the method
initialises the instance. That "#initializeWithX:y" is ugly to look at
and painful to type is just gravy: you shouldn't be calling that
method anyway. (Scala's type check is called isInstanceOf, and its
cast operation called asInstanceOf, are named this way precisely as a
source of pain to make you think twice about doing the wrong thing.)

> Smalltalk's simplicity and unity means we have to rely more on
> _conventions_, rather than language constructs, to delineate our
> pattern language.

Sure.

>> Smalltalk just doesn't work that way, and you can only set instvars
>> through setting a message, so I make do with the closest I can get:
>> basicNew initializeWith:.
>>
>>> I just want to make progress on 4.5.  Am I the only one?  Now I feel
>>> handcuffed -- so what now?
>>
>> I can sympathise with your feelings of frustration. What stops you
>> from simply doing other stuff on 4.5? There's oodles to do. I wouldn't
>> mind some playing with Monticello-fbs.581 in the Inbox: getting that
>> working will also flush out Environment bugs.
>
> My interest in is in getting the 4.5 _release_ done ASAP.  The only
> tests which are faliing at this point seem to be the Environments ones
> and a couple of Obsolete classes I think.  That's what led me here.

Some tests will take a long time to get working: the exception handler
one, for instance. I _dislike_ making a release with failing tests,
but we're just not going to get a green light on the test suite within
any reasonable release window, without faking it through
expectedFailures.

There's only one failing Environment test, and that's the same kind of
failing test as the exception handler one: it's a marker for the later
stage of development. Environments work: all that test does is tell us
that there's work to do to load MC definitions into an Environment.

frank

Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Chris Muller-4
> The reason I keep dissing them as setters is because they only set
> _some_ state.

My goodness Frank.  After all this you still are saying that?!  Please
forgive me for correcting you one last time with emphasis.

*** CPM's set ALL STATE required for a well-formed, functional object ***.

That's also why I committed Environments-cmm.38 as a multi-variable example.

Setters set one variable.  **Constructor Parameter Methods set ALL
variables passed from a constructor**.  A Constructor is, by
definition, a method capable of "constructing" a well-formed instance.

> Now, granted, some like Point >> #setX:setY: happen to
> fully initialize an instance, but the name does not make this
> responsibility clear.

The name makes clear *what it does*.  If it's #initializeWith: -- you
better look at the method to know what it does besides set state..
Plus, a constructor can't ONLY set state, it implies some sort of full
"initialization".

But, I'm repeating myself from 3 days ago..   :)

> But (the nonexistent) Point >>
> #initializeWithX:y: tells you loudly and clearly that the method
> initialises the instance. That "#initializeWithX:y" is ugly to look at
> and painful to type is just gravy: you shouldn't be calling that
> method anyway.

Not any more than you should call setX:y:.  Seriously, have you ever
had the urge to call that?  I always check the protocol of methods I'm
unsure about, and if it's correctly categorized, then you're relying
on an ugly selector name, initializeWith: to "fix" something that
isn't broken.

But I'm sounding like a broken record so... later.  :)

Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Nicolas Cellier

2013/12/24 Chris Muller <[hidden email]>
> The reason I keep dissing them as setters is because they only set
> _some_ state.

My goodness Frank.  After all this you still are saying that?!  Please
forgive me for correcting you one last time with emphasis.

*** CPM's set ALL STATE required for a well-formed, functional object ***.

That's also why I committed Environments-cmm.38 as a multi-variable example.

Setters set one variable.  **Constructor Parameter Methods set ALL
variables passed from a constructor**.  A Constructor is, by
definition, a method capable of "constructing" a well-formed instance.

> Now, granted, some like Point >> #setX:setY: happen to
> fully initialize an instance, but the name does not make this
> responsibility clear.

The name makes clear *what it does*.  If it's #initializeWith: -- you
better look at the method to know what it does besides set state..
Plus, a constructor can't ONLY set state, it implies some sort of full
"initialization".

But, I'm repeating myself from 3 days ago..   :)

> But (the nonexistent) Point >>
> #initializeWithX:y: tells you loudly and clearly that the method
> initialises the instance. That "#initializeWithX:y" is ugly to look at
> and painful to type is just gravy: you shouldn't be calling that
> method anyway.

Not any more than you should call setX:y:.  Seriously, have you ever
had the urge to call that?  I always check the protocol of methods I'm
unsure about, and if it's correctly categorized, then you're relying
on an ugly selector name, initializeWith: to "fix" something that
isn't broken.


It's a bit late for changing that now, but it could as well be named initializeX:x y:y to carry the exact intention.
Not every body knows that you should set once, more people know that you should initialize once and only once.
So you could have just change With:, it would have been less controversial.

The other point being whether to invoke new or basicNew is more germane, but not invoking new is a way to tell my instances are not created like that. We could push it further and redefine new ^self error as you suggested, but it's quite heavy...
 
But I'm sounding like a broken record so... later.  :)




Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Chris Muller-3
> The other point being whether to invoke new or basicNew is more germane, but
> not invoking new is a way to tell my instances are not created like that.

It's a way to tell your instances not to initialize _default values_, if any.

If a var is added and you add an initialize method, oops.  You better
change your constructor too, ha ha...

> We
> could push it further and redefine new ^self error as you suggested, but
> it's quite heavy...

Default values.

Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Nicolas Cellier

2013/12/24 Chris Muller <[hidden email]>
> The other point being whether to invoke new or basicNew is more germane, but
> not invoking new is a way to tell my instances are not created like that.

It's a way to tell your instances not to initialize _default values_, if any.

If a var is added and you add an initialize method, oops.  You better
change your constructor too, ha ha...

Chris, that's not your best argument, what do you read here?
^self basicNew initializeWith: prefix
                        ^^^^^^^^^

Did you browse HashedCollection>>new: as I suggested?
It does not send #new, nor #initialize but #initialize:
This is fairly common in Squeak.
 
> We
> could push it further and redefine new ^self error as you suggested, but
> it's quite heavy...

Default values.

Nah! We ain't gonna need such mock-ups, or we'll explicitely create some.


Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Nicolas Cellier

2013/12/24 Nicolas Cellier <[hidden email]>

2013/12/24 Chris Muller <[hidden email]>
> The other point being whether to invoke new or basicNew is more germane, but
> not invoking new is a way to tell my instances are not created like that.

It's a way to tell your instances not to initialize _default values_, if any.

If a var is added and you add an initialize method, oops.  You better
change your constructor too, ha ha...

Chris, that's not your best argument, what do you read here?
^self basicNew initializeWith: prefix
                        ^^^^^^^^^

Did you browse HashedCollection>>new: as I suggested?
It does not send #new, nor #initialize but #initialize:
This is fairly common in Squeak.
 

Not my best answer too, when I re-read it... ;)
Colin has revendicated the right to call self initialize from within initializeWithXXX: initializer.
You denied this right because that would open the door to arbitrarily ignore initialize.
But I think you are mistaking here.
Indeed, contrarily to what you said, each initialize SHOULD call another initialize (*), that is super initialize.
So once we agree that initializeWithXXX is a proper initialize method as HashedCollection>>initialize: is,
The problem is solved and we can revert to previous version.

(*) except intentionnally in well known cases
 
> We
> could push it further and redefine new ^self error as you suggested, but
> it's quite heavy...

Default values.

Nah! We ain't gonna need such mock-ups, or we'll explicitely create some.



Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Chris Muller-3
> Colin has revendicated the right to call self initialize from within
> initializeWithXXX: initializer.
> You denied this right because that would open the door to arbitrarily ignore
> initialize.

Yes, that is the core of my complaint.  I just cannot help to believe
all code should be at the highest level it can be.  I think it
provides better accessibility to a kind of system scripters and
app-developers want to use.

> But I think you are mistaking here.
> Indeed, contrarily to what you said, each initialize SHOULD call another
> initialize (*), that is super initialize.

As the aforementioned rebel that I am, I'm afraid "should" usually
leaves my curiosity unsatisfied.  However, I can understand the appeal
of wanting to see all initialization right there in one designated
initializer method, including even the line that does the
default-values.

> So once we agree that initializeWithXXX is a proper initialize method as
> HashedCollection>>initialize: is,
> The problem is solved and we can revert to previous version.

Out of respect for Colin and democracy and progress, I will revert the changes.

I've been writing Constructor Parameter Methods for 20 years.  I won't
change others' code about this again, but I must continue using my
style for my own trunk contributions.

Reply | Threaded
Open this post in threaded view
|

Re: 4.5 -- how should we proceed then?

Tobias Pape

On 25.12.2013, at 04:16, Chris Muller <[hidden email]> wrote:
> […]
> I've been writing Constructor Parameter Methods for 20 years.  I won't
> change others' code about this again, but I must continue using my
> style for my own trunk contributions.

I think this is the way to go. :)
Thank you Chris and thank you all other discussion participants
for investing effort in good design.
  I think it is worthwhile to note that all here tried to
reach the best style.

Code on!

Best
        -Tobias





signature.asc (1K) Download Attachment