Article about Herb Schildt accepted at comp.risks

P

Peter Nilsson

Keith Thompson said:
[The above is a quotation from Schildt's book.]

He's incorrect in describing parentheses as operators.

And in so doing, increased the precedence of each operator
therein. Each nesting effectively introduces an additional
precedence tier, recursively for each level of nesting.
Schildt's description, though it's badly worded,
isn't necessarily entirely wrong.

It's only wrong in that it calls (grouping) parentheses
operators when they are just syntax, just as the comma that
separates function arguments are syntax, not operators.
 Parentheses do have to do with precedence.

They affect the precedence of operators within them.
 Perhaps a better way to say it is that parentheses
themselves have very high precedence.

That is common and tends to be easier to understand
than recursively nested precedence tables.
 (Of course the C standard doesn't discuss this in terms
of precedence,

As the footnote says, the intent is that precedence is
implied by the grammer. The nesting of precedence tiers
is therefore also implied by the grammar.
but it's not unreasonable to apply the concept.)

It's not confusing, but it's not actually right. Just as
saying 'unsigned integers wrap on overflow' is not confusing,
but not actually right.
For example, in
    x + y * z
"*" has higher precedence than "+"; in
    (x + y) * z
"()" has higher precedence than either "+" or "*".

When in reality, the parentheses have given the contained "+"
a higher precedence than the outer "*".
 
S

Seebs

When in reality, the parentheses have given the contained "+"
a higher precedence than the outer "*".

I don't think that's an accurate description. It's not horribly wrong,
but I think it's misleading. The + has the same precedence it has always
had -- it's just that it is now in a smaller sub-expression.

In
foo(a + b) * 3;
foo() isn't changing the precedence of + -- it's just moving the + into
a separate expression which has a rule other than precedence defining
its boundaries.

-s
 
K

Keith Thompson

Peter Nilsson said:
Keith Thompson said:
Seebs said:
spinoza1111 wrote:
'Parentheses are operators that increase the precedence
of the operations inside them.'"

[The above is a quotation from Schildt's book.]
Herb is correct.

He's incorrect in describing parentheses as operators.
[...]

Agreed, the standard doesn't describe parentheses as operators.
But it could have done so, with no real change in meaning.
(Think of them as "unary outfix", if that's a word.)

Personally, I'm more comfortable thinking of parentheses as
operators than "." or "->". Still, it's generally better to
follow the terminology used by the standard.
 
S

spinoza1111

Peter Nilsson said:
Keith Thompson said:
spinoza1111 wrote:
'Parentheses are operators that increase the precedence
of the operations inside them.'"
[The above is a quotation from Schildt's book.]
Herb is correct.
He's incorrect in describing parentheses as operators.

[...]

Agreed, the standard doesn't describe parentheses as operators.

I don't give a damn about what the standard says. It was deliberately
given over for drafting to incompetents so as to avoid compiler
change.
But it could have done so, with no real change in meaning.
(Think of them as "unary outfix", if that's a word.)

"Unary outfix", if that's a word?
This is the ultima Thule of the absurd
Is there no depth to which you will not sink?
Were I but a drinking man, it would be time to have a drink.

Parentheses are not operators. Operators are compiled into code;
parentheses are used, and thrown away, by the compiler.

Personally, I'm more comfortable thinking of parentheses as
operators than "." or "->".  Still, it's generally better to
follow the terminology used by the standard.

It is always and everywhere a mark of Idiocy
To use the word "terminology".
The reason is simple and easy to understand
At least to a member of the species, Man.
"Terminology" is swot by the low and self-taught
In order to get jobs accounts to tot or copies to jot
It alienates the person from the word:
For it's obvious to the veriest bird,
That to study words is called "words", books, and reading
An occupation for the man of letters of excellent breeding
Whereas to mindlessly memorize "material"
(A sort of grey paste that's beginning to smell,
For that what the word used by teachers implies:
In "material" find the death of education, of joy and surprise)
To start again, to mindlessly swot by rote "material"
Is the mark of the fool and soon to be knave, tho' drest Swell
In clothes of the City from Versace or Hugo Boss
Underneath the swot, the geek, the lager lout, a loss
For all that come near him, be it colleague or lass
He's really learned nothing...he remaineth an Ass
Who can say from his perch at some corporate stool
"Parentheses are operators", is merely a Fool.
 
S

spinoza1111

Peter Nilsson said:
Keith Thompson said:
spinoza1111 wrote:
'Parentheses are operators that increase the precedence
of the operations inside them.'"
[The above is a quotation from Schildt's book.]
Herb is correct.
He's incorrect in describing parentheses as operators.

[...]

Agreed, the standard doesn't describe parentheses as operators.
But it could have done so, with no real change in meaning.
(Think of them as "unary outfix", if that's a word.)

Personally, I'm more comfortable thinking of parentheses as
operators than "." or "->".  Still, it's generally better to
follow the terminology used by the standard.

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

Schildt harmlessly refers to parentheses as "operators" where the noun
clearly means "anything that is not a symbol", as it would in a
classroom of junior programmers unprepared by university level
training in computer science. Keith, who should know better,
misinterprets this as meaning that parentheses are "operators" in the
narrower sense. He's unable to see, as is Seebach unable, that there's
three sorts of "language games" going on.

The first is the language game in which people who haven't taken
computer science need gradually to form mental "sets" and groupings of
concepts which only approximate the rigid taxonomy of formal computer
science.

The second is that of computer science which (because parentheses are
provably unnecessary) no longer calls parentheses operators.

The third is the debased parody of computer science language which
uneducated people pick up inside corporations, and it is what Seebach
and Kiki use. It is disturbingly similar to the examples Orwell gives
of poor English in his essay "Politics and the English Language", as
used by half-educated Stalinist thugs. This is because the writer
never takes responsibility for what goes on inside a phrase like
"outfix operator".

Real attempts at understanding (Herb's clarity) vary their language
game inside of the text, but people untrained in critical reading such
as Dweebach can't follow the shifts, especially when they are
mollycoddled little shits protected from participating in the real
world by white racism.

Herb knows that in the sense of compiling to an operation, a
parenthesis is not an operator. But from the standpoint of lexical
analysis, with which he's familiar and Dweebach isn't, it is a
syntactical operator. And, of course, it increases the precedence of
the semantic ops inside of it.

Franz Fanon long ago recognized the way in which lower middle class
little shits of *pieds noirs* used concepts rigidly: "look, a Negro".
This language autistically assumes that there's only one language
game. It lacks a human ability: to metalinguistically detect shifts in
language games overall.

There's Nothing Sacred about "operators". Humpty Dumpty was right.
When we use words they mean exactly what we intend them to mean: no
more and no less. The real action takes place in the air between two
people who are in purity of heart trying to solve a problem such as
their enmity or conflict. If they are as here trying to destroy the
other person, we may as well meet, in meat space, and have a fight.
I'm game.
 
S

spinoza1111

Seebs said:
[seebs, in C:TCN]
'Parentheses are operators that increase the precedence of the
operations inside them.'"
[The above is a quotation from Schildt's book.]
[spinny]
Herb is correct. This is what parentheses do. The optimizer is
entitled to change the order of evaluation if the precedence is
preserved,
...or even if it isn't. Between consecutive sequence points, the
implementation is entitled to use any order of evaluation in likes.
But really, they haven't changed the precedence of anything.  They've
grouped a subexpression.
Schildt's description, though it's badly worded, isn't necessarily
entirely wrong.  

Oh thanks mighty C authority
Parentheses do have to do with precedence.  Perhaps a
better way to say it is that parentheses themselves have very high
precedence.  

A remarkably ignorant statement, since in accepted usage in the
computer science community, only operators can have precedence, and
parentheses are not operators.
(Of course the C standard doesn't discuss this in terms of
precedence, but it's not unreasonable to apply the concept.)
For example, in
    x + y * z
"*" has higher precedence than "+"; in
    (x + y) * z
"()" has higher precedence than either "+" or "*".

This makes no sense whatsoever. The parentheses are not evaluated. If
you translate the expression "(x + y) * z" to suffix notation (xy+z*)
they go away.

Operator precedence is in fact defined only for infix expressions in
the ABSENCE of parentheses, and in ordinary math and compsci, the
addition and subtraction operators have higher precedence than the
multiplication and division operators, which was based on praxis in
high school algebra. Therefore, your statement gives evidence that you
flunked high school algebra. WTF do you think you are doing at Nokia?



I'm afraid that while Schildt may have been at times confused by an
artifact which was incompetently designed, your discussion, Mr.
Thompson, exhibits a frightening lack of comprehension of the
scientific basis of your profession.

It is remarkable how foully people who misuse "terminology" are
treated here by people who in Seebach's case, lack, and exhibit lack
of, computer science education, and in your case also eshibit this
lack.

During the later part of my programming career, earlier in this
decade, I noticed that actual programmers and their managers were
forever finding excuses not to program in the USA. This was because
for years, management had dismissed the scientific theory in favor of
snake oil, and it was confirmed by articles in the New York Times:
that most American programmers simply do not code much. They attend
meetings, they read and write "white papers", those famous documents,
carefully purged of critical thought, with a subtly racist name.

They occasionally change a line of code and almost as often get it
wrong. They write shell procedures or vanity C with unnecessarily
unstructured fallthrough.

They spend hours gossiping and backbiting, online and in meatspace,
and on the phone to real estate brokers.

When they are laid off, nothing much happens apart from the stock
price increase because all the work is being done by my former
coworkers in Shenzen, and in India.

Anyone who can say with a straight face that parentheses have
precedence is a clown.

And anyone who mounts a fifteen year campaign of personal destruction
against a harmless computer author is an evil clown.

I see another comp.risks submission: the RISKS of programmer
incompetence. Don't worry, I won't name names, whether of individuals
or companies. But part of my article will be based on what I've seen
here.

However, at this time, I have taken a break to write a Shakespearean
play about the British election, "The Well-Hung Election, or, Brown
Goeth Down to China Town". I am applying what I know about prosody.
People here are welcome to read it athttp://spinoza1111.wordpress.com/2010/05/07/a-newly-discoverd-play-by....
Here's a sample:

Brown: Varlet, scum, Nancy boy, loser,
And whatever other name may not unbecome
My high and palmy state, tho’ it be thus destroy’d
(For even as men remember’d Rome they will bewail
The loss of New Labour and its grand design)
Be thou call’d. Out of my sight! Thou dost infect mine eyes:
You incompetent Piece of Matter Fecal,
You toad-eating scum of the green-mantl’d Pond,
You block, you stone, you worse than senseless thing,
Thou hast stol’n the election and I am no longer King.

Aide Secundus:What, King? Thou weren’t elected
But King thou never wert, or my name is Bert




--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

I missed something here: where Herb, and not Kiki, was the first to
say that the parenthesis is an operator. That's something I or Dan
Appleman, would not have let stand in "Build Your Own .Net Language
and Compiler".

Herb, as I have said, uses an oral/informal style of discourse which
is far more clear than the nonsense posted in this thread by Kiki and
by Dweebach. You have to "listen" to it with the same sort of charity
and respect for one's elders I was able to display towards my
professor and Sherman, the author of my 7094 centric compsci text, in
1970. As you "listen", you form TEMPORARY concepts which being
temporary are soft, and further malleable.

Whereas people like Seebach, who has confessed to Autism, are debased
and brittle old men long before their time: if on one page Herb means
by "operator", "something that is not a variable", this must be cast
in stone.

Kiki's problem is that he wants to find out some way in which a
parenthesis could ALWAYS be an operator, and nobody who knows Polish
notation would regard this as perspicuous.
 
B

Ben Bacarisse

Seebs said:
I don't think that's an accurate description. It's not horribly wrong,
but I think it's misleading. The + has the same precedence it has always
had -- it's just that it is now in a smaller sub-expression.

In
foo(a + b) * 3;
foo() isn't changing the precedence of + -- it's just moving the + into
a separate expression which has a rule other than precedence defining
its boundaries.

However, one could parse the expression using Peter's rule. Lets say we
give every 'naked' operator a precedence in [0,100): ',' is 0, = is 1,
and so one. For every nesting construct (F(...), A[...] and plain
(...)) we add 10**(n+1) to the precedence of the enclosed operators
where n is the nesting level. We could then remove the ()s and []s and
parse the expression using operator precedence alone. We'd have to
leave some residual sign for the function call and subscript operators.

(a + 1)[(x + 3)*2]

Would become:

a {+111} 1 {[]14} x {+1011} 2 {*112} 2

using <OP PREC> to denote operator OP with precedence PREC. Thinking a
little about the details, I would not be surprised if ?: needed a left
and right precedence, but that not uncommon is such grammars.

I don't think there's much merit in this as a practical method, but it
never hurts to have more ways to describe things. Some people may find
it a useful way to think about parentheses.
 
P

Peter Nilsson

Seebs said:
I don't think that's an accurate description.

In what way is it inaccurate?
 It's not horribly wrong,

How is it wrong in _any_ way, other than not being the way
you would describe it?
but I think it's misleading.

That you find it misleading does not make it wrong. Perhaps
you you only find it misleading because you've grown up with
an alternative premice that you can't shake.
 The + has the same precedence it has always had
-- it's just that it is now in a smaller sub-expression.

If you play any trump card games, you can think of it in
terms that 10 beats 9, which beats 8, which beats 7 etc...
However, a 9 of hearts may trump a 10 of spades. It's still
a 9 and it's still lower than a 10, but being a high suit,
it can sometimes beat a 10 of any lower suit. [Of course,
the C grammer is not limited to 4 suits of operators. ;-]
 
S

Seebs

In what way is it inaccurate?

Nothing has changed about the precedence of any operators -- parentheses
just turn an arbitrary expression into a primary expression.
How is it wrong in _any_ way, other than not being the way
you would describe it?

Changing the precedence of an operator would change how it is bound
compared to other operators which are in the same expression, but
parenthesising creates a separate expression.

After that's done, no matter what's in the parentheses, it's treated the
same way an identifier or constant would be -- it's not subject to either
precedence or associativity, it's just become an atom with respect to some
containing expression.
If you play any trump card games, you can think of it in
terms that 10 beats 9, which beats 8, which beats 7 etc...
However, a 9 of hearts may trump a 10 of spades. It's still
a 9 and it's still lower than a 10, but being a high suit,
it can sometimes beat a 10 of any lower suit. [Of course,
the C grammer is not limited to 4 suits of operators. ;-]

I'd say parentheses work, not like a trump, but like moving a hand into a
separate game, in which no other hands may be played. It wins, not because
it's become a better hand, but because you've removed any possible
competition.

-s
 
P

Peter Nilsson

Seebs said:
Nothing has changed about the precedence of any operators

Nothing changes about the relative precedence of operators in
an _unparenthesised_ expression.
-- parentheses just turn an arbitrary expression into a
primary expression.

And parsing that primary expression independantly then
considering it as an atomic operand is isomorphic to
parsing the sub expression as if it had a higher (or
at least separate) tier of precedence to the rest of
the expression.
Changing the precedence of an operator would change how it
is bound compared to other operators which are in the same
expression,

But that is *precisely* the purpose of parentheses! To change
the binding of operators. If it weren't necessary to alter the
binding of operators, there would be no need to have
parentheses. But it _is_ necessary to alter the binding of
operators with infix notation.
but parenthesising creates a separate expression.

It is a sub expression that is part of the original expression.

If you play any trump card games, you can think of it in
terms that 10 beats 9, which beats 8, which beats 7 etc...
However, a 9 of hearts may trump a 10 of spades. It's still
a 9 and it's still lower than a 10, but being a high suit,
it can sometimes beat a 10 of any lower suit. [Of course,
the C grammer is not limited to 4 suits of operators. ;-]

I'd say parentheses work, not like a trump, but like moving
a hand into a separate game, ...

<sigh> Perhaps I can't teach an old dog new tricks. ;)

Consider an analogy of automatic variables in a recursive
function. You're arguing along the lines that they are the
same variables just 'treated separately' with each instance
of the function. Whereas I say they can be viewed as
different variables, with a higher priority of access, even
though they have the same name and come from the same
declaration line.
 
S

Seebs

Nothing changes about the relative precedence of operators in
an _unparenthesised_ expression.

Right. Operator precedence is fixed.
And parsing that primary expression independantly then
considering it as an atomic operand is isomorphic to
parsing the sub expression as if it had a higher (or
at least separate) tier of precedence to the rest of
the expression.

I think I agree that it has the same effects, but I'm not quite done
thinking that part through. However, I think there's a significant
conceptual difference between "this changes precedence" and "these
two things are in different expressions, so precedence isn't applicable."
But that is *precisely* the purpose of parentheses! To change
the binding of operators. If it weren't necessary to alter the
binding of operators, there would be no need to have
parentheses. But it _is_ necessary to alter the binding of
operators with infix notation.

Agreed, but I don't think they do it by modifying precedence.

Imagine that we were to create a syntax for actually modifying precedence;
you could take any operator, and prefix it with a backslash, and that operator
would then have increased precedence, so that:

1 \+ 2 * 3

would be 9.

That would be "modifying precedence".

In
(1 + 2) * 3
the precedence of + hasn't changed. It's just that + is in an expression
where there's no higher-precedence operators, and indeed, no other operators
at all. Similarly, * is now in an expression where it is the only operator;
the operands are both primary expressions, not expressions with operators
in them.
Consider an analogy of automatic variables in a recursive
function. You're arguing along the lines that they are the
same variables just 'treated separately' with each instance
of the function. Whereas I say they can be viewed as
different variables, with a higher priority of access, even
though they have the same name and come from the same
declaration line.

They're obviously different variables, but I don't think "priority of
access" is the right choice. It's not just that the local copy is
"higher priority" -- it's the ONLY priority, because the calling function
isn't in scope.

Consider:
int fact(int x) {
if (x <= 1)
return 1;
return x * fact(x - 1);
}

If we are to say that the inner x in a call of fact(2) is merely a
higher "priority of access", then what about:

int fact1(int x) {
if (x <= 1)
return 1;
return x * fact2(x - 1);
}
int fact2(int y) {
if (y <= 1)
return 1;
return y * fact1(y - 1);
}

If it's merely "higher priority of access", then if you call fact1(2),
in the inner call to fact2(1), you should still be able to access x, because
you don't have another x with a higher "priority of access".

But you can't, because it's not priority, but scope, and you've left the
previous scope entirely.

Similarly, when you parenthesize, it's not that the parenthesized expression
has operators with suddenly-higher precedence; it's that it's now a separate
expression entirely. There's no question of relative precedence; it's not as
though, if you just had a *high enough* precedence, you could beat the
now-increased precedence of the operators in the (). It's that from the
"(" until you see the ")", you have done something roughly equivalent to
pushing something on a stack; you've entered a new expression, and until
you're done parsing that (as indicated by the closing ")"), you're in a
new context.

-s
 
N

Nick Keighley

Operator precedence is in fact defined only for infix expressions in
the ABSENCE of parentheses, and in ordinary math and compsci, the
addition and subtraction operators have higher precedence than the
multiplication and division operators, which was based on praxis in
high school algebra. Therefore, your statement gives evidence that you
flunked high school algebra. WTF do you think you are doing at Nokia?

addition and subtraction operators have LOWER precedence than the
multiplication and division operators
 
B

Ben Bacarisse

Seebs said:
On 2010-05-14, Peter Nilsson <[email protected]> wrote:

Agreed, but I don't think they do it by modifying precedence.

Imagine that we were to create a syntax for actually modifying precedence;
you could take any operator, and prefix it with a backslash, and that operator
would then have increased precedence, so that:

1 \+ 2 * 3

would be 9.

That would be "modifying precedence".

In
(1 + 2) * 3
the precedence of + hasn't changed.

You are happy to postulate a syntax where the \ modifies the precedence
of the operator it is next to, so why do you not want to think of () as
modifying the precedence of the contained operators? It can't be simply
be the proximity of the symbols that makes one acceptable and the other
alien.

Here's the thing: what is this precedence that you say doesn't change?
C operators have no natural, unchanging, innate precedence -- a parser
may choose to give an operator a precedence and use that to determine
the binding, but this is just one method of parsing an expression.
Another would be parse the grammar in the standard, top down. The two
results will of course be a close match (but not, I think, an exact
one). As a result of this duality, people publish operator precedence
tables (K&R included) because we (as humans) find the idea of precedence
and associativity to be a simpler way to think about C expressions. All
that is being suggested is another way: associate with each operator a
precedence that includes the depth of the nesting it is found in -- and
then ignore the brackets.

[A nice way to think about it to let the ()s collapse down onto the
operators so (1 + 2) * 3 turns into 1 (+) 2 * 3. The ()s now modify
nothing but the precedence so (+) is just a high priority + operator.
Obviously all ((x)) bind tighter than all (x) which in turn bind more
tightly than the naked x operator.]

Why do this? Well, it may help some people understand precedence and
parentheses -- it's always good to have lots of alternate ways of
thinking about things.

And it can't hurt to have other ways to code expression parsing. In
that spirit (and because there has not been enough code to pick at
recently) here is a version of Dijkstra's classic shunting yard
algorithm that just counts brackets rather than pushing and popping
them. I am not claiming there is much practical benefit to doing it
this way (the logic of the code is a little simpler but the information
on the stack is a little more complex) -- I just think there's always
room for other ways to do things.

A few notes about this method: by being relaxed about checking it will
parse the version where the brackets are only round the operator. Thus
"1 (+) 2 * 3" is parsed as "(1 + 2) * 3". Also, by treating the
precedence as signed, I decided to permit "anti-parentheses" which lower
the binding. Thus we could also write the previous expression as "1 +
)2 * 3(" or by even as "1 + 2 )*( 3". I.e. ")*(" is just a low priority
multiplication operator.

<snip>

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#include <ctype.h>

struct operator {
int token;
int precedence;
};

bool stack_empty(void);
void stack_push(struct operator op);
struct operator stack_pop(void);
struct operator stack_top(void);

int get_token(FILE *f);


void shunt_exp(FILE *in, FILE *out)
{
int precedence[UCHAR_MAX] = {
['*'] = 3, ['/'] = 3, ['%'] = 3,
['+'] = 2, ['-'] = 2,
['='] = 1,
};

int token, nesting = 0;
while ((token = get_token(in)) != EOF)
if (isalnum(token))
fputc(token, out);
else if (token == '(')
++nesting;
else if (token == ')') {
--nesting;
}
else {
struct operator op = {
token,
precedence[token] + 100*nesting
};
while (!stack_empty() &&
op.precedence <= stack_top().precedence)
fputc(stack_pop().token, out);
stack_push(op);
}
if (nesting != 0)
fprintf(stderr, "Too many %cs.\n", nesting > 0 ? '(' : ')');
while (!stack_empty())
fputc(stack_pop().token, out);
}

int main(void)
{
shunt_exp(stdin, stdout);
return 0;
}


/* Here is just enough of a stack and an input function get things going. */

#define STACK_SIZE 10

static struct operator stack[STACK_SIZE];
static size_t top_of_stack = 0;

bool stack_empty(void)
{
return top_of_stack == 0;
}

void stack_push(struct operator op)
{
if (top_of_stack >= STACK_SIZE) {
fprintf(stderr, "Stack overflow.\n");
exit(EXIT_FAILURE);
}
else stack[top_of_stack++] = op;
}

struct operator stack_pop(void)
{
if (stack_empty()) {
fprintf(stderr, "Stack underflow.\n");
exit(EXIT_FAILURE);
}
else return stack[--top_of_stack];
}

struct operator stack_top(void)
{
return stack[top_of_stack - 1];
}

int get_token(FILE *f)
{
int c;
while (isspace(c = fgetc(f)));
return c;
}
 
S

Seebs

You are happy to postulate a syntax where the \ modifies the precedence
of the operator it is next to, so why do you not want to think of () as
modifying the precedence of the contained operators? It can't be simply
be the proximity of the symbols that makes one acceptable and the other
alien.

I guess for the same reason that I don't view ; as increasing the precedence
of operators. That's not how it works.
Another would be parse the grammar in the standard, top down. The two
results will of course be a close match (but not, I think, an exact
one). As a result of this duality, people publish operator precedence
tables (K&R included) because we (as humans) find the idea of precedence
and associativity to be a simpler way to think about C expressions. All
that is being suggested is another way: associate with each operator a
precedence that includes the depth of the nesting it is found in -- and
then ignore the brackets.
Ohhhhhh.

Why do this? Well, it may help some people understand precedence and
parentheses -- it's always good to have lots of alternate ways of
thinking about things.

I guess. I think the thing is...

1. While it is another way to think about things, it seems to me that it's
a simile, not a description. It is, I think, true that parentheses have an
effect similar to what you'd get if you could increase the precedence of
operators, but that's not how they're defined and I don't think it's how
anything actually parses it.
2. It sounds to me to be a much more complex way to think about things.
To me, "() makes a separate sub-expression, and is then an atom in
the containing expression" is super obvious, but "and then these things
all have their precedence increased, relatively, but are still part of the
same expression". Which gives the impression that if you could just
figure out how to write it, you'd be able to get a (x+y) and a (w*z) to
interact such that the *'s still-higher precedence would win. (You
can't, of course, because they need one of the other operators between
them...)

Hmm. I guess a lot of this is probably just that, while I'm fine with
ways-of-thinking, I get fussy if someone says that the way of thinking
is really what happens.

-s
 
B

Ben Bacarisse

Seebs said:
I guess for the same reason that I don't view ; as increasing the precedence
of operators. That's not how it works.

That seems circular. You don't like to think of it that way because "it
does not work like that" is an odd reply to a post about how it can be
made to work that way.
I guess. I think the thing is...

1. While it is another way to think about things, it seems to me that it's
a simile, not a description.

I don't get this distinction. All the different ways of thinking about
the (syntactic) meaning of expressions seem to me to be at the same
level -- they explain how a strings map to a parse trees. What do you
mean when you say one way is a simile and another a description.

I would concede that one method is privileged: the grammar in the
language standard is the *definition* of this mapping and all other
explanations (like operator precedence) would have to be shown to be
similar (or at least sufficiently similar).
It is, I think, true that parentheses have an
effect similar to what you'd get if you could increase the precedence of
operators, but that's not how they're defined and I don't think it's how
anything actually parses it.

Do you think about C operators using precedence and associativity? They
are not defined like, that but most people prefer the resulting
approximation to the full grammar. I'd be quite happy if you just said
you don't like it, but objecting because ()s are not defined like that
is only fair if you object to all operator precedence views of C's
expressions.

As for anything doing it that way, I don't know and I certainly don't
want to argue about it. I am not sure it matters when talking about
alternate ways of thinking about expressions.
2. It sounds to me to be a much more complex way to think about things.
To me, "() makes a separate sub-expression, and is then an atom in
the containing expression" is super obvious, but "and then these things
all have their precedence increased, relatively, but are still part of the
same expression".

Your paraphrase is not fair! Anyway, it may well be more complex. I
would not want to sell it on the grounds of simplicity.
Which gives the impression that if you could just
figure out how to write it, you'd be able to get a (x+y) and a (w*z) to
interact such that the *'s still-higher precedence would win. (You
can't, of course, because they need one of the other operators between
them...)

Hmm. I guess a lot of this is probably just that, while I'm fine with
ways-of-thinking, I get fussy if someone says that the way of thinking
is really what happens.

I feel the same, but I thought that what really happens was a the very
heart of your very argument: "that's not how it works" you said at the
start and later: "I don't think it's how anything actually parses it".
 
S

Seebs

That seems circular. You don't like to think of it that way because "it
does not work like that" is an odd reply to a post about how it can be
made to work that way.

I was responding more to the "way of thinking about it" aspect. I grant
that it could actually probably be done equivalently, but it's not what
the language spec describes, nor do I know of a parser which works that
way.
I don't get this distinction. All the different ways of thinking about
the (syntactic) meaning of expressions seem to me to be at the same
level -- they explain how a strings map to a parse trees. What do you
mean when you say one way is a simile and another a description.

I mean that if you actually look at the data structures inside any compiler
I've yet seen, it is not using a table of precedence and then increasing
the precedence of the operators inside the ().
Do you think about C operators using precedence and associativity?

Not usually -- I find the type-of-expression thing (primary expression,
additive expression, etc.) much clearer.
They
are not defined like, that but most people prefer the resulting
approximation to the full grammar. I'd be quite happy if you just said
you don't like it, but objecting because ()s are not defined like that
is only fair if you object to all operator precedence views of C's
expressions.

I don't entirely agree. The equivalence of the expression-naming thing
to precedence is clear, but when you do that and build a precedence table,
it doesn't have multiple copies of everything, with each set marked as
"inside another set of ()".
As for anything doing it that way, I don't know and I certainly don't
want to argue about it. I am not sure it matters when talking about
alternate ways of thinking about expressions.

A way of thinking about something that describes its behavior, but not
its mechanism, is good as a way-of-thinking-about, but not good as a
description of what actually happens.
Your paraphrase is not fair!

Sorry. I don't really *get* the precedence description, I don't think.
I feel the same, but I thought that what really happens was a the very
heart of your very argument: "that's not how it works" you said at the
start and later: "I don't think it's how anything actually parses it".

Yes. So if someone said "one way to think about parentheses is as if they
increased the precedence of all operators inside them so that relative
precedence is preserved within the parentheses, but everything inside them
has higher precedence than anything outside them", I wouldn't complain.
But if someone said "what parentheses do is increase the precedence of...",
I'd complain, because that's not what they do -- it's just a way of thinking
about what they do.

-s
 
W

Willem

Seebs wrote:
) I mean that if you actually look at the data structures inside any compiler
) I've yet seen, it is not using a table of precedence and then increasing
) the precedence of the operators inside the ().

How many compilers have you seen that use a table of precedence, period ?

What I've seen most often is a grammar graph with the most-tightly
binding operator at the root, going down from there, but with parens
making it point back to the root again. That makes it a loop, and
more parens means going round the loop more times.

The precedence is implicit in how many steps from the start you are,
and parens make you go round the loop more, so parens increase the
precedence.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
S

Seebs

How many compilers have you seen that use a table of precedence, period ?

None outside of example programs.

This is why I don't think describing parentheses as "increasing precedence"
is accurate.

-s
 
W

Willem

Seebs wrote:
)> How many compilers have you seen that use a table of precedence, period ?
)
) None outside of example programs.
)
) This is why I don't think describing parentheses as "increasing precedence"
) is accurate.

So you also don't think that describing multiplication
as having greater precedence than addition is accurate ?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
S

Seebs

Seebs wrote:
) This is why I don't think describing parentheses as "increasing precedence"
) is accurate.
So you also don't think that describing multiplication
as having greater precedence than addition is accurate ?

....

Huh. Weird -- that is definitely an inconsistency in my mental map of
this.

I'm still not sure why it just seems so clearly wrong to me to describe ()s
in terms of precedence rather than in terms of a separate expression.

Hmm. Thinking about it, I think it's just the (...) matching -- you
couldn't possibly split a () around anything else without ending up with
mismatched ()s, so obviously they're self-contained, and thus precedence
isn't at issue.

With something like
a + b * c + d
you COULD split the expression in any of several places -- using "precedence"
to describe how you decide helps, but it doesn't matter; the expression
wouldn't be *incoherent* if you just swapped the precedence around, it'd
just change its value.

But with
a + (b * c) + d
it would make no sense at all to split this into
a + (b
*
c) + d

-s
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top