Aleksi Niemelwrote:
> 
> First, I have to confess, Mark, that I fought with the issue too. Nowadays
> I'm calmer, as after few surprises one gets used to that :).
> 
> However, while you're right with your claim, you have to note the
> inconsistency could be detecetd only against some rule set. And in this case
> the rule set is quite simple, compact, and well working:
> 
>   1) plain method name doesn't say anything about state desctructive
>      or preserving nature
>   2) '!' in the end of the method name wakes you up. Now we're really
>      modifying receiving object instead of the usual thing, where
>      we return a new modified object.

This rule can be augmented in a way that makes everybody happy, even me,
and steps on nobody's toes.  Skip down to the end of this message to see
my proposal, but first I'll respond to some of these good points...
 
> So if your rule-set was something different, like mine was, you probably
> find yourself thinking why every state-modifying method isn't named with !.
> The reason is that most methods modify receiver's state, thus the code would
> be full of exclamation marks. Matz did see this, and started to use another,
> quite natural and little suprising, rule set. The one in my previous mail,
> and above.
> 
> Here Least Surprise was dismissed for the Friendly Source code. But it
> didn't manage to go far away, before there was again room for it.

Right.  The reason most methods modify receiver's state is that Ruby
isn't being used by most of us as a fundamentally functional language. 
Thing is, there's nothing in the essence of the language to _keep_ it
from also being used that way; ruby is really quite well suited for it,
and it comes down to a matter of what methods are supplied, as
functional-style code tends to rely more on constructors, and "indirect
constructors" (sorry, is there a technical name for that? I just mean
methods that return an object of the same type as the receiver, like
"succ" and many others).  My problem with the naming rule as it stands
is that it indicates a limiting assumption about the kinds of code
people will write.

> > |a use for a non-destructive array insert whereas to me it might sound
> > |just as natural and sensible as non-destructive string concatenation.
> 
> Humm..first, it's better to use state-modifying or something else than
> destructiveness to describe or call 'methods!'. Second, what are
> non-destructive string concatenation or array insert? Is non-destructive
> string concatenation an operation which doesn't change the state of the
> string object, thus the only possible catenation would be aString + "" and
> everything else rejected with an exception.
> 
> By the way did you notice how natural the previous aString.+("") looked.
> Would you like to say aString.+!("")?

Maybe I'm missing something here.  All I was trying to say is that
everybody recognizes the naturalness, and usefulness, of string
concatenation that doesn't modify the receiver, as in the "+" operator,
which returns a different string.  It isn't so obvious to everyone that
it might be nice to have an array insert method that returns a shallow
copy of the array reflecting the results of the specified insertion. If
it were available, I would use it all the time in preference to the
other; maybe that's just me, but if not, then surely modification of the
receiver isn't so clearly indicated by the method name.  I wouldn't
suggest there must only be non-destructive methods, that's not the
point.
 
> > |Naming a destructive method without the ! ties our hands
> 
> This is very good point!
> 
> Would you like to try what it's like to live in properly named world by
> creating a somewhat complete aliasing module, changing current
> state-modifying methods to have an exclamation mark etc.?

No, I guess not.  I mean, when I first looked at the usage of '!' I was
just convinced it was a mistake. You've convinced me that it is not -- I
don't agree with it, but I can also see it's not crazy.  And of course
there's the problem of messing up existing code.

So, instead I suggest standardizing a way to name a non-state-modifying
method when the unbanged name is already in use, such as a trailing
underscore.  Then we have:

  1. ends in '!': receiver's state changes.
  2. ends in '_': receiver's state guaranteed not to change.
  3. Otherwise consult (cough, cough) common sense, or documentation.

If we don't like '_', we can make it something else.  RFC?

 -- Mark