formatting ?: operator

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

formatting ?: operator

John W. Eaton
Administrator
While we're on the subject of formatting and whitespace, could we also
choose a convention for the ?: operator when it is longer than one line?

For example, I typically write them like this:

   x = ((some_long_condition || some_other_longer_condition)
        ? some + expression - that / is * not + short
        : another + expression - that / is * also + not - short);

By including the extra parens around the whole expression, Emacs knows
how to indent this as above (display with a fixed-width font).  I've
noticed that we now have some files that use this convention instead:

   retval = lower ? octave::math::gammainc (x, a)
                  : 1.0 - octave::math::gammainc (x, a);

This looks fine, but I don't know how to get Emacs to do this for me.
I'd rather be able to just hit TAB and have something reasonable happen.
  If I ask Emacs to indent the above, I get

   retval = lower ? octave::math::gammainc (x, a)
     : 1.0 - octave::math::gammainc (x, a);

If I surround the expression with (), then Emacs will indent it as

   retval = (lower ? octave::math::gammainc (x, a)
             : 1.0 - octave::math::gammainc (x, a));

which is OK, but not really great.  By chance, this one lines up neatly,
but that's not generally what will happen.  So that's why I would
normally try to get the expression on one line or split before the ? and
possibly the : if both expressions won't fit on one line.

jwe

Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

Rik-4
On 04/24/2017 10:34 PM, John W. Eaton wrote:

> While we're on the subject of formatting and whitespace, could we also
> choose a convention for the ?: operator when it is longer than one line?
>
> For example, I typically write them like this:
>
>   x = ((some_long_condition || some_other_longer_condition)
>        ? some + expression - that / is * not + short
>        : another + expression - that / is * also + not - short);
>
> By including the extra parens around the whole expression, Emacs knows
> how to indent this as above (display with a fixed-width font).  I've
> noticed that we now have some files that use this convention instead:
>
>   retval = lower ? octave::math::gammainc (x, a)
>                  : 1.0 - octave::math::gammainc (x, a);
>
> This looks fine, but I don't know how to get Emacs to do this for me. I'd
> rather be able to just hit TAB and have something reasonable happen.  If
> I ask Emacs to indent the above, I get
>
>   retval = lower ? octave::math::gammainc (x, a)
>     : 1.0 - octave::math::gammainc (x, a);
>
> If I surround the expression with (), then Emacs will indent it as
>
>   retval = (lower ? octave::math::gammainc (x, a)
>             : 1.0 - octave::math::gammainc (x, a));
>
> which is OK, but not really great.  By chance, this one lines up neatly,
> but that's not generally what will happen.  So that's why I would
> normally try to get the expression on one line or split before the ? and
> possibly the : if both expressions won't fit on one line.
>
> jwe

I really like having the '?' and ':' line up vertically to show that there
is alternative A and alternative B.  It seems verbose to wrap both the
entire line and the test condition in parentheses, but I'm not strongly
opposed if you want to use that convention.

--Rik

Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

John W. Eaton
Administrator
On 04/25/2017 12:02 PM, Rik wrote:

> I really like having the '?' and ':' line up vertically to show that there
> is alternative A and alternative B.

I agree, which is why I might write

   retval = (lower
             ? octave::math::gammainc (x, a)
             : 1.0 - octave::math::gammainc (x, a));

even if the condition and the first expression will fit on a single line.

> It seems verbose to wrap both the
> entire line and the test condition in parentheses, but I'm not strongly
> opposed if you want to use that convention.

It's not necessary to wrap the condition.  My example could have been
written this way:

    x = (some_long_condition || some_other_longer_condition
         ? some + expression - that / is * not + short
         : another + expression - that / is * also + not - short);

I'm curious to know whether you have to do the alignment by hand or if
your editor (vim?) does it for you automatically.

jwe


Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

Mike Miller-4
On Tue, Apr 25, 2017 at 12:19:59 -0400, John W. Eaton wrote:

> On 04/25/2017 12:02 PM, Rik wrote:
>
> > I really like having the '?' and ':' line up vertically to show that there
> > is alternative A and alternative B.
>
> I agree, which is why I might write
>
>   retval = (lower
>             ? octave::math::gammainc (x, a)
>             : 1.0 - octave::math::gammainc (x, a));
>
> even if the condition and the first expression will fit on a single line.
>
> > It seems verbose to wrap both the
> > entire line and the test condition in parentheses, but I'm not strongly
> > opposed if you want to use that convention.
>
> It's not necessary to wrap the condition.  My example could have been
> written this way:
>
>    x = (some_long_condition || some_other_longer_condition
>         ? some + expression - that / is * not + short
>         : another + expression - that / is * also + not - short);
>
> I'm curious to know whether you have to do the alignment by hand or if your
> editor (vim?) does it for you automatically.

In my vim configuration, when I start a new line after
"some_other_longer_condition", it auto-indents 2 × shiftwidth, so twice
the indentation level normally applied to a block indent, from the start
of the previous line.

There is a vim configuration option to auto-indent to the next character
after the previous unclosed parenthesis, which I have not bothered
enabling personally, but that would handle the above style
automatically.

I have also not bothered enabling GNU indenting style in my vim
settings, so I usually end up manually fixing the indent for single-line
vs brace-enclosed blocks.

--
mike

Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

Rik-4
In reply to this post by John W. Eaton
On 04/25/2017 09:19 AM, John W. Eaton wrote:

> On 04/25/2017 12:02 PM, Rik wrote:
>
>> I really like having the '?' and ':' line up vertically to show that there
>> is alternative A and alternative B.
>
> I agree, which is why I might write
>
>   retval = (lower
>             ? octave::math::gammainc (x, a)
>             : 1.0 - octave::math::gammainc (x, a));
>
> even if the condition and the first expression will fit on a single line.
>
>> It seems verbose to wrap both the
>> entire line and the test condition in parentheses, but I'm not strongly
>> opposed if you want to use that convention.
>
> It's not necessary to wrap the condition.  My example could have been
> written this way:
>
>    x = (some_long_condition || some_other_longer_condition
>         ? some + expression - that / is * not + short
>         : another + expression - that / is * also + not - short);
>
> I'm curious to know whether you have to do the alignment by hand or if
> your editor (vim?) does it for you automatically.
>

Alas, I just do it by hand.  I checked to see what astyle would do, but it
just aligns the next line to the indent after the '=' sign.

--Rik

Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

Daniel Sebald
On 04/25/2017 11:35 AM, Rik wrote:

> On 04/25/2017 09:19 AM, John W. Eaton wrote:
>> On 04/25/2017 12:02 PM, Rik wrote:
>>
>>> I really like having the '?' and ':' line up vertically to show that there
>>> is alternative A and alternative B.
>>
>> I agree, which is why I might write
>>
>>   retval = (lower
>>             ? octave::math::gammainc (x, a)
>>             : 1.0 - octave::math::gammainc (x, a));
>>
>> even if the condition and the first expression will fit on a single line.
>>
>>> It seems verbose to wrap both the
>>> entire line and the test condition in parentheses, but I'm not strongly
>>> opposed if you want to use that convention.
>>
>> It's not necessary to wrap the condition.  My example could have been
>> written this way:
>>
>>    x = (some_long_condition || some_other_longer_condition
>>         ? some + expression - that / is * not + short
>>         : another + expression - that / is * also + not - short);
>>
>> I'm curious to know whether you have to do the alignment by hand or if
>> your editor (vim?) does it for you automatically.
>>
>
> Alas, I just do it by hand.  I checked to see what astyle would do, but it
> just aligns the next line to the indent after the '=' sign.
>
> --Rik

I too align by hand because it is usually just a quick one or two
tab-presses.  However, here is the alignment done by gvim without the
use of Tab or Backspace when I turn on both "smartindent" and "cindent":

void junk(void)
{
     x = (some_long_condition || some_other_longer_condition
             ? some + expression = autoindented / per + C
             : another + expression - autoindented);

     y = some_expression_without < brackets
         ? question + mark / aligned + here
         : colon / aligned - here;
}

That is, all the lead characters are moved back and forth depending on
context.  For example, after "void junk(void)" a CR will align the
cursor with 4-space indent, but then a curly bracket '{' moves the
character back 4-spaces.  Alignment doesn't see quite what I do but it
is close.  Maybe I'll leave this active for a while and see how it works.

Dan

Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

Daniel Sebald
In reply to this post by Mike Miller-4
On 04/25/2017 11:34 AM, Mike Miller wrote:

> There is a vim configuration option to auto-indent to the next character
> after the previous unclosed parenthesis, which I have not bothered
> enabling personally, but that would handle the above style
> automatically.

That's actually the difference I was referring to in my post.  I'll look
for that setting.

Dan

Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

Mike Miller-4
In reply to this post by Daniel Sebald
On Tue, Apr 25, 2017 at 11:47:27 -0500, Daniel J Sebald wrote:
> tab-presses.  However, here is the alignment done by gvim without the use of
> Tab or Backspace when I turn on both "smartindent" and "cindent":

Turning on both is useless, the 'cindent' option is smarter and
overrides the 'smartindent' option whether it is set or not.

Refer to ":help cinoptions-values" on all the myriad ways you can tune
'cindent' to your needs and preferences.

--
mike

Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

Mike Miller-4
In reply to this post by John W. Eaton
On Tue, Apr 25, 2017 at 12:19:59 -0400, John W. Eaton wrote:

> On 04/25/2017 12:02 PM, Rik wrote:
>
> > I really like having the '?' and ':' line up vertically to show that there
> > is alternative A and alternative B.
>
> I agree, which is why I might write
>
>   retval = (lower
>             ? octave::math::gammainc (x, a)
>             : 1.0 - octave::math::gammainc (x, a));
>
> even if the condition and the first expression will fit on a single line.

Back to the original topic, I agree, and it looks like those that have
chimed in agree that it should look either like this

    retval = (lower
              ? octave::math::gammainc (x, a)
              : 1.0 - octave::math::gammainc (x, a));

or this

    retval = lower
             ? octave::math::gammainc (x, a)
             : 1.0 - octave::math::gammainc (x, a);

but not this

    retval = lower ? octave::math::gammainc (x, a)
                   : 1.0 - octave::math::gammainc (x, a);

The only sticking point seems to be whether we should mandate
parentheses around the entire expression or not, right? And the main
purpose of the outer parentheses is to get emacs to indent correctly?

--
mike

Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

John W. Eaton
Administrator
On 04/25/2017 01:28 PM, Mike Miller wrote:

> The only sticking point seems to be whether we should mandate
> parentheses around the entire expression or not, right? And the main
> purpose of the outer parentheses is to get emacs to indent correctly?

Yes, and to make it look psuedo-lispy, I suppose.  :-)

jwe



Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

Rik-4
In reply to this post by Mike Miller-4
On 04/25/2017 10:28 AM, Mike Miller wrote:
> On Tue, Apr 25, 2017 at 12:19:59 -0400, John W. Eaton wrote: >> On 04/25/2017 12:02 PM, Rik wrote: >> >>> I really like having the '?' and ':' line up vertically to show that there >>> is alternative A and alternative B. >> >> I agree, which is why I might write >> >>   retval = (lower >>             ? octave::math::gammainc (x, a) >>             : 1.0 - octave::math::gammainc (x, a)); >> >> even if the condition and the first expression will fit on a single line. > > Back to the original topic, I agree, and it looks like those that have > chimed in agree that it should look either like this > >     retval = (lower >               ? octave::math::gammainc (x, a) >               : 1.0 - octave::math::gammainc (x, a)); > > or this > >     retval = lower >              ? octave::math::gammainc (x, a) >              : 1.0 - octave::math::gammainc (x, a); > > but not this > >     retval = lower ? octave::math::gammainc (x, a) >                    : 1.0 - octave::math::gammainc (x, a);

Actually, I prefer this last form, but if people really want the long form then I will live with it.  For me the tertiary operator is about a quick if/then/else operation.  If it turns out to be three lines for every situation then it might be clearer to just write out the logic explicitly.

if (lower)
  retval = octave::math::gammainc (x, a)
else
  retval = 1.0 - octave::math::gammainc (x, a);

A quick absolute value function also looks unnecessarily long when written in the new style

abs_x = x < 0
        ? -x
        : x;

--Rik

> > > The only sticking point seems to be whether we should mandate > parentheses around the entire expression or not, right? And the main > purpose of the outer parentheses is to get emacs to indent correctly? >


Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

John W. Eaton
Administrator
On 04/25/2017 05:44 PM, Rik wrote:

> Actually, I prefer this last form, but if people really want the long
> form then I will live with it.  For me the tertiary operator is about a
> quick if/then/else operation.  If it turns out to be three lines for
> every situation then it might be clearer to just write out the logic
> explicitly.
>
> if (lower)
>   retval = octave::math::gammainc (x, a)
> else
>   retval = 1.0 - octave::math::gammainc (x, a);
>
> A quick absolute value function also looks unnecessarily long when
> written in the new style
>
> abs_x = x < 0
>         ? -x
>         : x;

I was only talking about where to break the expression when it won't all
fit on one line.  If it will fit on one line, then I wouldn't split it.

jwe






Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

Mike Miller-4
On Tue, Apr 25, 2017 at 17:51:06 -0400, John W. Eaton wrote:

> On 04/25/2017 05:44 PM, Rik wrote:
>
> > A quick absolute value function also looks unnecessarily long when
> > written in the new style
> >
> > abs_x = x < 0
> >         ? -x
> >         : x;
>
> I was only talking about where to break the expression when it won't all fit
> on one line.  If it will fit on one line, then I wouldn't split it.

That was my understanding also, line break before the '?' if and only if
the entire ternary expression doesn't fit in 80 columns.

--
mike

Reply | Threaded
Open this post in threaded view
|

Re: formatting ?: operator

Rik-4
In reply to this post by John W. Eaton
On 04/25/2017 02:51 PM, John W. Eaton wrote:
> On 04/25/2017 05:44 PM, Rik wrote: > >> Actually, I prefer this last form, but if people really want the long >> form then I will live with it.  For me the tertiary operator is about a >> quick if/then/else operation.  If it turns out to be three lines for >> every situation then it might be clearer to just write out the logic >> explicitly. >> >> if (lower) >>   retval = octave::math::gammainc (x, a) >> else >>   retval = 1.0 - octave::math::gammainc (x, a); >> >> A quick absolute value function also looks unnecessarily long when >> written in the new style >> >> abs_x = x < 0 >>         ? -x >>         : x; > > I was only talking about where to break the expression when it won't all fit on one line.  If it will fit on one line, then I wouldn't split it.

Okay, that's a lot better.

I prefer the version wrapped in parentheses if it is going to be a long piece of code.  It helps me understand that the entire right-hand side is a single object.  For example,

x = y == 1;

I find that this can be ambiguous.  Did the programmer mean for x to be a bool value, or did they simply mistype and were actually trying for multiple assignment?

x = (y == 1);  // interpretation 1
x = y = 1;     // interpretation 2

To avoid ambiguity with the tertiary operator I would use parentheses and write

retval = (lower
          ? octave::math::gammainc (x, a)
          : 1.0 - octave::math::gammainc (x, a));

so it is clear that however complicated the right-hand side is, I'm just getting a single value out of it.

--Rik