Jump to page: 1 2
Thread overview
Ternary if and ~ does not work quite well
Oct 12, 2015
Andre
Oct 12, 2015
Rikki Cattermole
Oct 12, 2015
anonymous
Oct 12, 2015
Marc Schütz
Oct 12, 2015
H. S. Teoh
Oct 12, 2015
Andre
Oct 12, 2015
TheFlyingFiddle
Oct 12, 2015
anonymous
Oct 12, 2015
deed
Oct 12, 2015
Ali Çehreli
Oct 13, 2015
Jonathan M Davis
October 12, 2015
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é

October 12, 2015
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!
October 12, 2015
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
October 12, 2015
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é
October 12, 2015
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.
October 12, 2015
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...
October 12, 2015
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.
October 12, 2015
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.
October 12, 2015
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
}

October 12, 2015
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

« First   ‹ Prev
1 2