www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - yank unary '+'?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Is there any good use of unary +? As an aside, Perl programs do use it 
occasionally for syntactic disambiguation :o).

Andrei
Dec 06 2009
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 Is there any good use of unary +?

In an array of directions I have used -something to mean left and +something to mean right, to keep their symmetry. This is an usage, but not a good enough one. Bye, bearophile
Dec 06 2009
parent BCS <none anon.com> writes:
Hello bearophile,

 Andrei Alexandrescu:
 
 Is there any good use of unary +?
 

+something to mean right, to keep their symmetry. This is an usage, but not a good enough one.

I do that sometimes and I'd like to keep doing it, but I'm not shure how improtant that is.
Dec 06 2009
prev sibling next sibling parent Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use it 
 occasionally for syntactic disambiguation :o).
 
 Andrei

In theory, it could be used in floating point for emphasizing that 0.0 is +0.0 and not -0.0. But that may not be what you mean. Outside of literals, the number of cases I've seen is +(+(+(+(+0))))
Dec 06 2009
prev sibling next sibling parent reply Michiel Helvensteijn <m.helvensteijn.remove gmail.com> writes:
Andrei Alexandrescu wrote:

 Is there any good use of unary +?

I think it's just good symmetry. It makes a programming language just a little bit more elegant. Plus, you keep the 0.01% of programmers that use it happy. What will removing it gain you? -- Michiel Helvensteijn
Dec 06 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Michiel Helvensteijn wrote:
 Andrei Alexandrescu wrote:
 
 Is there any good use of unary +?

I think it's just good symmetry. It makes a programming language just a little bit more elegant. Plus, you keep the 0.01% of programmers that use it happy. What will removing it gain you?

Sancta simplicitas. Andrei
Dec 06 2009
next sibling parent Rainer Deyke <rainerd eldwood.com> writes:
Andrei Alexandrescu wrote:
 Michiel Helvensteijn wrote:
 Andrei Alexandrescu wrote:

 Is there any good use of unary +?

I think it's just good symmetry. It makes a programming language just a little bit more elegant. Plus, you keep the 0.01% of programmers that use it happy. What will removing it gain you?

Sancta simplicitas.

Removing unary '+' does not simplify the language, but complicates it. In math, '+' and '-' are partners. Syntactically, in every context where '-' can be used, '+' can also be used. Keeping this symmetry is the easiest, simplest thing to do. Yes, it's easy to remember that while '-' works both as a binary and an unary operator, '+' is always binary. But should one have to? The omission of unary '+' would be dead weight in the language, reserving a symbol that can never be used for any purpose other than adding unary '+' back in. -- Rainer Deyke - rainerd eldwood.com
Dec 06 2009
prev sibling parent reply Michiel Helvensteijn <m.helvensteijn.remove gmail.com> writes:
Andrei Alexandrescu Wrote:

 What will removing it gain you?

Sancta simplicitas.

Hm.. I don't really buy that argument. I see you and Walter removing/witholding things (incomparability operators, logical operator overloading) from the language, because: "I can't imagine a use for it and removing it makes the language simpler." Meanwhile, you're keeping C syntax for function-pointers around, and I'm missing syntactic sugar for my tribool. The fact that you or I think there isn't a use for a feature, doesn't mean there isn't one. Programmers keep finding new and unintended uses for language features, which is a good thing. And if you want to simplify the language, I wouldn't start with the unary + when you've still got all that C stuff around. -- Michiel Helvensteijn
Dec 07 2009
next sibling parent reply Don <nospam nospam.com> writes:
Michiel Helvensteijn wrote:
 Andrei Alexandrescu Wrote:
 
 What will removing it gain you?


Hm.. I don't really buy that argument. I see you and Walter removing/witholding things (incomparability operators, logical operator overloading) from the language, because: "I can't imagine a use for it and removing it makes the language simpler." Meanwhile, you're keeping C syntax for function-pointers around,

C declaration syntax is on the chopping block. Walter hasn't actually removed any features yet from DMD releases. and I'm missing syntactic sugar for my tribool.
 
 The fact that you or I think there isn't a use for a feature, doesn't mean
there isn't one. Programmers keep finding new and unintended uses for language
features, which is a good thing. And if you want to simplify the language, I
wouldn't start with the unary + when you've still got all that C stuff around.

Yes, but D is getting *really* big. The language complexity is a problem. We need to cut out everything we can possibly can. Unary + is a nice example of something that is almost completely useless.
Dec 07 2009
parent Lukas Pinkowski <Lukas.Pinkowski web.de> writes:
Bill Baxter wrote:
 I say you should completely chop it then.  Leaving it in for literals
 only leaves a mess that's hard to justify.
 I have often written things like
 
   glVertex2f(-boxRadius,-boxRadius);
   glVertex2f(+boxRadius,-boxRadius);
   glVertex2f(+boxRadius,+boxRadius);
   glVertex2f(-boxRadius,+boxRadius);

I'm doing the same thing myself, too. I'm using the unary plus not only for documentation, but also for expressing intention: It symbolizes that I did not forget a minus sign for that specific value. This way a missing unary minus or unary plus makes me suspicious that I have done something wrong in my numerical code.
Dec 08 2009
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Michiel Helvensteijn wrote:
 Andrei Alexandrescu Wrote:
 
 What will removing it gain you?


Hm.. I don't really buy that argument. I see you and Walter removing/witholding things (incomparability operators, logical operator overloading) from the language, because: "I can't imagine a use for it and removing it makes the language simpler."

I disagree, and I think "not imagining a use for X" is a very weak argument for removing X. When a feature is made to walk the plank, we have much better arguments than that. Take typedef: it was ill-defined, defining it properly would have been a major effort, and all benefits could actually be emulated with a struct simpler and cheaper.
 Meanwhile, you're keeping C syntax for function-pointers around, and
 I'm missing syntactic sugar for my tribool.

C syntax for pointers to functions is there for a reason, but we're considering removing it. For one thing, TDPL doesn't mention it.
 The fact that you or I think there isn't a use for a feature, doesn't
 mean there isn't one. Programmers keep finding new and unintended
 uses for language features, which is a good thing. And if you want to
 simplify the language, I wouldn't start with the unary + when you've
 still got all that C stuff around.

I was mostly talking about overloading operator +. Operator + has a long history of being available for overloading in C++, which we can use to our advantage. It has been used to emulate DSLs, but I think we have much better means to define DSLs in D than to redefine all operators to mean some convention-chosen things. Andrei
Dec 07 2009
parent Michiel Helvensteijn <m.helvensteijn.remove gmail.com> writes:
Andrei Alexandrescu wrote:

 "I can't imagine a use for it and removing it makes the language
 simpler."

I disagree

(...)
 I was mostly talking about overloading operator +. Operator + has a long
 history of being available for overloading in C++, which we can use to
 our advantage. It has been used to emulate DSLs, but I think we have
 much better means to define DSLs in D than to redefine all operators to
 mean some convention-chosen things.

Ok, so it's: "I can imagine only one use for it -- but I think we have a better way to do that -- and removing it will make the language simpler." How is that a better reason? I'll ask you again, because I'm really curious. Why would you remove unary plus? * I can't imagine it would make the compiler simpler to any significant degree. If the compiler is well written, unary plus will simply occupy a standard spot in a couple of lists (parser, op-function-names, ...). I doubt removing it would even make a dent in the complexity of the code. * Assuming for the moment that the D language and the D compiler are different things (which they aren't), would it make the language simpler? It would probably only confuse programmers who expect the natural counterpart to unary minus to be present. As for documentation, again, it's a matter of a single spot in a list somewhere. * It doesn't, as far as I can see, take up syntax-space that might be occupied by another more useful feature. * There are even known use-cases. Though for a simple, expected, symmetric feature such as this one, that wouldn't even be a requirement for me. (Note that I'm not especially interested in the unary plus operator per se. I'm just using it as a convenient case-study. I'm more curious about your opinion on why language features should be adopted/tossed/kept.) Best regards, -- Michiel Helvensteijn
Dec 08 2009
prev sibling next sibling parent "Nick Sabalausky" <a a.a> writes:
"retard" <re tard.com.invalid> wrote in message 
news:hfjnfv$1gvr$4 digitalmars.com...
 Mon, 07 Dec 2009 04:06:14 -0500, Michiel Helvensteijn wrote:

 Andrei Alexandrescu Wrote:

 What will removing it gain you?

Sancta simplicitas.

Hm.. I don't really buy that argument. I see you and Walter removing/witholding things (incomparability operators, logical operator overloading) from the language, because: "I can't imagine a use for it and removing it makes the language simpler." Meanwhile, you're keeping C syntax for function-pointers around, and I'm missing syntactic sugar for my tribool.

You probably don't want to anger millions of users coming from the C community, do you?

Nope, we don't. So let's just define D == C, and keep all of them happy.
Dec 07 2009
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
retard wrote:
 Mon, 07 Dec 2009 04:06:14 -0500, Michiel Helvensteijn wrote:
 
 Andrei Alexandrescu Wrote:

 What will removing it gain you?


I see you and Walter removing/witholding things (incomparability operators, logical operator overloading) from the language, because: "I can't imagine a use for it and removing it makes the language simpler." Meanwhile, you're keeping C syntax for function-pointers around, and I'm missing syntactic sugar for my tribool.

You probably don't want to anger millions of users coming from the C community, do you?

While we're at it, lets avoid angering the millions of users coming from the Java community. And the Python community. And the PHP community. And the...
Dec 07 2009
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
retard wrote:
 Tue, 08 Dec 2009 12:08:43 +0900, Mike Parker wrote:
 
 retard wrote:
 Mon, 07 Dec 2009 04:06:14 -0500, Michiel Helvensteijn wrote:

 Andrei Alexandrescu Wrote:

 What will removing it gain you?


I see you and Walter removing/witholding things (incomparability operators, logical operator overloading) from the language, because: "I can't imagine a use for it and removing it makes the language simpler." Meanwhile, you're keeping C syntax for function-pointers around, and I'm missing syntactic sugar for my tribool.

community, do you?

the Java community. And the Python community. And the PHP community. And the...

That's just silly. D has its C roots. Python and PHP are rivaling amateur languages. A scripting language user wouldn't use D, but all C users should switch to D because the execution model is similar and C is basically a subset of D.

My point is that there's no reason to cater to any one particular group of programmers. We all have to learn new syntax when moving between languages, and we all have different backgrounds. There are numerous members of the D community with plenty of Java, but little or no C, experience. C syntax doesn't help them one bit. D is *not* C, no matter its roots. And D2 is farther from C than D1. There's no reason to keep around an alternative C syntax for a particular feature (like function pointers) when everyone recommends the /D style/ syntax be preferred. I think C programmers are smart enough to figure things out without the language keeping around old syntax. If they want C, they can stick with C.
Dec 08 2009
parent klickverbot <klickverbot gmail.com> writes:
Mike Parker wrote:
 […] I think C programmers are smart enough to figure things out without
 the language keeping around old syntax. If they want C, they can stick
 with C.

I think so too – the »new«, D function pointer syntax is much more readable and intuitive than the C one which is widely regarded as being quite messy, especially in more complex declarations. Please do not even start to think about removing elements with valid use- cases (even if there were hardly any) in the name of reducing language complexity (note aside: I do not really see how one more unary operator could really make a difference here) before removing redundancies…
Dec 08 2009
prev sibling parent KennyTM~ <kennytm gmail.com> writes:
On Dec 8, 09 19:11, retard wrote:
 Tue, 08 Dec 2009 12:08:43 +0900, Mike Parker wrote:

 retard wrote:
 Mon, 07 Dec 2009 04:06:14 -0500, Michiel Helvensteijn wrote:

 Andrei Alexandrescu Wrote:

 What will removing it gain you?


I see you and Walter removing/witholding things (incomparability operators, logical operator overloading) from the language, because: "I can't imagine a use for it and removing it makes the language simpler." Meanwhile, you're keeping C syntax for function-pointers around, and I'm missing syntactic sugar for my tribool.

You probably don't want to anger millions of users coming from the C community, do you?

While we're at it, lets avoid angering the millions of users coming from the Java community. And the Python community. And the PHP community. And the...

That's just silly. D has its C roots. Python and PHP are rivaling amateur languages. A scripting language user wouldn't use D, but all C users should switch to D because the execution model is similar and C is basically a subset of D.

All C users should switch to D when D can be used without the GC with little effort.
Dec 08 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Mon, Dec 7, 2009 at 4:00 AM, Don <nospam nospam.com> wrote:
 Michiel Helvensteijn wrote:
 Andrei Alexandrescu Wrote:

 What will removing it gain you?

Sancta simplicitas.

Hm.. I don't really buy that argument. I see you and Walter removing/witholding things (incomparability operators, logical operator overloading) from the language, because: "I can't imagine a use for it and removing it makes the language simpler." Meanwhile, you're keeping C syntax for function-pointers around,

C declaration syntax is on the chopping block. Walter hasn't actually removed any features yet from DMD releases. and I'm missing syntactic sugar for my tribool.
 The fact that you or I think there isn't a use for a feature, doesn't mean
 there isn't one. Programmers keep finding new and unintended uses for
 language features, which is a good thing. And if you want to simplify the
 language, I wouldn't start with the unary + when you've still got all that C
 stuff around.

Yes, but D is getting *really* big. The language complexity is a problem. We need to cut out everything we can possibly can. Unary + is a nice example of something that is almost completely useless.

I say you should completely chop it then. Leaving it in for literals only leaves a mess that's hard to justify. I have often written things like glVertex2f(-boxRadius,-boxRadius); glVertex2f(+boxRadius,-boxRadius); glVertex2f(+boxRadius,+boxRadius); glVertex2f(-boxRadius,+boxRadius); And often code like that starts out as something with constants: glVertex2f(-1,-1); glVertex2f(+1,-1); glVertex2f(+1,+1); glVertex2f(-1,+1); I would find it quite confusing and annoying if the latter worked but the former did not. But I could live with it if neither worked. --bb
Dec 07 2009
prev sibling next sibling parent retard <re tard.com.invalid> writes:
Mon, 07 Dec 2009 04:06:14 -0500, Michiel Helvensteijn wrote:

 Andrei Alexandrescu Wrote:
 
 What will removing it gain you?

Sancta simplicitas.

Hm.. I don't really buy that argument. I see you and Walter removing/witholding things (incomparability operators, logical operator overloading) from the language, because: "I can't imagine a use for it and removing it makes the language simpler." Meanwhile, you're keeping C syntax for function-pointers around, and I'm missing syntactic sugar for my tribool.

You probably don't want to anger millions of users coming from the C community, do you?
Dec 07 2009
prev sibling next sibling parent retard <re tard.com.invalid> writes:
Tue, 08 Dec 2009 12:08:43 +0900, Mike Parker wrote:

 retard wrote:
 Mon, 07 Dec 2009 04:06:14 -0500, Michiel Helvensteijn wrote:
 
 Andrei Alexandrescu Wrote:

 What will removing it gain you?


I see you and Walter removing/witholding things (incomparability operators, logical operator overloading) from the language, because: "I can't imagine a use for it and removing it makes the language simpler." Meanwhile, you're keeping C syntax for function-pointers around, and I'm missing syntactic sugar for my tribool.

You probably don't want to anger millions of users coming from the C community, do you?

While we're at it, lets avoid angering the millions of users coming from the Java community. And the Python community. And the PHP community. And the...

That's just silly. D has its C roots. Python and PHP are rivaling amateur languages. A scripting language user wouldn't use D, but all C users should switch to D because the execution model is similar and C is basically a subset of D.
Dec 08 2009
prev sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Tue, Dec 8, 2009 at 2:28 PM, Lukas Pinkowski <Lukas.Pinkowski web.de> wr=
ote:
 Bill Baxter wrote:
 I say you should completely chop it then. =A0Leaving it in for literals
 only leaves a mess that's hard to justify.
 I have often written things like

 =A0 glVertex2f(-boxRadius,-boxRadius);
 =A0 glVertex2f(+boxRadius,-boxRadius);
 =A0 glVertex2f(+boxRadius,+boxRadius);
 =A0 glVertex2f(-boxRadius,+boxRadius);

I'm doing the same thing myself, too. I'm using the unary plus not only for documentation, but also for express=

 intention: It symbolizes that I did not forget a minus sign for that
 specific value. This way a missing unary minus or unary plus makes me
 suspicious that I have done something wrong in my numerical code.

Well, you can use a leading space for that purpose too, with just slightly more ambiguity of intent. --bb
Dec 08 2009
prev sibling next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Dec 7, 09 00:23, Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use it
 occasionally for syntactic disambiguation :o).

 Andrei

Yes, when you want to port the Boost Spirit parser :o) (OK that's an abuse.) Well the unary + can help to emphasize "it's a positive number", and 1.0e+10 is already a form of "unary +" (not the operator). Removing the unary + doesn't lose much, but it doesn't gain much either, and with it already present in all other languages, I don't see a good reason to change it.
Dec 06 2009
parent reply Don <nospam nospam.com> writes:
KennyTM~ wrote:
 On Dec 7, 09 00:23, Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use it
 occasionally for syntactic disambiguation :o).

 Andrei

Yes, when you want to port the Boost Spirit parser :o) (OK that's an abuse.) Well the unary + can help to emphasize "it's a positive number", and 1.0e+10 is already a form of "unary +" (not the operator). Removing the unary + doesn't lose much, but it doesn't gain much either, and with it already present in all other languages, I don't see a good reason to change it.

I think + should be added to the syntax for numeric literals, and in all other cases unary + should be dropped. Ie, x = +0.78; should remain legal. But y = +x; should not. And likewise, x = +(+0.78); should be illegal. Overloading + is odd, too. Currently: +x; creates a "has no effect" error if x is a built-in type. But if x has an overloaded unary +, it might have side-effects. So it useful ONLY for operator abuse!
Dec 06 2009
parent reply KennyTM~ <kennytm gmail.com> writes:
On Dec 7, 09 04:30, Don wrote:
 KennyTM~ wrote:
 On Dec 7, 09 00:23, Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use it
 occasionally for syntactic disambiguation :o).

 Andrei

Yes, when you want to port the Boost Spirit parser :o) (OK that's an abuse.) Well the unary + can help to emphasize "it's a positive number", and 1.0e+10 is already a form of "unary +" (not the operator). Removing the unary + doesn't lose much, but it doesn't gain much either, and with it already present in all other languages, I don't see a good reason to change it.

I think + should be added to the syntax for numeric literals, and in all other cases unary + should be dropped. Ie, x = +0.78; should remain legal. But y = +x; should not. And likewise, x = +(+0.78); should be illegal. Overloading + is odd, too. Currently: +x; creates a "has no effect" error if x is a built-in type. But if x has an overloaded unary +, it might have side-effects. So it useful ONLY for operator abuse!

import std.math; auto theta1 = +PI/6; auto theta2 = -PI/8;
Dec 06 2009
parent Don <nospam nospam.com> writes:
KennyTM~ wrote:
 On Dec 7, 09 04:30, Don wrote:
 KennyTM~ wrote:
 On Dec 7, 09 00:23, Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use it
 occasionally for syntactic disambiguation :o).

 Andrei

Yes, when you want to port the Boost Spirit parser :o) (OK that's an abuse.) Well the unary + can help to emphasize "it's a positive number", and 1.0e+10 is already a form of "unary +" (not the operator). Removing the unary + doesn't lose much, but it doesn't gain much either, and with it already present in all other languages, I don't see a good reason to change it.

I think + should be added to the syntax for numeric literals, and in all other cases unary + should be dropped. Ie, x = +0.78; should remain legal. But y = +x; should not. And likewise, x = +(+0.78); should be illegal. Overloading + is odd, too. Currently: +x; creates a "has no effect" error if x is a built-in type. But if x has an overloaded unary +, it might have side-effects. So it useful ONLY for operator abuse!

import std.math; auto theta1 = +PI/6; auto theta2 = -PI/8;

Good one.
Dec 06 2009
prev sibling next sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use it 
 occasionally for syntactic disambiguation :o).

http://stackoverflow.com/questions/727516/what-does-the-unary-plus-operator-do
Dec 06 2009
prev sibling next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use it 
 occasionally for syntactic disambiguation :o).

An internet search reveals: 1. symmetry 2. compatibility with C and many other languages that use it 3. used with operator overloading to convert a user defined type to its preferred arithmetic representation (a cast can't know what the 'preferred' type is) 4. to create DSL languages, like Spirit, as Kenny points out 5. to coerce default integral promotion rules (again, cast(int) won't always produce the same result) 6. to visually emphasize that a literal is positive I say leave it in.
Dec 06 2009
next sibling parent reply Don <nospam nospam.com> writes:
Walter Bright wrote:
 Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use it 
 occasionally for syntactic disambiguation :o).

An internet search reveals: 1. symmetry

I think it makes sense for literals. Not for anything else though. Since + is a no-op, it just causes confusion.
 2. compatibility with C and many other languages that use it

That matters only if those other languages actually have a use for it.
 3. used with operator overloading to convert a user defined type to its 
 preferred arithmetic representation (a cast can't know what the 
 'preferred' type is)
 5. to coerce default integral promotion rules (again, cast(int) won't
 always produce the same result)

This one is interesting, and might be the strongest argument, but I don't understand it. An example would be interesting.
 4. to create DSL languages, like Spirit, as Kenny points out

If we are to have a feature specifically for DSL languages, it's not hard to come up with something more useful... (From memory, Spirit uses it as the nearest available approximation to postfix +).
 6. to visually emphasize that a literal is positive

general, I don't think. Just for numeric literals.
Dec 06 2009
parent Walter Bright <newshound1 digitalmars.com> writes:
Don wrote:
 Walter Bright wrote:
 3. used with operator overloading to convert a user defined type to 
 its preferred arithmetic representation (a cast can't know what the 
 'preferred' type is)

> always produce the same result) This one is interesting, and might be the strongest argument, but I don't understand it. An example would be interesting.

Integral promotion rules: byte b; +b => int dchar dc; +dc => uint long l; +l => long cast(int)l => Oops! lost some bits user defined type: struct S { long opCast() { ... } S opAdd(ref S) { ... } } S s; +s => long result s + s => S result s + +s => long result s + cast(int)s => Oops! lost some bits!
Dec 06 2009
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Walter Bright wrote:
 Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use it 
 occasionally for syntactic disambiguation :o).

An internet search reveals: 1. symmetry 2. compatibility with C and many other languages that use it 3. used with operator overloading to convert a user defined type to its preferred arithmetic representation (a cast can't know what the 'preferred' type is) 4. to create DSL languages, like Spirit, as Kenny points out 5. to coerce default integral promotion rules (again, cast(int) won't always produce the same result) 6. to visually emphasize that a literal is positive I say leave it in.

I am completely underwhelmed by 1-6 and have strong arguments against each, but "frankly, my dear" I have bigger problems than that. I have exactly zero valid reasons I could mention in TDPL, and that's my litmus test. I find the operator utterly useless. If '+' stays in, then call it horsetrading but the occasionally useful '^^=' must also be in. Andrei
Dec 06 2009
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Dec 7, 09 05:12, Andrei Alexandrescu wrote:
 I am completely underwhelmed by 1-6 and have strong arguments against
 each, but "frankly, my dear" I have bigger problems than that. I have
 exactly zero valid reasons I could mention in TDPL, and that's my litmus
 test. I find the operator utterly useless. If '+' stays in, then call it
 horsetrading but the occasionally useful '^^=' must also be in.

 Andrei

There would be zero reason to explain 1.0 vs 1.00, 1.0e2 vs 1.0e+2, and 0xabc vs 0xABC vs 0Xabc vs 0XABC too. And I thought there isn't ^^= yet just because Don's patch was only a proof-of-concept thing. (Currently 3*4^^2 doesn't event produce the expected result.) ^^= will be in, but that's irrelevant.
Dec 06 2009
parent reply Don <nospam nospam.com> writes:
KennyTM~ wrote:
 On Dec 7, 09 05:12, Andrei Alexandrescu wrote:
 I am completely underwhelmed by 1-6 and have strong arguments against
 each, but "frankly, my dear" I have bigger problems than that. I have
 exactly zero valid reasons I could mention in TDPL, and that's my litmus
 test. I find the operator utterly useless. If '+' stays in, then call it
 horsetrading but the occasionally useful '^^=' must also be in.

 Andrei

There would be zero reason to explain 1.0 vs 1.00, 1.0e2 vs 1.0e+2, and 0xabc vs 0xABC vs 0Xabc vs 0XABC too. And I thought there isn't ^^= yet just because Don's patch was only a proof-of-concept thing. (Currently 3*4^^2 doesn't event produce the expected result.) ^^= will be in, but that's irrelevant.

Not so. My patch included ^^=, but Walter stripped it out because he wasn't convinced there were enough use cases for it.
Dec 06 2009
next sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Don wrote:
 Not so. My patch included ^^=, but Walter stripped it out because he 
 wasn't convinced there were enough use cases for it.

Andrei's definitely in your camp on that one <g>.
Dec 06 2009
prev sibling parent KennyTM~ <kennytm gmail.com> writes:
On Dec 7, 09 13:11, Don wrote:
 KennyTM~ wrote:
 On Dec 7, 09 05:12, Andrei Alexandrescu wrote:
 I am completely underwhelmed by 1-6 and have strong arguments against
 each, but "frankly, my dear" I have bigger problems than that. I have
 exactly zero valid reasons I could mention in TDPL, and that's my litmus
 test. I find the operator utterly useless. If '+' stays in, then call it
 horsetrading but the occasionally useful '^^=' must also be in.

 Andrei

There would be zero reason to explain 1.0 vs 1.00, 1.0e2 vs 1.0e+2, and 0xabc vs 0xABC vs 0Xabc vs 0XABC too. And I thought there isn't ^^= yet just because Don's patch was only a proof-of-concept thing. (Currently 3*4^^2 doesn't event produce the expected result.) ^^= will be in, but that's irrelevant.

Not so. My patch included ^^=, but Walter stripped it out because he wasn't convinced there were enough use cases for it.

Ah, I see.
Dec 07 2009
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 Walter Bright wrote:
 Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use 
 it occasionally for syntactic disambiguation :o).

An internet search reveals: 1. symmetry 2. compatibility with C and many other languages that use it 3. used with operator overloading to convert a user defined type to its preferred arithmetic representation (a cast can't know what the 'preferred' type is) 4. to create DSL languages, like Spirit, as Kenny points out 5. to coerce default integral promotion rules (again, cast(int) won't always produce the same result) 6. to visually emphasize that a literal is positive I say leave it in.

I am completely underwhelmed by 1-6 and have strong arguments against each, but "frankly, my dear" I have bigger problems than that. I have exactly zero valid reasons I could mention in TDPL, and that's my litmus test. I find the operator utterly useless. If '+' stays in, then call it horsetrading but the occasionally useful '^^=' must also be in.

Think of it like the "bool" operator overload. bool gives a direct way for user defined times to be tested for if statements, etc. Similarly, U+ gives a direct way for user defined types to be converted to their most desired arithmetic type.
Dec 06 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Walter Bright wrote:
 Andrei Alexandrescu wrote:
 Walter Bright wrote:
 Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use 
 it occasionally for syntactic disambiguation :o).

An internet search reveals: 1. symmetry 2. compatibility with C and many other languages that use it 3. used with operator overloading to convert a user defined type to its preferred arithmetic representation (a cast can't know what the 'preferred' type is) 4. to create DSL languages, like Spirit, as Kenny points out 5. to coerce default integral promotion rules (again, cast(int) won't always produce the same result) 6. to visually emphasize that a literal is positive I say leave it in.

I am completely underwhelmed by 1-6 and have strong arguments against each, but "frankly, my dear" I have bigger problems than that. I have exactly zero valid reasons I could mention in TDPL, and that's my litmus test. I find the operator utterly useless. If '+' stays in, then call it horsetrading but the occasionally useful '^^=' must also be in.

Think of it like the "bool" operator overload. bool gives a direct way for user defined times to be tested for if statements, etc.

If I think of it that way, that doesn't look too good. The bool operator overload has been an unqualified and admitted failure for C++. The hacks used to avoid that failure are very ingenious; none was within the realm of what the language had planned or intended.
 Similarly, 
 U+ gives a direct way for user defined types to be converted to their 
 most desired arithmetic type.

Code that uses +a to convert a to another type? I'd consider that worse than a hack and worse than incompetent - it's downright malicious. Andrei
Dec 06 2009
parent Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 Walter Bright wrote:
 Andrei Alexandrescu wrote:
 Walter Bright wrote:
 Andrei Alexandrescu wrote:
 Is there any good use of unary +? As an aside, Perl programs do use 
 it occasionally for syntactic disambiguation :o).

An internet search reveals: 1. symmetry 2. compatibility with C and many other languages that use it 3. used with operator overloading to convert a user defined type to its preferred arithmetic representation (a cast can't know what the 'preferred' type is) 4. to create DSL languages, like Spirit, as Kenny points out 5. to coerce default integral promotion rules (again, cast(int) won't always produce the same result) 6. to visually emphasize that a literal is positive I say leave it in.

I am completely underwhelmed by 1-6 and have strong arguments against each, but "frankly, my dear" I have bigger problems than that. I have exactly zero valid reasons I could mention in TDPL, and that's my litmus test. I find the operator utterly useless. If '+' stays in, then call it horsetrading but the occasionally useful '^^=' must also be in.

Think of it like the "bool" operator overload. bool gives a direct way for user defined times to be tested for if statements, etc.

If I think of it that way, that doesn't look too good. The bool operator overload has been an unqualified and admitted failure for C++. The hacks used to avoid that failure are very ingenious; none was within the realm of what the language had planned or intended.
 Similarly, U+ gives a direct way for user defined types to be 
 converted to their most desired arithmetic type.

Code that uses +a to convert a to another type? I'd consider that worse than a hack and worse than incompetent - it's downright malicious. Andrei

And if Andrei has never heard of it, we can be pretty sure that very few programmmers would understand code that uses it. It's really looking as though U+ is only for literals and for operator abuse.
Dec 06 2009
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:

 Think of it like the "bool" operator overload. bool gives a direct way 
 for user defined times to be tested for if statements, etc. Similarly, 
 U+ gives a direct way for user defined types to be converted to their 
 most desired arithmetic type.

I'd like opBool in D, for example to implement multiprecision numbers that can be used as integers in: if (somenumber) {... Or when I want to give Python-like semantics to my collections, so they can be false when empty (I don't know if this is a good idea, I think it's handy). I agree with Andrei that type conversions done with + are cryptic, I am not a C expert but I am using it for some time and I have never seen + used that way. I'd like to keep writing +5.5, with numbers (and maybe with user-defined numbers too). Unary pos operator overload is available even in Python, it's named __pos__, an answer about it, that shows two bad usages of __pos__: http://groups.google.com/group/comp.lang.python/msg/07d6fb1e2c7a4f42 This is ugly, I didn't know about this:
 import decimal
 x = decimal.Decimal("-0.0")
 x



 +x



 x = decimal.Decimal("-2.0")
 x



 +x



Keeping opPos allows to write +x where x is a user-defined number (and x must not change sign as in the Python Decimal zero, I don't understand that design decision), so even if it's not so useful I think it's better to keep it in D. Bye, bearophile
Dec 06 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 Walter Bright:
 
 Think of it like the "bool" operator overload. bool gives a direct
 way for user defined times to be tested for if statements, etc.
 Similarly, U+ gives a direct way for user defined types to be
 converted to their most desired arithmetic type.

I'd like opBool in D, for example to implement multiprecision numbers that can be used as integers in: if (somenumber) {...

Unfortunately experience with C++ has shown that things look simpler than they are. If opBool is an implicit conversion to bool, then all sorts of weird expressions are allowed. That's why conversion to bool is flat out unrecommended in C++. Instead, various libraries found alternate ways to allow testing with if without compromising things too much. Loki uses conversion to an opaque pointer type. Boost uses conversion to a pointer to member. The standard itself uses, I think, conversion of iostreams to void*. In my draft spec of operators I have the test: a ? <expr1> : <expr2> where a is of user-defined type, rewritten as !!a ? <expr1> : <expr2> and the test: if (a) <stmt> rewritten as if (!!a) <stmt> This leads to perfect correspondence with the behavior of arrays, pointers, class references, and integrals: you can't convert any of those to bool but you can test them with if or the ternary operator. Rewriting to !!a achieves exactly the same thing. So user-defined types may define ! to return bool with the usual semantics, and the compiler nicely takes care of the rest. Andrei
Dec 06 2009
next sibling parent Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 bearophile wrote:
 Walter Bright:

 Think of it like the "bool" operator overload. bool gives a direct
 way for user defined times to be tested for if statements, etc.
 Similarly, U+ gives a direct way for user defined types to be
 converted to their most desired arithmetic type.

I'd like opBool in D, for example to implement multiprecision numbers that can be used as integers in: if (somenumber) {...

Unfortunately experience with C++ has shown that things look simpler than they are. If opBool is an implicit conversion to bool, then all sorts of weird expressions are allowed. That's why conversion to bool is flat out unrecommended in C++. Instead, various libraries found alternate ways to allow testing with if without compromising things too much. Loki uses conversion to an opaque pointer type. Boost uses conversion to a pointer to member. The standard itself uses, I think, conversion of iostreams to void*. In my draft spec of operators I have the test: a ? <expr1> : <expr2> where a is of user-defined type, rewritten as !!a ? <expr1> : <expr2> and the test: if (a) <stmt> rewritten as if (!!a) <stmt> This leads to perfect correspondence with the behavior of arrays, pointers, class references, and integrals: you can't convert any of those to bool but you can test them with if or the ternary operator. Rewriting to !!a achieves exactly the same thing. So user-defined types may define ! to return bool with the usual semantics, and the compiler nicely takes care of the rest.

That's great. Simple and effective.
Dec 06 2009
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Brad Roberts wrote:
 Andrei Alexandrescu wrote:
 bearophile wrote:
 Walter Bright:

 Think of it like the "bool" operator overload. bool gives a direct
 way for user defined times to be tested for if statements, etc.
 Similarly, U+ gives a direct way for user defined types to be
 converted to their most desired arithmetic type.

that can be used as integers in: if (somenumber) {...

than they are. If opBool is an implicit conversion to bool, then all sorts of weird expressions are allowed. That's why conversion to bool is flat out unrecommended in C++. Instead, various libraries found alternate ways to allow testing with if without compromising things too much. Loki uses conversion to an opaque pointer type. Boost uses conversion to a pointer to member. The standard itself uses, I think, conversion of iostreams to void*.

Isn't one of the key problems that bool conversion introduces is the follow on conversion to integral types? If implicit bool -> integral conversion wasn't allowed, T -> bool conversion would be less problematic, no?

That is correct, and "less problematic" is exactly how I'd put it. There's a problem left. Assuming bool -> numeric conversion is impossible, there's still a problem. First, consider a class, array, pointer, or number x. This compiles: if (x) stmt This also compiles: x ? expr1 : expr2 But this doesn't compile: bool b = x; Now consider we design tests to use opBool that effects implicit conversion to bool. Then, for a user-defined type x, all of the three samples above compile. Which means we have introduced a gratuitous incompatibility between user-defined and built-in types. Then consider another problem: a type that allows if (x) also wants to allow if (!x). It's the natural thing to want. Then we need to define opBool and opUnary!"!" to work in concert, redundantly. Bleh. I'm not sure how big problems these are. I think they are threatening enough that style manuals and coding standards mention both. Using double negation !!x throughout, there are only advantages and no disadvantage. I hit that design with Pacquiao punches over the past week or so, and couldn't find any shortcoming. It's consistent across positive and negated uses, easy to understand, easy to define, consistent with built-in types, and Walter likes it. Andrei
Dec 06 2009
next sibling parent reply Johan Granberg <lijat.meREM OVEgmail.com> writes:
Andrei Alexandrescu wrote:

 Brad Roberts wrote:
 Andrei Alexandrescu wrote:
 bearophile wrote:
 Walter Bright:

 Think of it like the "bool" operator overload. bool gives a direct
 way for user defined times to be tested for if statements, etc.
 Similarly, U+ gives a direct way for user defined types to be
 converted to their most desired arithmetic type.

that can be used as integers in: if (somenumber) {...

than they are. If opBool is an implicit conversion to bool, then all sorts of weird expressions are allowed. That's why conversion to bool is flat out unrecommended in C++. Instead, various libraries found alternate ways to allow testing with if without compromising things too much. Loki uses conversion to an opaque pointer type. Boost uses conversion to a pointer to member. The standard itself uses, I think, conversion of iostreams to void*.

Isn't one of the key problems that bool conversion introduces is the follow on conversion to integral types? If implicit bool -> integral conversion wasn't allowed, T -> bool conversion would be less problematic, no?

That is correct, and "less problematic" is exactly how I'd put it. There's a problem left. Assuming bool -> numeric conversion is impossible, there's still a problem. First, consider a class, array, pointer, or number x. This compiles: if (x) stmt This also compiles: x ? expr1 : expr2 But this doesn't compile: bool b = x; Now consider we design tests to use opBool that effects implicit conversion to bool. Then, for a user-defined type x, all of the three samples above compile. Which means we have introduced a gratuitous incompatibility between user-defined and built-in types. Then consider another problem: a type that allows if (x) also wants to allow if (!x). It's the natural thing to want. Then we need to define opBool and opUnary!"!" to work in concert, redundantly. Bleh. I'm not sure how big problems these are. I think they are threatening enough that style manuals and coding standards mention both. Using double negation !!x throughout, there are only advantages and no disadvantage. I hit that design with Pacquiao punches over the past week or so, and couldn't find any shortcoming. It's consistent across positive and negated uses, easy to understand, easy to define, consistent with built-in types, and Walter likes it. Andrei

Couldn't we solv that by instead of introducing opBool, introduce opTrue. Which is defined as yielding a type testable for truth and is only invoked in the same situations that class references are used as thruth values? To me this looks like a simple solution.
Dec 06 2009
parent Johan Granberg <lijat.meREM OVEgmail.com> writes:
Denis Koroskin wrote:

 On Mon, 07 Dec 2009 10:36:16 +0300, Johan Granberg
 <lijat.meREM ovegmail.com> wrote:
 
 Andrei Alexandrescu wrote:

 Brad Roberts wrote:
 Andrei Alexandrescu wrote:
 bearophile wrote:
 Walter Bright:

 Think of it like the "bool" operator overload. bool gives a direct
 way for user defined times to be tested for if statements, etc.
 Similarly, U+ gives a direct way for user defined types to be
 converted to their most desired arithmetic type.

that can be used as integers in: if (somenumber) {...

than they are. If opBool is an implicit conversion to bool, then all sorts of weird expressions are allowed. That's why conversion to bool is flat out unrecommended in C++. Instead, various libraries found alternate ways to allow testing with if without compromising things too much. Loki uses conversion to an opaque pointer type. Boost uses conversion to a pointer to member. The standard itself uses, I think, conversion of iostreams to void*.

Isn't one of the key problems that bool conversion introduces is the follow on conversion to integral types? If implicit bool -> integral conversion wasn't allowed, T -> bool conversion would be less problematic, no?

That is correct, and "less problematic" is exactly how I'd put it. There's a problem left. Assuming bool -> numeric conversion is impossible, there's still a problem. First, consider a class, array, pointer, or number x. This compiles: if (x) stmt This also compiles: x ? expr1 : expr2 But this doesn't compile: bool b = x; Now consider we design tests to use opBool that effects implicit conversion to bool. Then, for a user-defined type x, all of the three samples above compile. Which means we have introduced a gratuitous incompatibility between user-defined and built-in types. Then consider another problem: a type that allows if (x) also wants to allow if (!x). It's the natural thing to want. Then we need to define opBool and opUnary!"!" to work in concert, redundantly. Bleh. I'm not sure how big problems these are. I think they are threatening enough that style manuals and coding standards mention both. Using double negation !!x throughout, there are only advantages and no disadvantage. I hit that design with Pacquiao punches over the past week or so, and couldn't find any shortcoming. It's consistent across positive and negated uses, easy to understand, easy to define, consistent with built-in types, and Walter likes it. Andrei

Couldn't we solv that by instead of introducing opBool, introduce opTrue. Which is defined as yielding a type testable for truth and is only invoked in the same situations that class references are used as thruth values? To me this looks like a simple solution.

OpTrue also implies opFalse, which is redundant.

It was the semantics I was after I just choose a different name to keep the concepts appart.
Dec 07 2009
prev sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-12-07 01:29:14 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 Using double negation !!x throughout, there are only advantages and no 
 disadvantage. I hit that design with Pacquiao punches over the past 
 week or so, and couldn't find any shortcoming. It's consistent across 
 positive and negated uses, easy to understand, easy to define, 
 consistent with built-in types, and Walter likes it.

I'm not sure that's a great idea. What if you define your own FuzzyBool type (containing some sort of probability) and FuzzyBool.opUnary!("!") returns an inverted FuzzyBool (with 1 - original probability) instead of a regular bool, you'd have an infinite loop trying to evaluate !!myBoolValue. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 07 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Michel Fortin wrote:
 On 2009-12-07 01:29:14 -0500, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:
 
 Using double negation !!x throughout, there are only advantages and no 
 disadvantage. I hit that design with Pacquiao punches over the past 
 week or so, and couldn't find any shortcoming. It's consistent across 
 positive and negated uses, easy to understand, easy to define, 
 consistent with built-in types, and Walter likes it.

I'm not sure that's a great idea. What if you define your own FuzzyBool type (containing some sort of probability) and FuzzyBool.opUnary!("!") returns an inverted FuzzyBool (with 1 - original probability) instead of a regular bool, you'd have an infinite loop trying to evaluate !!myBoolValue.

Yeah, I thought about that liability and decided to discount it as a design mistake of the user. If a type decides to return non-bool from "!", they are bound to unpleasantly surprise its user in more ways than one. You can define a negate for FuzzyBool - just don't dress it as the "!" operator. Andrei
Dec 07 2009
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-12-07 23:52:04 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 Michel Fortin wrote:
 On 2009-12-07 01:29:14 -0500, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:
 
 Using double negation !!x throughout, there are only advantages and no 
 disadvantage. I hit that design with Pacquiao punches over the past 
 week or so, and couldn't find any shortcoming. It's consistent across 
 positive and negated uses, easy to understand, easy to define, 
 consistent with built-in types, and Walter likes it.

I'm not sure that's a great idea. What if you define your own FuzzyBool type (containing some sort of probability) and FuzzyBool.opUnary!("!") returns an inverted FuzzyBool (with 1 - original probability) instead of a regular bool, you'd have an infinite loop trying to evaluate !!myBoolValue.

Yeah, I thought about that liability and decided to discount it as a design mistake of the user. If a type decides to return non-bool from "!", they are bound to unpleasantly surprise its user in more ways than one. You can define a negate for FuzzyBool - just don't dress it as the "!" operator.

To me, its using "!" to transform something to a bool that looks like a hack. Surely there's a more explicit and intuitive way to define it that doesn't tie it to a specific operator. opTest perhaps? And if you think "!" should always return a bool, then it should just not be overridable and should be defined as returning the negation of opTest (or whatever the name). I don't feel restricting unary "!" to return a bool is sound when all other unary ops can be defined to return anything. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 08 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Michel Fortin wrote:
 On 2009-12-07 23:52:04 -0500, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:
 
 Michel Fortin wrote:
 On 2009-12-07 01:29:14 -0500, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 Using double negation !!x throughout, there are only advantages and 
 no disadvantage. I hit that design with Pacquiao punches over the 
 past week or so, and couldn't find any shortcoming. It's consistent 
 across positive and negated uses, easy to understand, easy to 
 define, consistent with built-in types, and Walter likes it.

I'm not sure that's a great idea. What if you define your own FuzzyBool type (containing some sort of probability) and FuzzyBool.opUnary!("!") returns an inverted FuzzyBool (with 1 - original probability) instead of a regular bool, you'd have an infinite loop trying to evaluate !!myBoolValue.

Yeah, I thought about that liability and decided to discount it as a design mistake of the user. If a type decides to return non-bool from "!", they are bound to unpleasantly surprise its user in more ways than one. You can define a negate for FuzzyBool - just don't dress it as the "!" operator.

To me, its using "!" to transform something to a bool that looks like a hack. Surely there's a more explicit and intuitive way to define it that doesn't tie it to a specific operator.

Actually this is quite what happens with built-in types. A common misconception (I'm sure not yours) is that "if" works with Booleans. In fact it works with Booleans, numbers, pointers, arrays, and class references. In a very palpable way "if" is special-cased for each of these. Then, the common misconception goes, all of those have a sort of conversion to Boolean that "if" taps into. Not quite, because if you try to assign a bool from an array or even an integer, it won't work. What does work is operator "!". Operator "!" accept _all_ of Booleans, numbers, pointers, arrays, and class references - i.e., exactly the set of "if"-testable entities. And it uniformly yields bool. So it is an excellent device for hooking user-defined types into "if". I'd say it is not a hack at all, although it may look so at first sight. It really holds water.
 opTest perhaps?

opTest was on the bench for a short while, but Walter threw his hands. "How many operators are you going to define?" And he's right - I'd do with fewer rather than more redundant operators. We (will) have a method for defining unary operators. I don't see why make an exception of "!", or, worse, allow both operator "!" and opTest.
 And if you think "!" should always return a bool, then it should just 
 not be overridable and should be defined as returning the negation of 
 opTest (or whatever the name). I don't feel restricting unary "!" to 
 return a bool is sound when all other unary ops can be defined to return 
 anything.

It's possible to require opTest and then say that "!a" is always rewritten into !a.opTest. But then consider this fragment: "For all unary operators except "!", the expression <op> a is rewritten as a.opUnary!"<op>"() However, !a is rewritten as !a.opTest()" Would you like to see something like that in TDPL? Andrei
Dec 08 2009
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 07 Dec 2009 10:36:16 +0300, Johan Granberg  
<lijat.meREM ovegmail.com> wrote:

 Andrei Alexandrescu wrote:

 Brad Roberts wrote:
 Andrei Alexandrescu wrote:
 bearophile wrote:
 Walter Bright:

 Think of it like the "bool" operator overload. bool gives a direct
 way for user defined times to be tested for if statements, etc.
 Similarly, U+ gives a direct way for user defined types to be
 converted to their most desired arithmetic type.

that can be used as integers in: if (somenumber) {...

than they are. If opBool is an implicit conversion to bool, then all sorts of weird expressions are allowed. That's why conversion to bool is flat out unrecommended in C++. Instead, various libraries found alternate ways to allow testing with if without compromising things too much. Loki uses conversion to an opaque pointer type. Boost uses conversion to a pointer to member. The standard itself uses, I think, conversion of iostreams to void*.

Isn't one of the key problems that bool conversion introduces is the follow on conversion to integral types? If implicit bool -> integral conversion wasn't allowed, T -> bool conversion would be less problematic, no?

That is correct, and "less problematic" is exactly how I'd put it. There's a problem left. Assuming bool -> numeric conversion is impossible, there's still a problem. First, consider a class, array, pointer, or number x. This compiles: if (x) stmt This also compiles: x ? expr1 : expr2 But this doesn't compile: bool b = x; Now consider we design tests to use opBool that effects implicit conversion to bool. Then, for a user-defined type x, all of the three samples above compile. Which means we have introduced a gratuitous incompatibility between user-defined and built-in types. Then consider another problem: a type that allows if (x) also wants to allow if (!x). It's the natural thing to want. Then we need to define opBool and opUnary!"!" to work in concert, redundantly. Bleh. I'm not sure how big problems these are. I think they are threatening enough that style manuals and coding standards mention both. Using double negation !!x throughout, there are only advantages and no disadvantage. I hit that design with Pacquiao punches over the past week or so, and couldn't find any shortcoming. It's consistent across positive and negated uses, easy to understand, easy to define, consistent with built-in types, and Walter likes it. Andrei

Couldn't we solv that by instead of introducing opBool, introduce opTrue. Which is defined as yielding a type testable for truth and is only invoked in the same situations that class references are used as thruth values? To me this looks like a simple solution.

OpTrue also implies opFalse, which is redundant.
Dec 07 2009
prev sibling next sibling parent Justin Johansson <no spam.com> writes:
Walter Bright wrote:
 1. symmetry
 2. compatibility with C and many other languages that use it
 3. used with operator overloading to convert a user defined type to its 
 preferred arithmetic representation (a cast can't know what the 
 'preferred' type is)
 4. to create DSL languages, like Spirit, as Kenny points out
 5. to coerce default integral promotion rules (again, cast(int) won't 
 always produce the same result)
 6. to visually emphasize that a literal is positive
 
 I say leave it in.

+vote
Dec 07 2009
prev sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Tue, 08 Dec 2009 16:40:20 +0300, Michel Fortin  
<michel.fortin michelf.com> wrote:

 On 2009-12-07 23:52:04 -0500, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> said:

 Michel Fortin wrote:
 On 2009-12-07 01:29:14 -0500, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> said:

 Using double negation !!x throughout, there are only advantages and  
 no disadvantage. I hit that design with Pacquiao punches over the  
 past week or so, and couldn't find any shortcoming. It's consistent  
 across positive and negated uses, easy to understand, easy to define,  
 consistent with built-in types, and Walter likes it.

FuzzyBool type (containing some sort of probability) and FuzzyBool.opUnary!("!") returns an inverted FuzzyBool (with 1 - original probability) instead of a regular bool, you'd have an infinite loop trying to evaluate !!myBoolValue.

design mistake of the user. If a type decides to return non-bool from "!", they are bound to unpleasantly surprise its user in more ways than one. You can define a negate for FuzzyBool - just don't dress it as the "!" operator.

To me, its using "!" to transform something to a bool that looks like a hack. Surely there's a more explicit and intuitive way to define it that doesn't tie it to a specific operator. opTest perhaps? And if you think "!" should always return a bool, then it should just not be overridable and should be defined as returning the negation of opTest (or whatever the name). I don't feel restricting unary "!" to return a bool is sound when all other unary ops can be defined to return anything.

You don't have to, but then you'll lose an ability to use UDT in if clause :P
Dec 08 2009
prev sibling next sibling parent Brad Roberts <braddr puremagic.com> writes:
Andrei Alexandrescu wrote:
 bearophile wrote:
 Walter Bright:

 Think of it like the "bool" operator overload. bool gives a direct
 way for user defined times to be tested for if statements, etc.
 Similarly, U+ gives a direct way for user defined types to be
 converted to their most desired arithmetic type.

I'd like opBool in D, for example to implement multiprecision numbers that can be used as integers in: if (somenumber) {...

Unfortunately experience with C++ has shown that things look simpler than they are. If opBool is an implicit conversion to bool, then all sorts of weird expressions are allowed. That's why conversion to bool is flat out unrecommended in C++. Instead, various libraries found alternate ways to allow testing with if without compromising things too much. Loki uses conversion to an opaque pointer type. Boost uses conversion to a pointer to member. The standard itself uses, I think, conversion of iostreams to void*.

Isn't one of the key problems that bool conversion introduces is the follow on conversion to integral types? If implicit bool -> integral conversion wasn't allowed, T -> bool conversion would be less problematic, no?
Dec 06 2009
prev sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:

 Is there any good use of unary +? As an aside, Perl programs do use it  
 occasionally for syntactic disambiguation :o).

 Andrei

Leave it in. WIth unary -, we should also have its archnemesis, the unary +. -- Simen
Dec 07 2009
next sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Simen kjaeraas wrote:
 Leave it in. WIth unary -, we should also have its archnemesis, the 
 unary +.

Can't have Superman without Lex Luthor!
Dec 07 2009
prev sibling parent reply Brad Roberts <braddr puremagic.com> writes:
Walter Bright wrote:
 Simen kjaeraas wrote:
 Leave it in. WIth unary -, we should also have its archnemesis, the
 unary +.

Can't have Superman without Lex Luthor!

Well, you can, but the stories would be a good bit less interesting.
Dec 07 2009
parent "Nick Sabalausky" <a a.a> writes:
"Brad Roberts" <braddr puremagic.com> wrote in message 
news:mailman.574.1260244655.20261.digitalmars-d puremagic.com...
 Walter Bright wrote:
 Simen kjaeraas wrote:
 Leave it in. WIth unary -, we should also have its archnemesis, the
 unary +.

Can't have Superman without Lex Luthor!

Well, you can, but the stories would be a good bit less interesting.

Issue #473: Superman clips his toenails!! Hair-raising, nail-biting action!
Dec 08 2009