Restricted unsigned integer range would have been better?

T

Tim Rentsch

glen herrmannsfeldt said:
Tim Rentsch said:
[considering n = n * 10 + (*s - '0') vs n = *s-'0' + n*10 ]
It was conscious, because I had to consider whether to add the
parentheses. In my usual work environment, they wouldn't
matter, so I would very likely leave them out. In this
newsgroup, little omissions like that can get you attacked
without mercy. :) So I did think about whether to put in the
parentheses, and that caused me to carefully consider the whole
expression.
Sorry, I wasn't clear. What I was (and am) curious about is
the choice between putting the multiplication term first or
second. Were both of those among the alternatives you
considered? (And, unimportant side issue: how about 10*n
instead of n*10?)

Usual math notation for polynomials puts the higher powers on
the left, and the coefficient to the left of the variable.
[snip elaboration and unrelated]

I don't find this idea very compelling either as explanation or as
argument. That is one common notation, but certainly not the only
one. Also it's true that the expression in question happens to be
a polynomial, but I expect that observation would not occur to
most software developers who write code to do such things. At
best it suggests there may be an unconscious habit of writing the
multiplication first, and probably there is some truth in that,
but that's a far cry from making an aesthetic choice. It seems
much more likely that people tend to write the multiplication
first simply because the first textbook or example they read of
how to do base conversion used 'n*10 + digit', or something
similar, in its code.
 
P

Philip Lantz

Tim said:
Philip said:
Tim said:
Philip Lantz writes:
pete wrote:
Tim Rentsch wrote:
pete writes:
Philip Lantz wrote:
[..snip..snip..]

5. while (*s != '\0')
n = n * 10 + (*s - '0');

If n is of type int and also not negative,
then you could write without having to use parentheses
n = n * 10 - '0' + *s;
with no possibility of overflow.

Is there some reason you wouldn't write

n = *s-'0' + n*10; /* or add more spacing, if preferred */

?


Not any good reason.

I have an aesthetic preference
for writing the more strongly associated arithmetic operators first.

I think aesthetics *is* a good reason for writing code a certain way.
[snip elaboration]

Sure, but not the only one. In writing, for example, it is my
preference not to split an infinitive. Sometimes, though, it's
awkward to just blindly follow that rule. In the particular
case here (ie, in assigning to n), IMO there is very little
difference aesthetically between the two writings, and the
second one even might be a little easier to digest when reading
it. Partly I was curious how much of the choice was an actual
conscious process and how much was doing things a particular way
just because that's the way the author is used to doing them.

It was conscious, because I had to consider whether to add the
parentheses. In my usual work environment, they wouldn't
matter, so I would very likely leave them out. In this
newsgroup, little omissions like that can get you attacked
without mercy. :) So I did think about whether to put in the
parentheses, and that caused me to carefully consider the whole
expression.

Sorry, I wasn't clear. What I was (and am) curious about is
the choice between putting the multiplication term first or
second. Were both of those among the alternatives you
considered? (And, unimportant side issue: how about 10*n
instead of n*10?)

It was clear--I only made the comment about the parentheses because it
caused me to consider the entire expression somewhat more carefully that
I might have otherwise. Hence I can say with confidence now, weeks
later, that it really is what I wanted to write, not just what I
happened to type first.

I think of the expression as "what I'm doing to n": multiplying it by 10
and adding something. So I write it in that order. I didn't consider
other specific alternatives, but I considered whether the expression as
written said what I wanted it to say. (I'm writing this as applied to
that one situation, but I'm describing my usual way of writing code,
which is, of course, the point.)
I mentioned one in the posting. Did you not see that?

No, and rereading both the context above and your original response, I
still don't see it.
Not exactly. I have seen reasons stated for preferring

if(0==*s) // or some other constant besides 0

over

if(*s==0)

but I don't remember that reasoning being extended to the '!='
operator. It is of course possible to make an indirect argument
for the '!=' case, based on the proposed argument for the '=='
case, but I don't remember it (either the case or the indirect
argument) being discussed. So I still don't know of any direct
reason to prefer 0 != *s to *s != 0.

<laugh> Of course, you're right. Since I have never liked that approach,
I didn't even think about the difference in applicability between == and
!=.
What I said was the writing with the '*' done second might be
easier to digest; because that formulation doesn't have (or
need) parentheses, they don't have to be scanned, and no mental
effort is required for why they might be necessary, unlike the
formulation that does have parentheses.

I disagree completely. The precedence of operations is critical to
reading the expression, and the mental effort required to understand
that precedence is not increased in this case with the parentheses
explicit. (Of course, this only applies with a very limited number of
parentheses, as in this example; I certainly am not encouraging lots of
redundant parentheses.)
If I may be philosophical for a moment, IME reactions on style
issues (considering this case purely a style issue, which of
course it isn't, at least not purely)

Again you say this isn't purely a style issue, but I still haven't seen
you say what, specifically, you regard as a non-style issue here. I'm
beginning to think that you and I have different ideas as to what
constitutes style. The only reason I see above that you give for a
different way of writing this is that it "might be easier to digest".
That seems to me to fall *completely* within the bounds of
style/aesthetics. (To me those two words cover the same ground.)
In many cases there is
no reason to prefer strongly one style over another, and when
that holds consistency with local custom should dominate. In
other cases there are good and compelling reasons for preferring
one style over another, and in those cases it is important to set
or influence local custom to go in the right direction. And
finally, it's almost never true that following a single style
choice in every circumstance, and without any alternative or
exceptions, is the best course of action. When advocating a
particular style choice (for a class of situations, but one
particular choice to apply to those situations), it's important
to discuss the limits or possible exceptional circumstances when
an alternate choice might be better.

I agree completely.
 
T

Tim Rentsch

Philip Lantz said:
Tim said:
Philip said:
Tim Rentsch wrote:
Philip Lantz writes:
pete wrote:
Tim Rentsch wrote:
pete writes:
Philip Lantz wrote:
[..snip..snip..]

5. while (*s != '\0')
n = n * 10 + (*s - '0');

If n is of type int and also not negative,
then you could write without having to use parentheses
n = n * 10 - '0' + *s;
with no possibility of overflow.

Is there some reason you wouldn't write

n = *s-'0' + n*10; /* or add more spacing, if preferred */

?


Not any good reason.

I have an aesthetic preference
for writing the more strongly associated arithmetic operators first.

I think aesthetics *is* a good reason for writing code a certain way.
[snip elaboration]

Sure, but not the only one. In writing, for example, it is my
preference not to split an infinitive. Sometimes, though, it's
awkward to just blindly follow that rule. In the particular
case here (ie, in assigning to n), IMO there is very little
difference aesthetically between the two writings, and the
second one even might be a little easier to digest when reading
it. Partly I was curious how much of the choice was an actual
conscious process and how much was doing things a particular way
just because that's the way the author is used to doing them.

It was conscious, because I had to consider whether to add the
parentheses. In my usual work environment, they wouldn't
matter, so I would very likely leave them out. In this
newsgroup, little omissions like that can get you attacked
without mercy. :) So I did think about whether to put in the
parentheses, and that caused me to carefully consider the whole
expression.

Sorry, I wasn't clear. What I was (and am) curious about is
the choice between putting the multiplication term first or
second. Were both of those among the alternatives you
considered? (And, unimportant side issue: how about 10*n
instead of n*10?)

It was clear--I only made the comment about the parentheses
because it caused me to consider the entire expression somewhat
more carefully that I might have otherwise. Hence I can say
with confidence now, weeks later, that it really is what I
wanted to write, not just what I happened to type first.

I think of the expression as "what I'm doing to n": multiplying
it by 10 and adding something. So I write it in that order. I
didn't consider other specific alternatives, but I considered
whether the expression as written said what I wanted it to say.
(I'm writing this as applied to that one situation, but I'm
describing my usual way of writing code, which is, of course, the
point.)

It really is what you wanted to write, out of the set of one
alternative that you considered? Does this mean you think
no other alternative could possibly be better, or only that
this writing is good enough so you don't have to think about
other ways to write it?

No, and rereading both the context above and your original
response, I still don't see it.

Sorry, I guess I was too terse.

<laugh> Of course, you're right. Since I have never liked that
approach, I didn't even think about the difference in
applicability between == and !=.

I hadn't either until I had the example in front of me.

I disagree completely. The precedence of operations is
critical to reading the expression, and the mental effort
required to understand that precedence is not increased in this
case with the parentheses explicit. (Of course, this only
applies with a very limited number of parentheses, as in this
example; I certainly am not encouraging lots of redundant
parentheses.)

You disagree meaning you personally don't find that writing
easier to digest, or you disagree meaning you don't think
it's possible that anyone could find it easier to digest?
Or perhaps most people?

Again you say this isn't purely a style issue, but I still
haven't seen you say what, specifically, you regard as a
non-style issue here. I'm beginning to think that you and I
have different ideas as to what constitutes style. The only
reason I see above that you give for a different way of writing
this is that it "might be easier to digest". That seems to me
to fall *completely* within the bounds of style/aesthetics.
(To me those two words cover the same ground.)

In programming, I think I would say something is purely a style
issue if all the alternatives being considered are obviously
semantically equivalent. The word 'obviously' is obviously
somewhat fuzzy. The word 'equivalent' is also fuzzy in the
sense I mean to use it here, which is weaker than 'identical'
but stronger than 'isomorphic' (eg, an N**2 algorithm is not
"equivalent" in this sense to an N * log N algorithm, even
though their externally visible behavior may be identical if
performance is ignored; whereas 'for(;;)' and 'while(1)' seem
close enough to be called "equivalent").

In the thread of this discussion, some of the alternatives that
have come up are (the spacing may not match exactly, please
ignore that):

n = n * 10 + *s - '0';
n = n * 10 + (*s - '0');
n = n * 10 - '0' + *s;
n = *s-'0' + n*10;

Certainly these are not all semantically equivalent, since when
overflow happens isn't always the same in the different cases.
Not couting that, are all of these _obviously_ equivalent? At
some level I think we're having the discussion precisely because
it isn't immediately obvious that the expression '*s-'0' + n*10'
does what you want it to do. It's clear enough if System 2
thinking is used, but maybe not if just System 1 thinking is
used. (These terms in the sense of "Thinking, Fast and Slow",
by Kahneman.) Does that all make sense? I'm definitely
interested to hear what you mean by "style" if it would draw
different sorts of boundaries.

I agree completely.

That is reassuring, at least we agree on something. :)
 
P

Phil Carmody

Tim Rentsch said:
Usual math notation for polynomials puts the higher powers on
the left, and the coefficient to the left of the variable.
[snip elaboration and unrelated]

I don't find this idea very compelling either as explanation or as
argument. That is one common notation, but certainly not the only
one.

Absolutely. In perturbation theory, p-adic arithmetic, probability
and statistics, and calculus, it's absolutely standard to have the
exponents increase as you move right. The "usual notation" argument
is completely hollow.

The strongest argument for ordering the operands for me is the one
that makes the code self-descriptive - the code says what the human
would say to explain it. What are we doing? We're multiplying n by
10 and adding the new digit. I.e. n = n * 10 + (*pd - '0');
In particular, I like the line begining "n = n ...", as that says
in the clearest possible way (apart from the 'op=' notiation which
can't perform multiple modifications, both * and +) that we're
modifying the prior value of n.

Phil
 
J

James Kuyper

On 01/02/2013 04:07 PM, Philip Lantz wrote:
....
I disagree completely. The precedence of operations is critical to
reading the expression, and the mental effort required to understand
that precedence is not increased in this case with the parentheses
explicit. (Of course, this only applies with a very limited number of
parentheses, as in this example; I certainly am not encouraging lots of
redundant parentheses.)

For me, redundant parenthesis always cause a slight slowdown in my
reading of an expression, because I have to carefully consider the
possibility that I misunderstood something that makes them not
redundant. That's only a significant effect in very complicated
expressions, but it always has some effect, even for the simplest ones.

It's similar, in that regard, to unnecessary casts - I always have to
stop and consider the possibility that I've misunderstood something that
might have made the cast necessary.

People who have more confidence (whether or not it's warranted) in their
ability to not make such mistakes probably don't suffer the same slowdown.
 
T

Tim Rentsch

Phil Carmody said:
[ discussing 'n = n * 10 + (c - '0');' and various alternate
formulations of that]

The strongest argument for ordering the operands for me is the
one that makes the code self-descriptive - the code says what
the human would say to explain it. What are we doing? We're
multiplying n by 10 and adding the new digit. [like in the
example.] In particular, I like the line begining "n = n ...",
as that says in the clearest possible way (apart from the 'op='
notiation which can't perform multiple modifications, both *
and +) that we're modifying the prior value of n.

Excellent. Of all the responses given, this one strikes me as
both the best explanation and also the most compelling argument.
Bravo!
 
D

David Thompson

On 05 Jan 2013 12:00:56 +0200, Phil Carmody

The strongest argument for ordering the operands for me is the one
that makes the code self-descriptive - the code says what the human
would say to explain it. What are we doing? We're multiplying n by

I agree with that -- although different humans describe or best
understand some things differently, so this is de gustibus.
10 and adding the new digit. I.e. n = n * 10 + (*pd - '0');
In particular, I like the line begining "n = n ...", as that says
in the clearest possible way (apart from the 'op=' notiation which
can't perform multiple modifications, both * and +) that we're
modifying the prior value of n.

In C++ where assignments yield lvalues, we can do
(n *= 10) += *pd - '0';

I find that clear enough, but unpretty. YMMV.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top