Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #11331 > unrolled thread
| Started by | Francois Grieu <fgrieu@gmail.com> |
|---|---|
| First post | 2011-10-07 19:10 +0200 |
| Last post | 2012-01-24 16:14 -0800 |
| Articles | 20 on this page of 57 — 16 participants |
Back to article view | Back to comp.lang.c
is the < operator transitive? Francois Grieu <fgrieu@gmail.com> - 2011-10-07 19:10 +0200
Re: is the < operator transitive? Robert Wessel <robertwessel2@yahoo.com> - 2011-10-07 13:44 -0500
Re: is the < operator transitive? Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2011-10-07 18:50 +0000
Re: is the < operator transitive? Keith Thompson <kst-u@mib.org> - 2011-10-07 12:42 -0700
Re: is the < operator transitive? Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2011-10-07 20:23 +0000
Re: is the < operator transitive? Patrick Scheible <kkt@zipcon.net> - 2011-10-07 14:29 -0700
Re: is the < operator transitive? Keith Thompson <kst-u@mib.org> - 2011-10-07 16:49 -0700
Re: is the < operator transitive? Patrick Scheible <kkt@zipcon.net> - 2011-10-07 19:19 -0700
Re: is the < operator transitive? Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-10-08 09:57 -0400
Re: is the < operator transitive? "BartC" <bc@freeuk.com> - 2011-10-08 13:17 +0100
Re: is the < operator transitive? Harald van Dijk <truedfx@gmail.com> - 2011-10-08 06:06 -0700
Re: is the < operator transitive? "BartC" <bc@freeuk.com> - 2011-10-08 14:48 +0100
Re: is the < operator transitive? Harald van Dijk <truedfx@gmail.com> - 2011-10-08 07:18 -0700
Re: is the < operator transitive? "BartC" <bc@freeuk.com> - 2011-10-08 15:19 +0100
Re: is the < operator transitive? Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2011-10-07 18:50 +0000
Re: is the < operator transitive? jacob navia <jacob@spamsink.net> - 2011-10-07 21:23 +0200
Re: is the < operator transitive? Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2011-10-07 20:24 +0000
Re: is the < operator transitive? James Kuyper <jameskuyper@verizon.net> - 2011-10-07 16:40 -0400
Re: is the < operator transitive? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-07 23:12 +0100
Re: is the < operator transitive? Harald van Dijk <truedfx@gmail.com> - 2011-10-07 15:28 -0700
Re: is the < operator transitive? Harald van Dijk <truedfx@gmail.com> - 2011-10-07 15:31 -0700
Re: is the < operator transitive? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-07 23:36 +0100
Re: is the < operator transitive? Patrick Scheible <kkt@zipcon.net> - 2011-10-07 16:18 -0700
Re: is the < operator transitive? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-08 10:32 +0100
Re: is the < operator transitive? James Kuyper <jameskuyper@verizon.net> - 2011-10-07 18:30 -0400
Re: is the < operator transitive? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-08 00:21 +0100
Re: is the < operator transitive? James Kuyper <jameskuyper@verizon.net> - 2011-10-07 21:33 -0400
Re: is the < operator transitive? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-08 10:45 +0100
Re: is the < operator transitive? James Kuyper <jameskuyper@verizon.net> - 2011-10-08 14:02 -0400
Re: is the < operator transitive? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-08 21:49 +0100
Re: is the < operator transitive? James Kuyper <jameskuyper@verizon.net> - 2011-10-08 17:17 -0400
Re: is the < operator transitive? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-08 22:59 +0100
Re: is the < operator transitive? James Kuyper <jameskuyper@verizon.net> - 2011-10-08 21:33 -0400
Re: is the < operator transitive? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-09 09:09 +0100
Re: is the < operator transitive? James Kuyper <jameskuyper@verizon.net> - 2011-10-09 07:00 -0400
Re: is the < operator transitive? "BartC" <bc@freeuk.com> - 2011-10-09 01:12 +0100
Re: is the < operator transitive? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-09 08:55 +0100
Re: is the < operator transitive? Robert Wessel <robertwessel2@yahoo.com> - 2011-10-07 18:16 -0500
Re: is the < operator transitive? David Thompson <dave.thompson2@verizon.net> - 2011-10-18 02:03 -0400
Re: is the < operator transitive? Robert Wessel <robertwessel2@yahoo.com> - 2011-10-20 18:03 -0500
Re: is the < operator transitive? Keith Thompson <kst-u@mib.org> - 2011-10-07 16:50 -0700
Re: is the < operator transitive? "io_x" <a@b.c.invalid> - 2011-10-09 11:00 +0200
Re: is the < operator transitive? Willem <willem@toad.stack.nl> - 2011-10-09 09:42 +0000
Re: is the < operator transitive? Ike Naar <ike@sverige.freeshell.org> - 2011-10-09 12:20 +0000
Re: is the < operator transitive? Willem <willem@toad.stack.nl> - 2011-10-09 12:40 +0000
Re: is the < operator transitive? Ike Naar <ike@sverige.freeshell.org> - 2011-10-09 12:54 +0000
Re: is the < operator transitive? Willem <willem@toad.stack.nl> - 2011-10-09 13:04 +0000
Re: is the < operator transitive? "BartC" <bc@freeuk.com> - 2011-10-09 15:34 +0100
Re: is the < operator transitive? Willem <willem@toad.stack.nl> - 2011-10-09 15:08 +0000
Re: is the < operator transitive? Robert Wessel <robertwessel2@yahoo.com> - 2011-10-09 12:14 -0500
Re: is the < operator transitive? James Kuyper <jameskuyper@verizon.net> - 2011-10-07 15:36 -0400
Re: is the < operator transitive? Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-10-07 20:00 -0400
Re: is the < operator transitive? James Kuyper <jameskuyper@verizon.net> - 2011-10-07 21:38 -0400
Re: is the < operator transitive? Francois Grieu <fgrieu@gmail.com> - 2011-10-09 21:40 +0200
Re: is the < operator transitive? Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-10-09 16:34 -0400
Re: is the < operator transitive? Francois Grieu <fgrieu@gmail.com> - 2011-10-11 14:08 +0200
Re: is the < operator transitive? Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 16:14 -0800
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | Harald van Dijk <truedfx@gmail.com> |
|---|---|
| Date | 2011-10-07 15:31 -0700 |
| Message-ID | <17e038ac-ebf2-484d-ab67-643d76b788ae@h10g2000yqd.googlegroups.com> |
| In reply to | #11355 |
On Oct 8, 12:28 am, Harald van Dijk <true...@gmail.com> wrote: > On Oct 8, 12:12 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote: > > If <, >, <=, >=, == and != all have the same priority, you can parse it > > just like a + b - c + d and simply double the operand you have "in hand" > > and add &&. The operators need to be marked as non-associative, but it > > can be fitted into an operator precedence grammar very simply. > > > I've spent the last hour (not exclusively, you understand) trying to > > remember what language it was that I've worked on that does this, and > > I've come up with nothing. But I don't think I'm making it up, honest. > > Python does this. Is that what you were trying to think of? I see Python was already mentioned in the post you replied to, just not part of the text you quoted.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-10-07 23:36 +0100 |
| Message-ID | <0.d84d000fd0f0f2131344.20111007233634BST.87ty7kv37x.fsf@bsb.me.uk> |
| In reply to | #11355 |
Harald van Dijk <truedfx@gmail.com> writes: > On Oct 8, 12:12 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote: >> If <, >, <=, >=, == and != all have the same priority, you can parse it >> just like a + b - c + d and simply double the operand you have "in hand" >> and add &&. The operators need to be marked as non-associative, but it >> can be fitted into an operator precedence grammar very simply. >> >> I've spent the last hour (not exclusively, you understand) trying to >> remember what language it was that I've worked on that does this, and >> I've come up with nothing. But I don't think I'm making it up, honest. > > Python does this. Is that what you were trying to think of? Thanks, but not what I was thinking of. It's something depressingly old. Maybe Maxima? Or an extension to Algo68, maybe? -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Patrick Scheible <kkt@zipcon.net> |
|---|---|
| Date | 2011-10-07 16:18 -0700 |
| Message-ID | <86pqi875lx.fsf@zipcon.net> |
| In reply to | #11358 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > Harald van Dijk <truedfx@gmail.com> writes: > >> On Oct 8, 12:12 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote: >>> If <, >, <=, >=, == and != all have the same priority, you can parse it >>> just like a + b - c + d and simply double the operand you have "in hand" >>> and add &&. The operators need to be marked as non-associative, but it >>> can be fitted into an operator precedence grammar very simply. >>> >>> I've spent the last hour (not exclusively, you understand) trying to >>> remember what language it was that I've worked on that does this, and >>> I've come up with nothing. But I don't think I'm making it up, honest. >> >> Python does this. Is that what you were trying to think of? > > Thanks, but not what I was thinking of. It's something depressingly > old. Maybe Maxima? Or an extension to Algo68, maybe? The Icon Programming Language does this, and it's not a special case but a natural consequence of a well-designed set of operators. Comparison operators are evaluated left to right and produced the value of their right operand if they are true (succeed, in Icon terminology). If they fail, the subsequent comparison fails also. A < B < C is evaluated (A < B); if true, it produces B, which is then compared to C. If (A < B) is false, it fails and produces no result. Comparing to no result fails in turn. http://www.cs.arizona.edu/icon/ -- Patrick
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-10-08 10:32 +0100 |
| Message-ID | <0.9773ec0ec8ffd69ee85a.20111008103202BST.8762jzvnfx.fsf@bsb.me.uk> |
| In reply to | #11365 |
Patrick Scheible <kkt@zipcon.net> writes: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > >> Harald van Dijk <truedfx@gmail.com> writes: >> >>> On Oct 8, 12:12 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote: >>>> If <, >, <=, >=, == and != all have the same priority, you can parse it >>>> just like a + b - c + d and simply double the operand you have "in hand" >>>> and add &&. The operators need to be marked as non-associative, but it >>>> can be fitted into an operator precedence grammar very simply. >>>> >>>> I've spent the last hour (not exclusively, you understand) trying to >>>> remember what language it was that I've worked on that does this, and >>>> I've come up with nothing. But I don't think I'm making it up, honest. >>> >>> Python does this. Is that what you were trying to think of? >> >> Thanks, but not what I was thinking of. It's something depressingly >> old. Maybe Maxima? Or an extension to Algo68, maybe? > > The Icon Programming Language does this, and it's not a special case but > a natural consequence of a well-designed set of operators. Ah, yes, I'd forgotten that. It wasn't Icon I was thinking about, but it does indeed do this naturally. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-10-07 18:30 -0400 |
| Message-ID | <4E8F7D9A.70405@verizon.net> |
| In reply to | #11353 |
On 10/07/2011 06:12 PM, Ben Bacarisse wrote: ... > If <, >, <=, >=, == and != all have the same priority, you can parse it > just like a + b - c + d and simply double the operand you have "in hand" > and add &&. The operators need to be marked as non-associative, but it > can be fitted into an operator precedence grammar very simply. I'd like to see that explained more clearly. In particular I'd like to see an explanation of how, with that modification, each of the following expressions would be handled: 2 < 1 < 3 0 < 3 (2 < 1) < 3
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-10-08 00:21 +0100 |
| Message-ID | <0.8ddcdfed841f725b51f7.20111008002123BST.87d3e8v158.fsf@bsb.me.uk> |
| In reply to | #11356 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 10/07/2011 06:12 PM, Ben Bacarisse wrote:
> ...
>> If <, >, <=, >=, == and != all have the same priority, you can parse it
>> just like a + b - c + d and simply double the operand you have "in hand"
>> and add &&. The operators need to be marked as non-associative, but it
>> can be fitted into an operator precedence grammar very simply.
>
> I'd like to see that explained more clearly. In particular I'd like to
> see an explanation of how, with that modification, each of the following
> expressions would be handled:
>
> 2 < 1 < 3
> 0 < 3
> (2 < 1) < 3
I'll try. I should go find some code probably but I am a bit short of
time right now...
Operators are marked with a precedence and an associativity. This
latter can be "left", "right" or "none". The heart of the parser deals
with operators with left or no associativity and a priority that is
passed as an argument:
exp = parse_exp_with_prio(priority + 1);
last_right = null;
while (next_token.prio == priority) {
op = next_token;
advance_token();
right = parse_exp_with_prio(priority + 1);
if (last_right != null && op.assoc == none) {
e = make_exp(last_right, op, right);
exp = make_exp(exp, '&&', e);
}
else exp = make_exp(exp, op, right);
last_right = right;
}
return exp;
When called with maximum priority, parse_exp_with_prio matches only
constansts, names, and expressions in brackets. This nested case is
handled by calling parse_exp_with_prio(0).
So "0 < 3" goes round this loop once and builds one expression node
with a < operator.
"2 < 1 < 3" goes round twice. In the second iteration we notice that we
have seen a previous "right operand" of this priority (it will be the
constant 1) and we build (2 < 1) && (1 < 3) while setting last_right to
3 in case there are non-associative operators of the same priority.
"(2 < 1) < 3" parses as normal. The request for exp on the left will
eventually be matched by a call to parse_exp_with_prio with maximum
priority. That will return 2 < 1 after calling parse_exp_with_prio(0)
and matching the closing bracket. This nested call goes round the loop
once. Having get exp on the left, we loop once to build (2 < 1) < 3.
I am sure I've messed up some detail (writing in haste here) and the big
picture is missing. But if you've seen other recursive descent parsers
where expressions are handled by one parameterised parser function
(rather than one for each operator priority) it won't look too odd.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-10-07 21:33 -0400 |
| Message-ID | <j6o99i$aa6$1@dont-email.me> |
| In reply to | #11363 |
On 10/07/2011 07:21 PM, Ben Bacarisse wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>
>> On 10/07/2011 06:12 PM, Ben Bacarisse wrote:
>> ...
>>> If <, >, <=, >=, == and != all have the same priority, you can parse it
>>> just like a + b - c + d and simply double the operand you have "in hand"
>>> and add &&. The operators need to be marked as non-associative, but it
>>> can be fitted into an operator precedence grammar very simply.
>>
>> I'd like to see that explained more clearly. In particular I'd like to
>> see an explanation of how, with that modification, each of the following
>> expressions would be handled:
>>
>> 2 < 1 < 3
>> 0 < 3
>> (2 < 1) < 3
>
> I'll try. I should go find some code probably but I am a bit short of
> time right now...
>
> Operators are marked with a precedence and an associativity. This
> latter can be "left", "right" or "none". The heart of the parser deals
> with operators with left or no associativity and a priority that is
> passed as an argument:
>
> exp = parse_exp_with_prio(priority + 1);
> last_right = null;
> while (next_token.prio == priority) {
> op = next_token;
> advance_token();
> right = parse_exp_with_prio(priority + 1);
> if (last_right != null && op.assoc == none) {
> e = make_exp(last_right, op, right);
> exp = make_exp(exp, '&&', e);
> }
> else exp = make_exp(exp, op, right);
> last_right = right;
> }
> return exp;
>
> When called with maximum priority, parse_exp_with_prio matches only
> constansts, names, and expressions in brackets. This nested case is
> handled by calling parse_exp_with_prio(0).
>
> So "0 < 3" goes round this loop once and builds one expression node
> with a < operator.
>
> "2 < 1 < 3" goes round twice. In the second iteration we notice that we
> have seen a previous "right operand" of this priority (it will be the
> constant 1) and we build (2 < 1) && (1 < 3) while setting last_right to
> 3 in case there are non-associative operators of the same priority.
>
> "(2 < 1) < 3" parses as normal. The request for exp on the left will
> eventually be matched by a call to parse_exp_with_prio with maximum
> priority. That will return 2 < 1 after calling parse_exp_with_prio(0)
> and matching the closing bracket. This nested call goes round the loop
> once. Having get exp on the left, we loop once to build (2 < 1) < 3.
So 2 < 1 < 3 would be different from (2 < 1) < 3. That would bother me;
not because it's so important to allow the current meaning of 2<1<3 to
survive, but because it would be inconsistent with the way parentheses
work in most other C contexts.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-10-08 10:45 +0100 |
| Message-ID | <0.9c297e0e5b9ae67129fd.20111008104538BST.87zkhbu88t.fsf@bsb.me.uk> |
| In reply to | #11375 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 10/07/2011 07:21 PM, Ben Bacarisse wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
>>
>>> On 10/07/2011 06:12 PM, Ben Bacarisse wrote:
>>> ...
>>>> If <, >, <=, >=, == and != all have the same priority, you can parse it
>>>> just like a + b - c + d and simply double the operand you have "in hand"
>>>> and add &&. The operators need to be marked as non-associative, but it
>>>> can be fitted into an operator precedence grammar very simply.
>>>
>>> I'd like to see that explained more clearly. In particular I'd like to
>>> see an explanation of how, with that modification, each of the following
>>> expressions would be handled:
>>>
>>> 2 < 1 < 3
>>> 0 < 3
>>> (2 < 1) < 3
>>
>> I'll try. I should go find some code probably but I am a bit short of
>> time right now...
>>
>> Operators are marked with a precedence and an associativity. This
>> latter can be "left", "right" or "none". The heart of the parser deals
>> with operators with left or no associativity and a priority that is
>> passed as an argument:
>>
>> exp = parse_exp_with_prio(priority + 1);
>> last_right = null;
>> while (next_token.prio == priority) {
>> op = next_token;
>> advance_token();
>> right = parse_exp_with_prio(priority + 1);
>> if (last_right != null && op.assoc == none) {
>> e = make_exp(last_right, op, right);
>> exp = make_exp(exp, '&&', e);
>> }
>> else exp = make_exp(exp, op, right);
>> last_right = right;
>> }
>> return exp;
>>
>> When called with maximum priority, parse_exp_with_prio matches only
>> constansts, names, and expressions in brackets. This nested case is
>> handled by calling parse_exp_with_prio(0).
>>
>> So "0 < 3" goes round this loop once and builds one expression node
>> with a < operator.
>>
>> "2 < 1 < 3" goes round twice. In the second iteration we notice that we
>> have seen a previous "right operand" of this priority (it will be the
>> constant 1) and we build (2 < 1) && (1 < 3) while setting last_right to
>> 3 in case there are non-associative operators of the same priority.
>>
>> "(2 < 1) < 3" parses as normal. The request for exp on the left will
>> eventually be matched by a call to parse_exp_with_prio with maximum
>> priority. That will return 2 < 1 after calling parse_exp_with_prio(0)
>> and matching the closing bracket. This nested call goes round the loop
>> once. Having get exp on the left, we loop once to build (2 < 1) < 3.
>
> So 2 < 1 < 3 would be different from (2 < 1) < 3. That would bother me;
> not because it's so important to allow the current meaning of 2<1<3 to
> survive, but because it would be inconsistent with the way parentheses
> work in most other C contexts.
Well, that's an example, and I aimed to make it different deliberately
because I thought your point was that it would be hard to distinguish
between those two.
A simpler solution is to parse without creating the extra && nodes and
have the code generator (or some later parse tree re-writing) handle it.
Then (2 < 1) < 1 and 2 < (1 < 3) can easily mean the same as 2 < 1 < 3.
But none of this can be about C, surely, not even as an extension. In
that case (a < b) < c does not have to mean the same as a < b < c. The
relational operators (in this scheme) are non-associative, so the
programmer will know that the parentheses can change the meaning.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-10-08 14:02 -0400 |
| Message-ID | <j6q379$56l$1@dont-email.me> |
| In reply to | #11388 |
On 10/08/2011 05:45 AM, Ben Bacarisse wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>
>> On 10/07/2011 07:21 PM, Ben Bacarisse wrote:
...
>>> I'll try. I should go find some code probably but I am a bit short of
>>> time right now...
>>>
>>> Operators are marked with a precedence and an associativity. This
>>> latter can be "left", "right" or "none". The heart of the parser deals
>>> with operators with left or no associativity and a priority that is
>>> passed as an argument:
>>>
>>> exp = parse_exp_with_prio(priority + 1);
>>> last_right = null;
>>> while (next_token.prio == priority) {
>>> op = next_token;
>>> advance_token();
>>> right = parse_exp_with_prio(priority + 1);
>>> if (last_right != null && op.assoc == none) {
>>> e = make_exp(last_right, op, right);
>>> exp = make_exp(exp, '&&', e);
>>> }
>>> else exp = make_exp(exp, op, right);
>>> last_right = right;
>>> }
>>> return exp;
>>>
>>> When called with maximum priority, parse_exp_with_prio matches only
>>> constansts, names, and expressions in brackets. This nested case is
>>> handled by calling parse_exp_with_prio(0).
>>>
>>> So "0 < 3" goes round this loop once and builds one expression node
>>> with a < operator.
>>>
>>> "2 < 1 < 3" goes round twice. In the second iteration we notice that we
>>> have seen a previous "right operand" of this priority (it will be the
>>> constant 1) and we build (2 < 1) && (1 < 3) while setting last_right to
>>> 3 in case there are non-associative operators of the same priority.
>>>
>>> "(2 < 1) < 3" parses as normal. The request for exp on the left will
>>> eventually be matched by a call to parse_exp_with_prio with maximum
>>> priority. That will return 2 < 1 after calling parse_exp_with_prio(0)
>>> and matching the closing bracket. This nested call goes round the loop
>>> once. Having get exp on the left, we loop once to build (2 < 1) < 3.
>>
>> So 2 < 1 < 3 would be different from (2 < 1) < 3. That would bother me;
>> not because it's so important to allow the current meaning of 2<1<3 to
>> survive, but because it would be inconsistent with the way parentheses
>> work in most other C contexts.
>
> Well, that's an example, and I aimed to make it different deliberately
> because I thought your point was that it would be hard to distinguish
> between those two.
Not quite. I gave three expressions for an important reason. After I
sent that message, I've since realized that it would have been less
confusing to use an expression which would have a different value under
the current standard than it would have if the suggested change were made:
A: 3 < 2 < 1
B: (3 < 2) < 1
C: 0 < 1
Under the current standard, the first two statements have the same
meaning, and all three expressions have the same value. The fact that A
and B have the same meaning is needed for consistency with the rest of
the C language. The fact that B and C have the same value is needed for
consistency with the rest of the C language. You can change the meaning
of a < b < c to be (a<b) && (b<c), but only at the cost of breaking one
of those relationships. I don't care which one is broken, they're both
important, and I wouldn't like to see either one change.
In a new language that was otherwise similar to C, I'd favor having a
boolean type that was
a) Not treated as special kind of integer type
b) incapable of conversion to or from any other type.
c) the only type that could be used as a condition in #if preprocessing
directives; if(), while(), do while(), or for() statements; or ?:
expressions.
In such a language, the connection between B and C above would be
broken; and I wouldn't mind, but such a language could not be backward
compatible with existing C code, so I cannot favor any such change to C
itself.
> But none of this can be about C, surely, not even as an extension. In
I'm in agreement about that, but Edward Rutherford said:
> IMO it would be great if this could be backported to C.
And my comments have all been in the context of that comment.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-10-08 21:49 +0100 |
| Message-ID | <0.5dc2ca7041c5610fa99e.20111008214949BST.87ty7jtdhu.fsf@bsb.me.uk> |
| In reply to | #11400 |
James Kuyper <jameskuyper@verizon.net> writes: <snip> > A: 3 < 2 < 1 > B: (3 < 2) < 1 > C: 0 < 1 <snip> > In a new language that was otherwise similar to C, I'd favor having a > boolean type that was > a) Not treated as special kind of integer type > b) incapable of conversion to or from any other type. > c) the only type that could be used as a condition in #if preprocessing > directives; if(), while(), do while(), or for() statements; or ?: > expressions. > > In such a language, the connection between B and C above would be > broken; and I wouldn't mind, but such a language could not be backward > compatible with existing C code, so I cannot favor any such change to C > itself. I think your conditions are not quite enough. I'd say that the boolean type must not be ordered. If it is ordered, (false is usually < true) there is a reasonable (C-like) meaning to A -- it means the same as B and C. To fully break the connection between these expressions, booleans should be unordered. That's a step too far for lots of languages. For example, Haskell will sort a list of bool values as happily as it will any type with an ordering. It meets your conditions (a), (b) and (c) but the designers chose to make < non-associative so that 3 < 2 < 1 is a parse error rather than a type error. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-10-08 17:17 -0400 |
| Message-ID | <j6qeku$e4p$1@dont-email.me> |
| In reply to | #11408 |
On 10/08/2011 04:49 PM, Ben Bacarisse wrote: > James Kuyper <jameskuyper@verizon.net> writes: > <snip> >> A: 3 < 2 < 1 >> B: (3 < 2) < 1 >> C: 0 < 1 > <snip> >> In a new language that was otherwise similar to C, I'd favor having a >> boolean type that was >> a) Not treated as special kind of integer type >> b) incapable of conversion to or from any other type. >> c) the only type that could be used as a condition in #if preprocessing >> directives; if(), while(), do while(), or for() statements; or ?: >> expressions. >> >> In such a language, the connection between B and C above would be >> broken; and I wouldn't mind, but such a language could not be backward >> compatible with existing C code, so I cannot favor any such change to C >> itself. > > I think your conditions are not quite enough. I'd say that the boolean > type must not be ordered. If it is ordered, (false is usually < true) > there is a reasonable (C-like) meaning to A -- it means the same as B > and C. To fully break the connection between these expressions, > booleans should be unordered. I forgot a few additional item: d) expressions containing the defined operator in #if directives, and all relational, equality, and logical expressions have values of boolean type. e) Logical operators (&&, ||) require operands of boolean type. There's no need to prohibit comparisons of boolean values with each other for relative order, so long as they cannot be compared with anything else. In the hypothetical language that I was describing, 1 cannot be converted to a boolean type, and the boolean value of 3<2 cannot be converted to an integer type; without a common type that both can be converted to, "false < 1" would have to be a constraint violation. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-10-08 22:59 +0100 |
| Message-ID | <0.05da23b1f25502367918.20111008225930BST.87zkhbrvp9.fsf@bsb.me.uk> |
| In reply to | #11413 |
James Kuyper <jameskuyper@verizon.net> writes: > On 10/08/2011 04:49 PM, Ben Bacarisse wrote: >> James Kuyper <jameskuyper@verizon.net> writes: >> <snip> >>> A: 3 < 2 < 1 >>> B: (3 < 2) < 1 >>> C: 0 < 1 >> <snip> >>> In a new language that was otherwise similar to C, I'd favor having a >>> boolean type that was >>> a) Not treated as special kind of integer type >>> b) incapable of conversion to or from any other type. >>> c) the only type that could be used as a condition in #if preprocessing >>> directives; if(), while(), do while(), or for() statements; or ?: >>> expressions. >>> >>> In such a language, the connection between B and C above would be >>> broken; and I wouldn't mind, but such a language could not be backward >>> compatible with existing C code, so I cannot favor any such change to C >>> itself. >> >> I think your conditions are not quite enough. I'd say that the boolean >> type must not be ordered. If it is ordered, (false is usually < true) >> there is a reasonable (C-like) meaning to A -- it means the same as B >> and C. To fully break the connection between these expressions, >> booleans should be unordered. > > I forgot a few additional item: > d) expressions containing the defined operator in #if directives, and > all relational, equality, and logical expressions have values of boolean > type. > e) Logical operators (&&, ||) require operands of boolean type. > > There's no need to prohibit comparisons of boolean values with each > other for relative order, so long as they cannot be compared with > anything else. In the hypothetical language that I was describing, 1 > cannot be converted to a boolean type, and the boolean value of 3<2 > cannot be converted to an integer type; without a common type that both > can be converted to, "false < 1" would have to be a constraint > violation. Maybe I've missed your point, but it seems to be that a < b < c is perfectly valid when a, b and c are of type bool (not C bool -- this hypothetical language's bool) provided that bool is an ordered type. I was not saying that an ordered bool type somehow effected 3 < 2 < 1, just that it affects some syntactically similar expressions. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-10-08 21:33 -0400 |
| Message-ID | <j6qtl9$1v0$1@dont-email.me> |
| In reply to | #11417 |
On 10/08/2011 05:59 PM, Ben Bacarisse wrote: > James Kuyper <jameskuyper@verizon.net> writes: ... >> There's no need to prohibit comparisons of boolean values with each >> other for relative order, so long as they cannot be compared with >> anything else. In the hypothetical language that I was describing, 1 >> cannot be converted to a boolean type, and the boolean value of 3<2 >> cannot be converted to an integer type; without a common type that both >> can be converted to, "false < 1" would have to be a constraint >> violation. > > Maybe I've missed your point, but it seems to be that > > a < b < c > > is perfectly valid when a, b and c are of type bool (not C bool -- this > hypothetical language's bool) provided that bool is an ordered type. I > was not saying that an ordered bool type somehow effected 3 < 2 < 1, > just that it affects some syntactically similar expressions. You're right, I'd forgotten to cover that possibility. It seems we must sacrifice either sortability of boolean values, or the proposed new meaning for a<b<c. Given those options, I favor sortability. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-10-09 09:09 +0100 |
| Message-ID | <0.2dfc50b72ffcd236185f.20111009090921BST.87ipnysi1a.fsf@bsb.me.uk> |
| In reply to | #11422 |
James Kuyper <jameskuyper@verizon.net> writes: > On 10/08/2011 05:59 PM, Ben Bacarisse wrote: >> James Kuyper <jameskuyper@verizon.net> writes: > ... >>> There's no need to prohibit comparisons of boolean values with each >>> other for relative order, so long as they cannot be compared with >>> anything else. In the hypothetical language that I was describing, 1 >>> cannot be converted to a boolean type, and the boolean value of 3<2 >>> cannot be converted to an integer type; without a common type that both >>> can be converted to, "false < 1" would have to be a constraint >>> violation. >> >> Maybe I've missed your point, but it seems to be that >> >> a < b < c >> >> is perfectly valid when a, b and c are of type bool (not C bool -- this >> hypothetical language's bool) provided that bool is an ordered type. I >> was not saying that an ordered bool type somehow effected 3 < 2 < 1, >> just that it affects some syntactically similar expressions. > > You're right, I'd forgotten to cover that possibility. It seems we must > sacrifice either sortability of boolean values, or the proposed new > meaning for a<b<c. Given those options, I favor sortability. The "problem" (I am not sure i remember what it is) may be worse in the I used < following your example, but the general idea would be to do this for all relations operators, so a == b == c would be permitted to mean a == b && b == c (with b evaluated only once). It would be a bog step to outlaw equality testing for bool. Again, unless I'm missing the main point, I don't see the problem. If this hypothetical language clearly states all the relational operators and non-associative, chains of them must mean something other the usual default pair-wise bracketing that associativity implies. Given that in mathematics, (a < b) < c is at the very least odd, or rare, compared to a < b < c, I'd be happy for it to have it's obvious meaning distinct from the unbracketed version. In many non-C-like languages, things like (3 < 2) < 1 will be type error anyway, so the only "silent" cases would be the very rare examples of bracketed comparisons of booleans. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-10-09 07:00 -0400 |
| Message-ID | <j6rutc$sc0$1@dont-email.me> |
| In reply to | #11432 |
On 10/09/2011 04:09 AM, Ben Bacarisse wrote: ... > The "problem" (I am not sure i remember what it is) may be worse in the > I used < following your example, but the general idea would be to do > this for all relations operators, so > > a == b == c > > would be permitted to mean a == b && b == c (with b evaluated only > once). It would be a bog step to outlaw equality testing for bool. > > Again, unless I'm missing the main point, I don't see the problem. If > this hypothetical language clearly states all the relational operators > and non-associative, chains of them must mean something other the usual > default pair-wise bracketing that associativity implies. Associativity isn't the relevant characteristic. Associativity is about how an expression's meaning can be rearranged, while still having the same value; my issue with this proposal doesn't have anything to do with an expression's possible rearrangements. In the hypothetical language I was discussing, chains of relational or equality operators would necessarily be constraint violations - unless all values being compared after the first two were of boolean type - and that's the problem. There's no way to handle that case which is consistent with the proposed chain rule for relational and equality operators without violating a key feature that the hypothetical language was intended to share with C. The relevant feature of C is that every complex expression can be broken down recursively into a top-level operator operating on the value of it's sub-expressions. The value and meaning of the sub-expressions depends only upon the sub-expression itself, not on the context in which it occurs. What the top-level operation does depends only upon the values of it's operands, and not upon how they were calculated. I can think of a few special exceptions (for instance, the fact that &*p can have a well-defined meaning in contexts where *p does not), but in general this is a fundamental feature of the structure of C. The proposed new interpretation of x = a == b == c; would make it quite different from auto temp = a == b; x = temp == c; I've borrowed here a new feature of C++, where the 'auto' keyword causes 'temp' to be declared with precisely the type of it's initializer. That type would be 'int' in C; and 'bool' in the hypothetical language I've been referring to, but the issue is the same in both cases. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2011-10-09 01:12 +0100 |
| Message-ID | <j6qp25$c5s$1@dont-email.me> |
| In reply to | #11388 |
"Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
news:0.9c297e0e5b9ae67129fd.20111008104538BST.87zkhbu88t.fsf@bsb.me.uk...
> A simpler solution is to parse without creating the extra && nodes and
> have the code generator (or some later parse tree re-writing) handle it.
> Then (2 < 1) < 1 and 2 < (1 < 3) can easily mean the same as 2 < 1 < 3.
>
> But none of this can be about C, surely, not even as an extension. In
> that case (a < b) < c does not have to mean the same as a < b < c. The
> relational operators (in this scheme) are non-associative, so the
> programmer will know that the parentheses can change the meaning.
I've had a go at implementing a<b<c for one of my language projects.
The expression is modified in a subsequent pass, after already being parsed
as (< (< a b) c). When the left operand of a compare op is also a compare
op, the whole thing gets changed to (and (< a b) (< b c)).
('b' gets evaluated twice, but I don't care; not at this time of night
anyway.)
This works fine (also for long chains of relational and equality ops).
But I thought that by writing (a<b)<c, I could also turn a<b into a bool
result, and compare that against c (this is more useful when written as
(a<b)==c), but it doesn't work! The parentheses disappear. Which in fact is
as it should be:
If a<b<c is usually evaluated as (a<b)<c, then actually writing (a<b)<c
should do the same. (So some dummy op is needed to isolate the a<b bit - in
C that might be something like !!(a<b) - so that the conversion above is not
triggered.)
(Then I tried a<(b<c), which does compare a against the bool result of b<c;
that's OK, as there is no other meaning for that. The only niggle is that it
doesn't match the behaviour of a+b+c and a+(b+c), which are more or less the
same.)
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-10-09 08:55 +0100 |
| Message-ID | <0.e63445836250346188d0.20111009085536BST.87obxqsio7.fsf@bsb.me.uk> |
| In reply to | #11420 |
"BartC" <bc@freeuk.com> writes:
> "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
> news:0.9c297e0e5b9ae67129fd.20111008104538BST.87zkhbu88t.fsf@bsb.me.uk...
>
>> A simpler solution is to parse without creating the extra && nodes and
>> have the code generator (or some later parse tree re-writing) handle it.
>> Then (2 < 1) < 1 and 2 < (1 < 3) can easily mean the same as 2 < 1 < 3.
>>
>> But none of this can be about C, surely, not even as an extension. In
>> that case (a < b) < c does not have to mean the same as a < b < c. The
>> relational operators (in this scheme) are non-associative, so the
>> programmer will know that the parentheses can change the meaning.
>
> I've had a go at implementing a<b<c for one of my language projects.
>
> The expression is modified in a subsequent pass, after already being
> parsed as (< (< a b) c). When the left operand of a compare op is also
> a compare op, the whole thing gets changed to (and (< a b) (< b c)).
>
> ('b' gets evaluated twice, but I don't care; not at this time of night
> anyway.)
That should be fixed but I can see it's not a priority in an experiment.
> This works fine (also for long chains of relational and equality ops).
>
> But I thought that by writing (a<b)<c, I could also turn a<b into a
> bool result, and compare that against c (this is more useful when
> written as (a<b)==c), but it doesn't work! The parentheses
> disappear. Which in fact is as it should be:
The simples options is to parse are I originally described, and then,
because the operators are non-associative, adding brackets to the left
or to the right will produce something new.
Once you have a parse tree of (< (< a b) c) there is no way to know if
it's from (a < b) < c or a plain a < b < c. There might be a kludge in
that could use a spare bit in the operator to indicate if it was
originally in parentheses, but that's, well, a kludge!
> If a<b<c is usually evaluated as (a<b)<c, then actually writing
> (a<b)<c should do the same. (So some dummy op is needed to isolate the
> a<b bit - in C that might be something like !!(a<b) - so that the
> conversion above is not triggered.)
I don't follow this. If a<b<c is usually evaluated as (a<b)<c that's
what you should do, and a<b<c can't have it's special meaning.
> (Then I tried a<(b<c), which does compare a against the bool result of
> b<c; that's OK, as there is no other meaning for that. The only niggle
> is that it doesn't match the behaviour of a+b+c and a+(b+c), which are
> more or less the same.)
Id say it's not a niggle at all -- it perfect. < is not symmetric, so a
better comparison is with a-b-c which changes meaning with brackets:
a-(b-c).
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2011-10-07 18:16 -0500 |
| Message-ID | <rj1v871u15fpmnp1b8avt7gvun3769tc69@4ax.com> |
| In reply to | #11353 |
On Fri, 07 Oct 2011 23:12:51 +0100, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote: >James Kuyper <jameskuyper@verizon.net> writes: ><snip> >> You could define '< <' as a special trinary operator like "?:". But then >> you'd have to define a<b<c<d as a quaternary operator, etc. That way >> lies madness. > >The madness can be avoided. There's no need define tertiary or >quaternary (and so on) versions. In fact doing so either rules out a < >b <= c or it means you need < <= as yet another operator (and so on for >dozens of combinations). > >If <, >, <=, >=, == and != all have the same priority, you can parse it >just like a + b - c + d and simply double the operand you have "in hand" >and add &&. The operators need to be marked as non-associative, but it >can be fitted into an operator precedence grammar very simply. > >I've spent the last hour (not exclusively, you understand) trying to >remember what language it was that I've worked on that does this, and >I've come up with nothing. But I don't think I'm making it up, honest. Cobol 68 did something like that. You could write: IF A IS GREATER THAN B OR C (or equivalently) IF A > B OR C You could also do things like: IF A IS EQUAL TO B AND NOT C (and yes, the second term(?) is "A IS NOT EQUAL TO C") My history on this is a bit fuzzy, but I think that form was removed in Cobol 7x. Or maybe that was pre-68 and it was removed in '68. That and a related syntactical oddity introduced some *really* confusing logical statements when the conditions became complex.
[toc] | [prev] | [next] | [standalone]
| From | David Thompson <dave.thompson2@verizon.net> |
|---|---|
| Date | 2011-10-18 02:03 -0400 |
| Message-ID | <195q97lp8gqkc4kf23g2oo574d8cpie9ct@4ax.com> |
| In reply to | #11362 |
On Fri, 07 Oct 2011 18:16:40 -0500, Robert Wessel <robertwessel2@yahoo.com> wrote: > On Fri, 07 Oct 2011 23:12:51 +0100, Ben Bacarisse > <ben.usenet@bsb.me.uk> wrote: <snip: a<b<c etc.> > >If <, >, <=, >=, == and != all have the same priority, you can parse it > >just like a + b - c + d and simply double the operand you have "in hand" > >and add &&. The operators need to be marked as non-associative, but it > >can be fitted into an operator precedence grammar very simply. > > > >I've spent the last hour (not exclusively, you understand) trying to > >remember what language it was that I've worked on that does this, and > >I've come up with nothing. But I don't think I'm making it up, honest. > > > Cobol 68 did something like that. You could write: > > IF A IS GREATER THAN B OR C > > (or equivalently) > > IF A > B OR C > > You could also do things like: > > IF A IS EQUAL TO B AND NOT C > > (and yes, the second term(?) is "A IS NOT EQUAL TO C") > > My history on this is a bit fuzzy, but I think that form was removed > in Cobol 7x. Or maybe that was pre-68 and it was removed in '68. > Still in -74 and -85. And still in the last draft I looked at for -03; I didn't follow to completion, but I would be astonished if they dropped a longstanding feature that is trivial to implement. Of course this repeats the _left_ comparand (and possibly the operator), not the right which as elsethread Icon does. FWIW in (Common)Lisp all operators are syntactically function calls, allowing variable number of arguments e.g. (< 3 4) and (< 3 4 5 6 7). These do have the 'obvious' semantics, except maybe /= notequal which per standard checks all pairs not just adjacent pairs (as the C syntax presumably would); I don't recall ever wanting /= with more than 2 operands for any real purpose, and thus exercising that case.
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2011-10-20 18:03 -0500 |
| Message-ID | <r591a7hfugnq0vcmrtsh38q0q8nke7qpkg@4ax.com> |
| In reply to | #11850 |
On Tue, 18 Oct 2011 02:03:54 -0400, David Thompson <dave.thompson2@verizon.net> wrote: >On Fri, 07 Oct 2011 18:16:40 -0500, Robert Wessel ><robertwessel2@yahoo.com> wrote: > >> On Fri, 07 Oct 2011 23:12:51 +0100, Ben Bacarisse >> <ben.usenet@bsb.me.uk> wrote: ><snip: a<b<c etc.> >> >If <, >, <=, >=, == and != all have the same priority, you can parse it >> >just like a + b - c + d and simply double the operand you have "in hand" >> >and add &&. The operators need to be marked as non-associative, but it >> >can be fitted into an operator precedence grammar very simply. >> > >> >I've spent the last hour (not exclusively, you understand) trying to >> >remember what language it was that I've worked on that does this, and >> >I've come up with nothing. But I don't think I'm making it up, honest. >> >> >> Cobol 68 did something like that. You could write: >> >> IF A IS GREATER THAN B OR C >> >> (or equivalently) >> >> IF A > B OR C >> >> You could also do things like: >> >> IF A IS EQUAL TO B AND NOT C >> >> (and yes, the second term(?) is "A IS NOT EQUAL TO C") >> >> My history on this is a bit fuzzy, but I think that form was removed >> in Cobol 7x. Or maybe that was pre-68 and it was removed in '68. >> >Still in -74 and -85. And still in the last draft I looked at for -03; >I didn't follow to completion, but I would be astonished if they >dropped a longstanding feature that is trivial to implement. > >Of course this repeats the _left_ comparand (and possibly the >operator), not the right which as elsethread Icon does. > >FWIW in (Common)Lisp all operators are syntactically function calls, >allowing variable number of arguments e.g. (< 3 4) and (< 3 4 5 6 7). >These do have the 'obvious' semantics, except maybe /= notequal which >per standard checks all pairs not just adjacent pairs (as the C syntax >presumably would); I don't recall ever wanting /= with more than 2 >operands for any real purpose, and thus exercising that case. I blame age and fading memories... True enough, implied subjects and relations still exist, but they did change the rules in Cobol-74. Notably the binding of NOT in conditionals with implied relationals changed. In Cobol 68: IF A > B AND NOT < C AND D parsed as: IF (A > B) AND (NOT A < C) AND (A < D) In Cobol-74, the NOT binds to the less than instead, changing that to: IF (A > B) AND (A NOT < C) AND (A NOT < D) Which doesn't change the practical meaning of the middle term (in approximate C* terms it goes from (!(a<c)) to ((a!<c)) ), but it certainly changes the meaning of the third term. *Ignoring that C doesn't actually have a "!<" (not less than) operator
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web