www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Ternary if and ~ does not work quite well

reply Andre <andre s-e-a-p.de> writes:
Hi,

I am not sure, whether the output of following coding is correct:

import std.stdio;

void main()
{
	writeln("foo "~ true ? "bar" : "baz");
	writeln("foo "~ false ? "bar" : "baz");
	// assert("foo "~ true ? "bar" : "baz" == "foo bar"); does not 
compile
}

Output:
 bar
 bar
I would expect the output:
 foo bar
 foo baz
Also I would expect the assertion to compile. Kind regards André
Oct 11 2015
next sibling parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
On 12/10/15 6:19 PM, Andre wrote:
 Hi,

 I am not sure, whether the output of following coding is correct:

 import std.stdio;

 void main()
 {
      writeln("foo "~ true ? "bar" : "baz");
      writeln("foo "~ false ? "bar" : "baz");
      // assert("foo "~ true ? "bar" : "baz" == "foo bar"); does not compile
 }

 Output:
 bar
 bar
I would expect the output:
 foo bar
 foo baz
Also I would expect the assertion to compile. Kind regards André
I read it as: assert("foo "~ (true ? ("bar") : ("baz" == "foo bar"))); Oh hey look: /d434/f138.d(6): Error: incompatible types for (("bar") : ("baz" == "foo bar")): 'string' and 'bool' Compiler agrees!
Oct 11 2015
parent reply anonymous <anonymous example.com> writes:
On Monday 12 October 2015 07:23, Rikki Cattermole wrote:

 On 12/10/15 6:19 PM, Andre wrote:
[...]
      // assert("foo "~ true ? "bar" : "baz" == "foo bar"); does not 
compile [...]
 I read it as:
 
 assert("foo "~ (true ? ("bar") : ("baz" == "foo bar")));
 
 Oh hey look:
 /d434/f138.d(6): Error: incompatible types for (("bar") : ("baz" == "foo 
 bar")): 'string' and 'bool'
 
 Compiler agrees!
It's `assert(("foo "~ true) ? ("bar") : ("baz" == "foo bar"));` though.
Oct 11 2015
parent Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Monday, 12 October 2015 at 05:34:13 UTC, anonymous wrote:
 It's `assert(("foo "~ true) ? ("bar") : ("baz" == "foo bar"));` 
 though.
"foo" ~ true Stupid C implicit conversion rules...
Oct 12 2015
prev sibling next sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Mon, Oct 12, 2015 at 05:19:38AM +0000, Andre via Digitalmars-d-learn wrote:
 Hi,
 
 I am not sure, whether the output of following coding is correct:
 
 import std.stdio;
 
 void main()
 {
 	writeln("foo "~ true ? "bar" : "baz");
 	writeln("foo "~ false ? "bar" : "baz");
 	// assert("foo "~ true ? "bar" : "baz" == "foo bar"); does not compile
 }
[...] It's best to parenthesize when mixing other operators with ?, because ? has a pretty low precedence and may "steal" arguments from surrounding operators that you don't intend. My suspicion is that what you wrote is being parsed as: writeln(("foo " ~ true) ? "bar" : "baz"); which is why you're getting unexpected output. Write instead: writeln("foo " ~ (true ? "bar" : "baz")); If anything, it also helps readers of your code understand what it does without needing to consult the precedence table. T -- EMACS = Extremely Massive And Cumbersome System
Oct 11 2015
parent Andre <andre s-e-a-p.de> writes:
On Monday, 12 October 2015 at 05:25:46 UTC, H. S. Teoh wrote:
 On Mon, Oct 12, 2015 at 05:19:38AM +0000, Andre via 
 Digitalmars-d-learn wrote:
 [...]
[...] It's best to parenthesize when mixing other operators with ?, because ? has a pretty low precedence and may "steal" arguments from surrounding operators that you don't intend. My suspicion is that what you wrote is being parsed as: writeln(("foo " ~ true) ? "bar" : "baz"); which is why you're getting unexpected output. Write instead: writeln("foo " ~ (true ? "bar" : "baz")); If anything, it also helps readers of your code understand what it does without needing to consult the precedence table. T
Thanks a lot for your answers, it really makes sense. Kind regards André
Oct 11 2015
prev sibling next sibling parent reply TheFlyingFiddle <kurtyan student.chalmers.se> writes:
On Monday, 12 October 2015 at 05:19:40 UTC, Andre wrote:
 Hi,
 	writeln("foo "~ true ? "bar" : "baz");
 André
"foo" ~ true How does this compile? All i can see is a user trying to append a boolean to a string which is obvously a type error. Or are they converted to ints and then ~ would be a complement operator? In that case.. horror.
Oct 12 2015
next sibling parent anonymous <anonymous example.com> writes:
On Monday 12 October 2015 17:39, TheFlyingFiddle wrote:

 "foo" ~ true
 
 How does this compile? All i can see is a user trying to append a 
 boolean to a string which is obvously a type error. Or are they 
 converted to ints and then ~ would be a complement operator? In 
 that case.. horror.
char and bool are considered integral types. In `"foo " ~ true`, true is converted to a char with a value of 1, i.e. some control character. I'm not a fan either.
Oct 12 2015
prev sibling next sibling parent deed <none none.none> writes:
On Monday, 12 October 2015 at 15:39:15 UTC, TheFlyingFiddle wrote:
 How does this compile?
{ string str = "hello"; foreach (n; [32, 119, 111, 114, 108, 100, 33]) str ~= n; import std.stdio : writeln; str.writeln; // prints "hello world!" writeln(true == 1); // true writeln(false == 0); // true string str2 = str.dup; str ~= 0; str2 ~= false; writeln(str == str2); // true str ~= 1; str2 ~= true; writeln(str == str2); // true }
Oct 12 2015
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 10/12/2015 08:39 AM, TheFlyingFiddle wrote:
 On Monday, 12 October 2015 at 05:19:40 UTC, Andre wrote:
 Hi,
     writeln("foo "~ true ? "bar" : "baz");
 André
"foo" ~ true How does this compile? All i can see is a user trying to append a boolean to a string which is obvously a type error. Or are they converted to ints and then ~ would be a complement operator? In that case.. horror.
Yes, horror and the mandatory link: :) http://dlang.org/type.html#integer-promotions That is why most C++ guidelines (used to) recommend against defining 'operator bool()' for user types because then objects of that type take part in expressions as integers. The common recommendation in C++ used to be to define 'operator void*()' instead, which is not integral but if I remember correctly, it had its own share of issues. (Sorry, can't find a reference for that at the moment.) C++11 made it possible to define 'operator bool()' as 'explicit' to prevent implicit conversion bugs. Ali
Oct 12 2015
prev sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Sunday, October 11, 2015 22:21:55 H. S. Teoh via Digitalmars-d-learn wrote:
 It's best to parenthesize when mixing other operators with ?, because ?
 has a pretty low precedence and may "steal" arguments from surrounding
 operators that you don't intend.  My suspicion is that what you wrote is
 being parsed as:

   writeln(("foo " ~ true) ? "bar" : "baz");

 which is why you're getting unexpected output. Write instead:

   writeln("foo " ~ (true ? "bar" : "baz"));

 If anything, it also helps readers of your code understand what it does
 without needing to consult the precedence table.
The ternary operator is on the next to bottom rung on the same level with the various assigment operators. The _only_ operator with lower precedence than the ternary operator is the comma (be it the comma operator or the comma as an argument separator). So, if you're doing something like auto i = foo == bar ? "hello" : "world"; or foo(arg1, foo == bar ? "hello" : "world", arg3); then the ternary is done before the stuff around it, but other than that, everything around it is going to be done first. So, whether you need parens are not is actually pretty straightforward. It pretty much boils down to if you want the ternary to be done before anything else around it, use parens. If you want the ternary operator to be done last, then you don't need them. I actually think that the ternary operator is very easy to get right because it's pretty much at one end of the operator precedence table rather than in the middle where you have to remember what goes before and what comes after. But for some reason, a lot of folks seem to assume that it has different precedence than it has and have trouble with it. - Jonathan M Davis
Oct 13 2015