www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Ternary/Trinary Operator Shortcut Notation

reply Alvaro Gutierrez <Alvaro_member pathlink.com> writes:
Hi there,

I'm a bit of a D newbie (C/C++/C# background), and I apologize if this has been
discussed before. I searched the archives and didn't find anything, though. By
the way, I absolutely love the language and I only hope I can help to make it
even better.

Anyway, I was wondering if perhaps the (very practical) "shortcut" form of the
ternary/trinary (?:) operator could be added to the D spec/implementation. This
feature originated as a GNU-C extension, and essentially allows for the omission
of the second operand. For example:

x = y ? y : z;

Could be shortened to (becomes the same as):

x = y ?: z;

This is a silly, trivial example, but for operands with side effects it becomes
quite useful. Consider the following (given the shortcut form is available):

string setting = readline() ?: "default value";

Otherwise, you'd have to go with the much wordier (and less aesthetic):

string input = readline();

if (input) {
setting = input;
}
else {
setting = "default value";
}

In addition, I don't generally see any drawbacks to implementing this feature,
barring some horrible lexical ambiguity that I'm not aware of. Is this something
that has been considered? Anything I can do to help make it happen?

Thanks for your time,
--AJG.

================================
2B || !2B, that is the question.
Jun 08 2005
next sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
This is useful, indeed.  Perl, iirc, generally implements this (very 
confusingly, imho) as "or".

But, you can shorten your example as follows:

string setting = readline();
if (!setting)
	setting = "default value";

So, it's not quite as bad as your example makes it look, in my opinion, 
but it's still a lot more cumbersome than the one-liner.

-[Unknown]


 Hi there,
 
 I'm a bit of a D newbie (C/C++/C# background), and I apologize if this has been
 discussed before. I searched the archives and didn't find anything, though. By
 the way, I absolutely love the language and I only hope I can help to make it
 even better.
 
 Anyway, I was wondering if perhaps the (very practical) "shortcut" form of the
 ternary/trinary (?:) operator could be added to the D spec/implementation. This
 feature originated as a GNU-C extension, and essentially allows for the
omission
 of the second operand. For example:
 
 x = y ? y : z;
 
 Could be shortened to (becomes the same as):
 
 x = y ?: z;
 
 This is a silly, trivial example, but for operands with side effects it becomes
 quite useful. Consider the following (given the shortcut form is available):
 
 string setting = readline() ?: "default value";
 
 Otherwise, you'd have to go with the much wordier (and less aesthetic):
 
 string input = readline();
 
 if (input) {
 setting = input;
 }
 else {
 setting = "default value";
 }
 
 In addition, I don't generally see any drawbacks to implementing this feature,
 barring some horrible lexical ambiguity that I'm not aware of. Is this
something
 that has been considered? Anything I can do to help make it happen?
 
 Thanks for your time,
 --AJG.
 
 ================================
 2B || !2B, that is the question.

Jun 08 2005
parent reply James Dunne <james.jdunne gmail.com> writes:
I definitely see the use in shortening that syntax, but the ?: together just
doesn't look appealing/intuitive to me.  I suppose it is the best choice for the
shortened operator, but !: would make more sense to me... It's more like "if NOT
this, then do this".  ?: on first appearance would look like "if this, then do
this".

In article <d87p0o$2o39$1 digitaldaemon.com>, Unknown W. Brackets says...
This is useful, indeed.  Perl, iirc, generally implements this (very 
confusingly, imho) as "or".

But, you can shorten your example as follows:

string setting = readline();
if (!setting)
	setting = "default value";

So, it's not quite as bad as your example makes it look, in my opinion, 
but it's still a lot more cumbersome than the one-liner.

-[Unknown]


 Hi there,
 
 I'm a bit of a D newbie (C/C++/C# background), and I apologize if this has been
 discussed before. I searched the archives and didn't find anything, though. By
 the way, I absolutely love the language and I only hope I can help to make it
 even better.
 
 Anyway, I was wondering if perhaps the (very practical) "shortcut" form of the
 ternary/trinary (?:) operator could be added to the D spec/implementation. This
 feature originated as a GNU-C extension, and essentially allows for the
omission
 of the second operand. For example:
 
 x = y ? y : z;
 
 Could be shortened to (becomes the same as):
 
 x = y ?: z;
 
 This is a silly, trivial example, but for operands with side effects it becomes
 quite useful. Consider the following (given the shortcut form is available):
 
 string setting = readline() ?: "default value";
 
 Otherwise, you'd have to go with the much wordier (and less aesthetic):
 
 string input = readline();
 
 if (input) {
 setting = input;
 }
 else {
 setting = "default value";
 }
 
 In addition, I don't generally see any drawbacks to implementing this feature,
 barring some horrible lexical ambiguity that I'm not aware of. Is this
something
 that has been considered? Anything I can do to help make it happen?
 
 Thanks for your time,
 --AJG.
 
 ================================
 2B || !2B, that is the question.


Regards, James Dunne
Jun 09 2005
parent reply Alvaro Gutierrez <Alvaro_member pathlink.com> writes:
James Dunne says...
I definitely see the use in shortening that syntax, but the ?: together just
doesn't look appealing/intuitive to me.  I suppose it is the best choice for the
shortened operator, but !: would make more sense to me... It's more like "if NOT
this, then do this".  ?: on first appearance would look like "if this, then do
this".

That's actually not a bad idea. I'd be happy to see the feature implemented with either of the two forms (with '?' or with '!'). In addition, in GNU-C, the two tokens don't have to go together, so it's somewhat flexible. E.g.: x = y ? : z; or: x = y ? /* y */ : z; or, with this new idea: x = y ! : z; Cheers, --AJG.
In article <d87p0o$2o39$1 digitaldaemon.com>, Unknown W. Brackets says...
This is useful, indeed.  Perl, iirc, generally implements this (very 
confusingly, imho) as "or".

But, you can shorten your example as follows:

string setting = readline();
if (!setting)
	setting = "default value";

So, it's not quite as bad as your example makes it look, in my opinion, 
but it's still a lot more cumbersome than the one-liner.

-[Unknown]


 Hi there,
 
 I'm a bit of a D newbie (C/C++/C# background), and I apologize if this has been
 discussed before. I searched the archives and didn't find anything, though. By
 the way, I absolutely love the language and I only hope I can help to make it
 even better.
 
 Anyway, I was wondering if perhaps the (very practical) "shortcut" form of the
 ternary/trinary (?:) operator could be added to the D spec/implementation. This
 feature originated as a GNU-C extension, and essentially allows for the
omission
 of the second operand. For example:
 
 x = y ? y : z;
 
 Could be shortened to (becomes the same as):
 
 x = y ?: z;
 
 This is a silly, trivial example, but for operands with side effects it becomes
 quite useful. Consider the following (given the shortcut form is available):
 
 string setting = readline() ?: "default value";
 
 Otherwise, you'd have to go with the much wordier (and less aesthetic):
 
 string input = readline();
 
 if (input) {
 setting = input;
 }
 else {
 setting = "default value";
 }
 
 In addition, I don't generally see any drawbacks to implementing this feature,
 barring some horrible lexical ambiguity that I'm not aware of. Is this
something
 that has been considered? Anything I can do to help make it happen?
 
 Thanks for your time,
 --AJG.
 
 ================================
 2B || !2B, that is the question.


Regards, James Dunne

================================ 2B || !2B, that is the question.
Jun 09 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 9 Jun 2005 15:05:26 +0000 (UTC), Alvaro Gutierrez wrote:

 James Dunne says...
I definitely see the use in shortening that syntax, but the ?: together just
doesn't look appealing/intuitive to me.  I suppose it is the best choice for the
shortened operator, but !: would make more sense to me... It's more like "if NOT
this, then do this".  ?: on first appearance would look like "if this, then do
this".

That's actually not a bad idea. I'd be happy to see the feature implemented with either of the two forms (with '?' or with '!'). In addition, in GNU-C, the two tokens don't have to go together, so it's somewhat flexible. E.g.: x = y ? : z; or: x = y ? /* y */ : z; or, with this new idea: x = y ! : z;

Just to clarify, the proposed syntax is equivalent to ... if (!(y)) x = z; right? Which is three characters longer. -- Derek Parnell Melbourne, Australia 10/06/2005 6:46:51 AM
Jun 09 2005
parent reply Oskar Linde <olREM OVEnada.kth.se> writes:
Derek Parnell wrote:

 On Thu, 9 Jun 2005 15:05:26 +0000 (UTC), Alvaro Gutierrez wrote:
 
 James Dunne says...
I definitely see the use in shortening that syntax, but the ?: together
just
doesn't look appealing/intuitive to me.  I suppose it is the best choice
for the shortened operator, but !: would make more sense to me... It's
more like "if NOT
this, then do this".  ?: on first appearance would look like "if this,
then do this".

That's actually not a bad idea. I'd be happy to see the feature implemented with either of the two forms (with '?' or with '!'). In addition, in GNU-C, the two tokens don't have to go together, so it's somewhat flexible. E.g.: x = y ? : z; or: x = y ? /* y */ : z; or, with this new idea: x = y ! : z;

Just to clarify, the proposed syntax is equivalent to ... if (!(y)) x = z; right? Which is three characters longer.

No. The proposed syntax is equivalent to: x = y ? y : z; but with only one evaluation of y. I use this feature extensively in another language where || has this behaviour. E.g: string message = query_message() || "Default"; ob = get_object() || new Ob; It is neat and useful, but maybe more so in dynamically typed languages.
Jun 09 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 09 Jun 2005 23:47:05 +0000, Oskar Linde wrote:

 Derek Parnell wrote:
 
 On Thu, 9 Jun 2005 15:05:26 +0000 (UTC), Alvaro Gutierrez wrote:
 
 James Dunne says...
I definitely see the use in shortening that syntax, but the ?: together
just
doesn't look appealing/intuitive to me.  I suppose it is the best choice
for the shortened operator, but !: would make more sense to me... It's
more like "if NOT
this, then do this".  ?: on first appearance would look like "if this,
then do this".

That's actually not a bad idea. I'd be happy to see the feature implemented with either of the two forms (with '?' or with '!'). In addition, in GNU-C, the two tokens don't have to go together, so it's somewhat flexible. E.g.: x = y ? : z; or: x = y ? /* y */ : z; or, with this new idea: x = y ! : z;

Just to clarify, the proposed syntax is equivalent to ... if (!(y)) x = z; right? Which is three characters longer.

No. The proposed syntax is equivalent to: x = y ? y : z; but with only one evaluation of y.

Thanks, I got a bit lost there for awhile. So using standard syntax it's sort of like ... if ( ((x = y) == false) x = z; The difference being that this has two assignments rather than one.
 I use this feature extensively in another language where || has this
 behaviour. E.g:
 
 string message = query_message() || "Default";
 
 ob = get_object() || new Ob;
 
 It is neat and useful, but maybe more so in dynamically typed languages.

Yes, I can see that it might be a neat shortcut at times. It would just have to be another idiom for people to learn how to read. How about a more familiar sort of syntax ... ob =? get_object() : new Obj; To me, this implies an assignment that is conditional and is analogous to x ? y : z; -- Derek Melbourne, Australia 10/06/2005 8:38:02 AM
Jun 09 2005
parent reply James McComb <ned jamesmccomb.id.au> writes:
Derek Parnell wrote:

 How about a more familiar sort of syntax ... 
 
   ob =? get_object() : new Obj;

What about this: ob ?= get_object() : new Obj; ?= by analogy with += *= etc. James McComb
Jun 09 2005
next sibling parent Derek Parnell <derek psych.ward> writes:
On Fri, 10 Jun 2005 09:16:21 +1000, James McComb wrote:

 Derek Parnell wrote:
 
 How about a more familiar sort of syntax ... 
 
   ob =? get_object() : new Obj;

What about this: ob ?= get_object() : new Obj; ?= by analogy with += *= etc.

Yeah, not bad at all. -- Derek Melbourne, Australia 10/06/2005 9:18:40 AM
Jun 09 2005
prev sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
I like that.  The downside is that, in Perl, you can:

print $test || "default";

But you couldn't:

writef(?= $test : "default");

But, of course, I think the ?= usage covers most of the usefulness of 
such a feature, and fits *much* more nicely with C syntax.

-[Unknown]


 Derek Parnell wrote:
 
 How about a more familiar sort of syntax ...
   ob =? get_object() : new Obj;

What about this: ob ?= get_object() : new Obj; ?= by analogy with += *= etc. James McComb

Jun 09 2005
parent reply Oskar Linde <olREM OVEnada.kth.se> writes:
Unknown W. Brackets wrote:

 I like that.  The downside is that, in Perl, you can:
 
 print $test || "default";
 
 But you couldn't:
 
 writef(?= $test : "default");
 
 But, of course, I think the ?= usage covers most of the usefulness of
 such a feature, and fits *much* more nicely with C syntax.

It would limit the usefulness if you had to assign the result to a named variable. Looking at how I use || where it has this semantic, it is more often used for temporaries, like funcall(a||b) or as a subexpression. Would it hurt anything if a||b in D got this functionality? It already has the semantics a?1:b?1:0 (or is it cast(bit)a?cast(bit)a:cast(bit)b ?) Changing this to a?a:b would be equivalent in most cases. Apart from dealing with the implicit cast: bit x = 0||5; I can see a potential problem were the operands have different types... ("string"||7) Another suggestion: a ?| b / Oskar
Jun 10 2005
parent reply Alvaro Gutierrez <Alvaro_member pathlink.com> writes:
Hi there,

There're a couple of things I'd like to add:

1) I think most of these proposed syntaxes would work ('!=' or '?|' or '?='). My
preference still lies with the original ('?:') or the Perl-ish variants ('||'
and 'or'), though. Nevertheless, the other suggestions aren't bad at all; I just
don't see any drawback to the original.

2) However, I have to agree with Oskar in that making it necessary to assign the
result to a variable limits the usefulness and generally makes things more
complicated.

3) Finally, I think a mere extension to an existing type-agnostic (IIRC)
operator (?:) is much simpler and easier to learn as an idiom (or ignored) than
a completely new assignment operator. It also avoids the whole operator
overloading morass. It seems like the path of least resistance; almost nothing
has to change.

Having said that, having any of these would be better than nothing at all. I
hope Walter considers some of the options.

Cheers,
--AJG.



In article <d8bf63$jgp$1 digitaldaemon.com>, Oskar Linde says...
Unknown W. Brackets wrote:

 I like that.  The downside is that, in Perl, you can:
 
 print $test || "default";
 
 But you couldn't:
 
 writef(?= $test : "default");
 
 But, of course, I think the ?= usage covers most of the usefulness of
 such a feature, and fits *much* more nicely with C syntax.

It would limit the usefulness if you had to assign the result to a named variable. Looking at how I use || where it has this semantic, it is more often used for temporaries, like funcall(a||b) or as a subexpression. Would it hurt anything if a||b in D got this functionality? It already has the semantics a?1:b?1:0 (or is it cast(bit)a?cast(bit)a:cast(bit)b ?) Changing this to a?a:b would be equivalent in most cases. Apart from dealing with the implicit cast: bit x = 0||5; I can see a potential problem were the operands have different types... ("string"||7) Another suggestion: a ?| b / Oskar

Jun 10 2005
parent Matthias Becker <Matthias_member pathlink.com> writes:
I suggest to use ??. Why? Because C# 2.0 does.

# int? x = 42; // nullable type
# 
# int foo = x ?? -1;  // foo will be 42
# 
# 
# int? y = null; // nullable type
# 
# int bar = y ?? -1;  // foo will be -1 as y is null
Jun 10 2005
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Alvaro Gutierrez wrote:
<snip>
 Anyway, I was wondering if perhaps the (very practical) "shortcut" form of the
 ternary/trinary (?:) operator could be added to the D spec/implementation. This
 feature originated as a GNU-C extension, and essentially allows for the
omission
 of the second operand. For example:

 string setting = readline() ?: "default value";

Like a generalisation of ||. I guess that || could be enhanced to do this (at the moment it just returns a boolean value), but I'm thinking it would complicate the process of detecting the '=' instead of '==' typo.
 Otherwise, you'd have to go with the much wordier (and less aesthetic):
 
 string input = readline();
 
 if (input) {
 setting = input;
 }
 else {
 setting = "default value";
 }

Assuming that string is an alias for a char[], then you can compromise string input; setting = (input = readline()) != "" ? input : "default value"; Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 09 2005
parent "Ben Hinkle" <bhinkle mathworks.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message 
news:d89pcp$1q6v$1 digitaldaemon.com...
 Alvaro Gutierrez wrote:
 <snip>
 Anyway, I was wondering if perhaps the (very practical) "shortcut" form 
 of the
 ternary/trinary (?:) operator could be added to the D 
 spec/implementation. This
 feature originated as a GNU-C extension, and essentially allows for the 
 omission
 of the second operand. For example:

 string setting = readline() ?: "default value";

Like a generalisation of ||. I guess that || could be enhanced to do this (at the moment it just returns a boolean value), but I'm thinking it would complicate the process of detecting the '=' instead of '==' typo.

Let's call the new operator ||| just kidding.
Jun 09 2005