Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Proposal: More flexible comparisons

0 views
Skip to first unread message

Ioannis Vranos

unread,
Jun 25, 2009, 7:34:00 AM6/25/09
to
Proposal:


I think the following simple approach will provide great flexibility in conditions.


The style:

1.

if(1<x<4)
// ...


2.

if(1<x<4 and 3<=y<=5 and z>1)
// ...


--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net

Bo Persson

unread,
Jun 25, 2009, 8:18:12 AM6/25/09
to
Ioannis Vranos wrote:
> Proposal:
>
>
> I think the following simple approach will provide great
> flexibility in conditions.
>
> The style:
>
> 1.
>
> if(1<x<4)
> // ...
>
>
> 2.
>
> if(1<x<4 and 3<=y<=5 and z>1)
> // ...

The proposal has the disadvantage that it proposes new semantics for
an existing syntax. Very low likelyhood for acceptance.

Example 1 could also be written as

if (x == 2 or 3)

with the same problem.


Bo Persson


Message has been deleted

Ioannis Vranos

unread,
Jun 25, 2009, 9:35:10 AM6/25/09
to


What do you mean new semantics. The first example could be resolved to:


if(1<x and x<4)

Juha Nieminen

unread,
Jun 25, 2009, 9:36:32 AM6/25/09
to
Ioannis Vranos wrote:
> if(1<x<4)

How should this be interpreted?

if(a < b < c < d)

Ioannis Vranos

unread,
Jun 25, 2009, 9:45:30 AM6/25/09
to


This can be interpreted as:

if(a<b and b< c and c< d)

Ioannis Vranos

unread,
Jun 25, 2009, 10:16:41 AM6/25/09
to
Ioannis Vranos wrote:
> Proposal:
>
>
> I think the following simple approach will provide great flexibility in
> conditions.
>
>
> The style:
>
> 1.
>
> if(1<x<4)
> // ...
>
>
> 2.
>
> if(1<x<4 and 3<=y<=5 and z>1)
> // ...

My mistake.

The condition


1<x<4 is currently valid, it is evaluated from left to right as usual and is equivalent to

(1<x)<4


which is not the obvious mathematical meaning.

Victor Bazarov

unread,
Jun 25, 2009, 10:26:28 AM6/25/09
to

Both are valid constructs now, AFAICT. Right? So, we can't expect the
language to introduce a different interpretation of those because it
might break existing code. The (1<x<4) always evaluates to 'true' (now)
and the example you gave evaluates to 'true' when (a >= b) and (c < d).

I understand that you want to know what the proposal is in more detail,
don't get me wrong.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Richard Herring

unread,
Jun 25, 2009, 10:33:42 AM6/25/09
to
In message <h1vuee$po4$1...@news.grnet.gr>, Ioannis Vranos
<ivr...@freemail.gr> writes

>Bo Persson wrote:
>> Ioannis Vranos wrote:
>>> Proposal:
>>>
>>>
>>> I think the following simple approach will provide great
>>> flexibility in conditions.
>>>
>>> The style:
>>>
>>> 1.
>>>
>>> if(1<x<4)
>>> // ...
>>>
>>>
>>> 2.
>>>
>>> if(1<x<4 and 3<=y<=5 and z>1)
>>> // ...
>> The proposal has the disadvantage that it proposes new semantics for
>>an existing syntax. Very low likelyhood for acceptance.
>> Example 1 could also be written as
>> if (x == 2 or 3)
>> with the same problem.
>
>
>What do you mean new semantics.

Semantics that differ from the existing semantics, presumably. (1<x<4)
is already a valid expression in C++, but it doesn't mean (i.e. its
existing semantics are other than) what you would like it to.


>The first example could be resolved to:
>
>
>if(1<x and x<4)
> // ...
>
>
>

--
Richard Herring

Ioannis Vranos

unread,
Jun 25, 2009, 10:38:32 AM6/25/09
to
Ioannis Vranos wrote:
> Proposal:
>
>
> I think the following simple approach will provide great flexibility in
> conditions.
>
>
> The style:
>
> 1.
>
> if(1<x<4)
> // ...
>
>
> 2.
>
> if(1<x<4 and 3<=y<=5 and z>1)
> // ...


The proposal corrected:

I think a keyword like "condition" with function semantics, and with the operands evaluated only once, would
provide great flexibility (readability), abstraction and efficiency optimisation:


For example:


while( condition(x< z< pow(x,y)<= 35) )
// ...

would mean:


while(x< z and z< pow(x,y) and pow(x,y)<= 35)
// ...


The first code is more readable, provides the ability to evaluate pow(x, y) only once, and thus is more flexible.


Any thoughts are welcome.

Ioannis Vranos

unread,
Jun 25, 2009, 10:45:19 AM6/25/09
to
Clarification:


Ioannis Vranos wrote:
>
> The proposal corrected:
>

I think a keyword like "condition" with function ==> appearance, and ==> perhaps under the rule with the


> operands evaluated only once, would provide great flexibility
> (readability), abstraction and efficiency optimisation:
>
>
> For example:


==> int x= 2, y= 3;

Jonathan Lee

unread,
Jun 25, 2009, 11:11:45 AM6/25/09
to
> I think the following simple approach will provide great flexibility in conditions.
> ...
> if(1<x<4)

While we're on the topic, I wish there was an "in" operator, ∈. As in
set-theory membership. Then you might be able to write something like

if (x ∈ (1,4)) { } // if (x in (1,4)) { }

Also while we're at it, unions, intersections, subset,...

No joke. That would be awesome.

--Jonathan

Victor Bazarov

unread,
Jun 25, 2009, 11:33:33 AM6/25/09
to

But you can do it yourself. You can define a class Interval with a
consturctor that takes two ends (or four classes: OpenInterval,
ClosedInterval, OpenClosedInterval, ClosedOpenInterval), and then define
an operator, say, equality. Here is pseudo code:

template<class value_type> struct Interval_t
{
value_type from, to;

Interval_t(value_type f, value_type t) : from(f), to(t) {}
};

template<class T> Interval_t<T> Interval(T f, T t)
{
return Interval_t<T>(f, t);
}

template<class T> bool operator ^ (T t, Interval_t<T> const& i)
{
return t > i.from && t < i.to;
}

int main()
{
bool in = 4 ^ Interval(1, 10));
bout out = 444 ^ Interval(1, 10));

Jonathan Lee

unread,
Jun 25, 2009, 12:03:40 PM6/25/09
to
> But you can do it yourself.
> ...
> V

I really just mean the notation. As it is I pretty much do as you've
suggested, and mimic the functionality (though I tend to use '<' to
hint at subset notationt). But I'm more of a mathematician than a
programmer so it doesn't really "feel" right. Highly subjective, I
know.

But I don't immediately see what would be wrong with allowing the user
to introduce new binary operators. Source could be written in Unicode,
so that's not a huge issue. And precedence could be specified at the
time of declaration:

operator @ like ^; // new operator, @, has precedence of ^

I see the potential for abuse, but used correctly I think it would
make a lot of things more readable.

--Jonathan

Victor Bazarov

unread,
Jun 25, 2009, 12:54:39 PM6/25/09
to

What symbol would you use for "belongs" or "includes" (for sets)? You
already can do

#define is ^
#define in Interval
...
if (4 is in (1, 10))
...

Preprocessor is not always your enemy.

Pete Becker

unread,
Jun 25, 2009, 1:06:46 PM6/25/09
to
Victor Bazarov wrote:
> Juha Nieminen wrote:
>> Ioannis Vranos wrote:
>>> if(1<x<4)
>>
>> How should this be interpreted?
>>
>> if(a < b < c < d)
>
> Both are valid constructs now, AFAICT. Right? So, we can't expect the
> language to introduce a different interpretation of those because it
> might break existing code. The (1<x<4) always evaluates to 'true' (now)
> and the example you gave evaluates to 'true' when (a >= b) and (c < d).
>

Well, "might break existing code" is relative. It wouldn't bother me in
the least if those examples changed meaning, since "might" here is
purely hypothetical. On the other hand, I don't find the suggested new
meaning particularly compelling.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)

Jonathan Lee

unread,
Jun 25, 2009, 1:38:46 PM6/25/09
to
> What symbol would you use for "belongs" or "includes" (for sets)?

The usual "element of". I don't think it'll show up in the newsgroup
post, but this is what I mean:
http://www.fileformat.info/info/unicode/char/2208/index.htm

Similarly, cup for union, etc. Basically, as you would write it with
pen and paper.

I realize the characters are not easy to type since they aren't on any
keyboard -- it's just wishful thinking. Also, being familiar with some
WYSIWYG LaTeX editors makes me inclined to think it's not _that_
troublesome.

>     #define is ^
>     #define in Interval
>     ...
>         if (4 is in (1, 10))
>     ...

Interesting. I usually *do* think of the preprocessor as my enemy :)
But that could be useful.

--Jonathan

Juha Nieminen

unread,
Jun 25, 2009, 5:36:48 PM6/25/09
to
Pete Becker wrote:
> Victor Bazarov wrote:
>> Juha Nieminen wrote:
>>> Ioannis Vranos wrote:
>>>> if(1<x<4)
>>>
>>> How should this be interpreted?
>>>
>>> if(a < b < c < d)
>>
>> Both are valid constructs now, AFAICT. Right? So, we can't expect
>> the language to introduce a different interpretation of those because
>> it might break existing code. The (1<x<4) always evaluates to 'true'
>> (now) and the example you gave evaluates to 'true' when (a >= b) and
>> (c < d).
>>
>
> Well, "might break existing code" is relative. It wouldn't bother me in
> the least if those examples changed meaning, since "might" here is
> purely hypothetical. On the other hand, I don't find the suggested new
> meaning particularly compelling.

I wonder if something like "if(a<b> c)" could cause a conflict with
template code.

Also overloading the comparison operators could become interesting
with the proposed semantics. You could end up with some really
obfuscated code along the lines of "if(a<b><c> d)".

I wouldn't want to write a lexer for that.

James Kanze

unread,
Jun 26, 2009, 4:50:03 AM6/26/09
to
On Jun 25, 3:45 pm, Ioannis Vranos <ivra...@freemail.gr> wrote:
> Juha Nieminen wrote:
> > Ioannis Vranos wrote:
> >> if(1<x<4)

> > How should this be interpreted?

> > if(a < b < c < d)

> This can be interpreted as:

> if(a<b and b< c and c< d)

Not in C++. In C++, it is:

if ( ((a < b) < c) < d )

While there is some merit in your suggestion, it would break
code which depends on the above meaning, and so has very little
chance of being adopted. (On the other hand, I suspect that
code which actually wants the above semantics is very rare; I
think even that some compilers warn about it.)

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze

unread,
Jun 26, 2009, 4:54:00 AM6/26/09
to
On Jun 25, 11:36 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> Pete Becker wrote:
> > Victor Bazarov wrote:
> >> Juha Nieminen wrote:
> >>> Ioannis Vranos wrote:
> >>>> if(1<x<4)

> >>> How should this be interpreted?

> >>> if(a < b < c < d)

> >> Both are valid constructs now, AFAICT. Right? So, we
> >> can't expect the language to introduce a different
> >> interpretation of those because it might break existing
> >> code. The (1<x<4) always evaluates to 'true' (now) and the
> >> example you gave evaluates to 'true' when (a >= b) and (c <
> >> d).

> > Well, "might break existing code" is relative. It wouldn't
> > bother me in the least if those examples changed meaning,
> > since "might" here is purely hypothetical. On the other
> > hand, I don't find the suggested new meaning particularly
> > compelling.

> I wonder if something like "if(a<b> c)" could cause a conflict
> with template code.

No. The language doesn't require the compiler to do that much
look-ahead. If a names a template, a '<' which immediately
follows it always opens a template argument list (even if there
is no '>' later), otherwise, it is always a less than operator.
(C++ doesn't have a context free grammar.)

> Also overloading the comparison operators could become interesting
> with the proposed semantics. You could end up with some really
> obfuscated code along the lines of "if(a<b><c> d)".

> I wouldn't want to write a lexer for that.

It would be no more difficult that the current situation.

Hendrik Schober

unread,
Jun 26, 2009, 4:55:29 AM6/26/09
to
Victor Bazarov wrote:
> [...] You
> already can do
>
> #define is ^
> #define in Interval
> ...
> if (4 is in (1, 10))
> ...
>
> Preprocessor is not always your enemy.

Except that this wreaks havoc with code like this
std::istream& operator<<(std::istream& is, const T& o);
which isn't really uncommon.

Using this <http://www.research.att.com/~bs/whitespace98.pdf>
idea, however, we can introduce a class 'in', overload the
appropriate operator, and everything works beautifully. :)

> V

Schobi

Fred Zwarts

unread,
Jun 26, 2009, 5:04:08 AM6/26/09
to
"Juha Nieminen" <nos...@thanks.invalid> wrote in message news:Q5S0m.262$ct6...@read4.inet.fi...

> Pete Becker wrote:
>> Victor Bazarov wrote:
>>> Juha Nieminen wrote:
>>>> Ioannis Vranos wrote:
>>>>> if(1<x<4)
>>>>
>>>> How should this be interpreted?
>>>>
>>>> if(a < b < c < d)
>>>
>>> Both are valid constructs now, AFAICT. Right? So, we can't expect
>>> the language to introduce a different interpretation of those because
>>> it might break existing code. The (1<x<4) always evaluates to 'true'
>>> (now) and the example you gave evaluates to 'true' when (a >= b) and
>>> (c < d).
>>>
>>
>> Well, "might break existing code" is relative. It wouldn't bother me in
>> the least if those examples changed meaning, since "might" here is
>> purely hypothetical. On the other hand, I don't find the suggested new
>> meaning particularly compelling.
>
> I wonder if something like "if(a<b> c)" could cause a conflict with
> template code.

Isn't there a conflict already with the current meaning?

>
> Also overloading the comparison operators could become interesting
> with the proposed semantics. You could end up with some really
> obfuscated code along the lines of "if(a<b><c> d)".
>
> I wouldn't want to write a lexer for that.

Would that be more complex then it is with the current meaning?

Fred Zwarts

unread,
Jun 26, 2009, 5:43:40 AM6/26/09
to
"Jonathan Lee" <cho...@shaw.ca> wrote in message news:4289fa26-0d24-4599...@s16g2000vbp.googlegroups.com...

I don't think it is a good idea to add operators to a general purpose
language for each mathematical operation that mathematicians can
think of. Giving each of them a separate character is also not a
good idea. My keyboard is not big enough and I don't like
more keys like shift, alt, Ctrl, and combinations thereof.
Maybe that a mathematician would find it easier to read,
for others it will become very difficult to understand the differences
between *, ¤, ∈, ×, /,⁄, ÷, ·, ., ¯,–, —,¬,-,ø,‡,†.
The language should define a small amount of elementary operations
in which other more complex operations can be expressed.
more complex operators should have a descriptive name.
I think C++ offers enough elementary operations for integral numbers.
and the possibility to extend it with classes and overloading are also sufficient.

Jonathan Lee

unread,
Jun 26, 2009, 9:41:15 AM6/26/09
to
> Except that this wreaks havoc with code like this
>    std::istream& operator<<(std::istream& is, const T& o);
> which isn't really uncommon.

True, but maybe there is the possibility of #define-ing in as LaTeX
would: \in. Or even the unicode character itself, but I don't know
offhand if the preprocessor will recognize the character.

> Using this <http://www.research.att.com/~bs/whitespace98.pdf>
> idea, however, we can introduce a class 'in', overload the
> appropriate operator, and everything works beautifully. :)

Too bad that was written as an April Fool's joke :) The wing dings
with the telephone was priceless.

Still, the exaggeration doesn't mean it's a totally bad idea. You
could probably make an identifier out of the first chapter of
"Finnegan's Wake" and underscores, but that doesn't mean identifiers
are a bad idea in general. For example, I think at least a couple
people here would appreciate a cross-product, or dot-product operator.
But anyways, it's not a proposal of any sort. Just thinking out loud.

robert...@yahoo.com

unread,
Jun 27, 2009, 3:16:11 AM6/27/09
to
On Jun 25, 6:34 am, Ioannis Vranos <ivra...@freemail.gr> wrote:
> Proposal:
>
> I think the following simple approach will provide great flexibility in conditions.
>
> The style:
>
> 1.
>
> if(1<x<4)
>    // ...
>
> 2.
>
> if(1<x<4 and 3<=y<=5 and z>1)
>    // ...


While it has some merit, it doesn't appear to work very well in
practice. Take a look at Cobol, which has done that since the sixties
(although they did change how some of the complex combinations are
interpreted in COBOL-74). Most coding standards prohibit the use of
those forms, for pretty good reason - while simple case are not too
bad, it's very easy to generate statements that are very hard to
interpret (for humans).

Juha Nieminen

unread,
Jun 27, 2009, 4:48:32 AM6/27/09
to
Fred Zwarts wrote:
>> Also overloading the comparison operators could become interesting
>> with the proposed semantics. You could end up with some really
>> obfuscated code along the lines of "if(a<b><c> d)".
>>
>> I wouldn't want to write a lexer for that.
>
> Would that be more complex then it is with the current meaning?

Can you currently write something like "a<b><c> d" so that it's
syntactically and semantically correct?

Juha Nieminen

unread,
Jun 27, 2009, 4:56:21 AM6/27/09
to
Hendrik Schober wrote:
> Victor Bazarov wrote:
>> [...] You already can do
>>
>> #define is ^
>> #define in Interval
>> ...
>> if (4 is in (1, 10))
>> ...
>>
>> Preprocessor is not always your enemy.
>
> Except that this wreaks havoc with code like this
> std::istream& operator<<(std::istream& is, const T& o);
> which isn't really uncommon.

Preprocessor macros messing up things is a relatively common problem.
For example, some versions of the C++ standard library implementation in
MSVC defined min() and max() as macros. This naturally caused havoc
anywhere you wanted to use those names, such as:

namespace
{
MyType min(MyType a, MyType b) { return ...; }
}

I once used an enumerated constant named NO_ERROR (inside a class) in
a library I made. Someone reported that this caused problems with some
version of Borland C++ because some library in that compiler defined
that name as a preprocessor macro.

Ioannis Vranos

unread,
Jun 27, 2009, 5:23:12 AM6/27/09
to
There can't be any solution for this, since the


a< b< c< d


expression is currently evaluated from left to right (as usual) and it is equivalent to:

((a<b)<c)<d


which is no the expected normal notion.


If we introduce any notion that does the mathematical meaning, even this someone else suggested:


x E [1, 4]

or something similar like


x= [1,4]

x=[1,4)


e.t.c.


there will be confusion with the current evaluation of

1<x<=4


which currently is evaluated to (1<x)<=4.

However although controversial, I think the committee can force a fix on the issue and break the incorrect
notion when more than one comparison operators are present, to the correct mathematical meaning, as they did
break the notion of the largest built-in signed/unsigned integral types, with the introduction of the
unnecessary long long/unsigned long long integral types.

Hendrik Schober

unread,
Jun 29, 2009, 5:51:41 AM6/29/09
to
Juha Nieminen wrote:
> Hendrik Schober wrote:
>> Victor Bazarov wrote:
>>> [...] You already can do
>>>
>>> #define is ^
>>> #define in Interval
>>> ...
>>> if (4 is in (1, 10))
>>> ...
>>>
>>> Preprocessor is not always your enemy.
>> Except that this wreaks havoc with code like this
>> std::istream& operator<<(std::istream& is, const T& o);
>> which isn't really uncommon.
>
> Preprocessor macros messing up things is a relatively common problem.
> For example, some versions of the C++ standard library implementation in
> MSVC defined min() and max() as macros. This naturally caused havoc
> anywhere you wanted to use those names, such as:
>
> namespace
> {
> MyType min(MyType a, MyType b) { return ...; }
> }

NOMINMAX

> I once used an enumerated constant named NO_ERROR (inside a class) in
> a library I made. Someone reported that this caused problems with some
> version of Borland C++ because some library in that compiler defined
> that name as a preprocessor macro.

But then identifiers in upper case are commonly used
for macros, so if you introduce one, you know you run
the risk of it being trampled over.
I find the habit to make constants all upper case odd,
and the only explanation I see for their existence is
that they are a left-over from the times when constants
really where macros. Get rid of that habit and have
less problems.

Schobi

Pete Becker

unread,
Jun 29, 2009, 9:40:53 AM6/29/09
to
Hendrik Schober wrote:
>>
>> Preprocessor macros messing up things is a relatively common problem.
>> For example, some versions of the C++ standard library implementation in
>> MSVC defined min() and max() as macros.

No, it's not the C++ standard library. It's the Windows headers.

Juha Nieminen

unread,
Jun 29, 2009, 2:50:52 PM6/29/09
to
Hendrik Schober wrote:
>> I once used an enumerated constant named NO_ERROR (inside a class) in
>> a library I made. Someone reported that this caused problems with some
>> version of Borland C++ because some library in that compiler defined
>> that name as a preprocessor macro.
>
> But then identifiers in upper case are commonly used
> for macros, so if you introduce one, you know you run
> the risk of it being trampled over.
> I find the habit to make constants all upper case odd,
> and the only explanation I see for their existence is
> that they are a left-over from the times when constants
> really where macros. Get rid of that habit and have
> less problems.

But it's a good example of a compiler breaking perfectly standard C++
code because of macros and their naming.

If it had either not used a macro, or used a name reserved for the
compiler (ie. starting with an underscore), the problem would not have
happened.

Hendrik Schober

unread,
Jun 29, 2009, 3:45:45 PM6/29/09
to
Juha Nieminen wrote:
> Hendrik Schober wrote:
>>> I once used an enumerated constant named NO_ERROR (inside a class) in
>>> a library I made. Someone reported that this caused problems with some
>>> version of Borland C++ because some library in that compiler defined
^^^^^^^

>>> that name as a preprocessor macro.
> [...]

> But it's a good example of a compiler breaking perfectly standard C++
> code because of macros and their naming.

No, it's a (non-standard) library breaking code. A naming
conflict has nothing to do with standard/non-standard (at
least as long as the name isn't in namespace 'std' or one
of the few macros the std lib defines).

> If it had either not used a macro, or used a name reserved for the
> compiler (ie. starting with an underscore), the problem would not have
> happened.

Yes. (Although I doubt that using a name reserved for the
compiler is a good idea for any library except the std lib.)
Note that it wouldn't have happened either, hadn't you used
a name commonly reserved for macros. I found that, in general,
it's easier to change my habits than those of others. :)

Schobi

0 new messages