digitalmars.D.learn - Ternary if and ~ does not work quite well
- Andre (15/19) Oct 11 2015 Hi,
- Rikki Cattermole (7/25) Oct 11 2015 I read it as:
- anonymous (5/16) Oct 11 2015 compile
- Marc =?UTF-8?B?U2Now7x0eg==?= (3/5) Oct 12 2015 "foo" ~ true
- H. S. Teoh via Digitalmars-d-learn (14/26) Oct 11 2015 [...]
- Andre (4/18) Oct 11 2015 Thanks a lot for your answers, it really makes sense.
- TheFlyingFiddle (6/9) Oct 12 2015 "foo" ~ true
- anonymous (4/10) Oct 12 2015 char and bool are considered integral types. In `"foo " ~ true`, true is...
- deed (16/17) Oct 12 2015 {
- =?UTF-8?Q?Ali_=c3=87ehreli?= (12/21) Oct 12 2015 Yes, horror and the mandatory link: :)
- Jonathan M Davis via Digitalmars-d-learn (19/28) Oct 13 2015 The ternary operator is on the next to bottom rung on the same level wit...
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 barI would expect the output:foo bar foo bazAlso I would expect the assertion to compile. Kind regards André
Oct 11 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: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!bar barI would expect the output:foo bar foo bazAlso I would expect the assertion to compile. Kind regards André
Oct 11 2015
On Monday 12 October 2015 07:23, Rikki Cattermole wrote:On 12/10/15 6:19 PM, Andre wrote:[...]compile [...]// assert("foo "~ true ? "bar" : "baz" == "foo bar"); does notI 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
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
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
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:Thanks a lot for your answers, it really makes sense. Kind regards André[...][...] 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
Oct 11 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.
Oct 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.
Oct 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 }
Oct 12 2015
On 10/12/2015 08:39 AM, TheFlyingFiddle wrote:On Monday, 12 October 2015 at 05:19:40 UTC, Andre wrote: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. AliHi, 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
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