Ternary operator



  • I’ve heard people discourage using a ternary operator. But I’ve never seen anybody go out of their way to use it.

    Return IIF(UCase(Data.Web_enabled) = "Y", True, False)


  • @liserdarts said:

    I’ve heard people discourage using a ternary operator. But I’ve never seen anybody go out of their way to use it.

    Return IIF(UCase(Data.Web_enabled) = "Y", True, False)

     Alrighty then.



  • "IIf" doesn't even work like an actual ternary operator ala C - both true and false cases get evaluated in VB, which can be seriously annoying.



  • yes and purely due to the ambiguity of the overloaded = operator.

     

    It could have been written as such:

    Return UCase(Data.Web_enabled) = "Y" 

    But how many vb programmers understand if that is now an assignment or an equality operation?  

    FWIW, It is an equality operator in this context, not an assignment. 



  • Whenever I return a value like that I always put brackets around the condition, like:

    Return ( UCase(Data.Web_enabled) = "Y" )

    It makes it a little more readable, and I can make sure that it won't get turned into an assignment by removing the "return"



  • well in this case it never will become an assignment because of the UCase()

    Now if instead it looked like the following:

    Return Data.Web_enabled = "Y"

    It would be a comparison, but if the return is removed it would become an assignment. 

    Placing parenthesis as you suggest around it would make it a comparison always.

    The rules behind this are pretty straight forward, but the application of it is not.   You have to take into account "implied assignments".

     



  • I love the ternary operator so much, and VB makes me sad because IIF just isn't the ternary operator, and is pretty much completely useless as in the situations in which ?: is most useful, IIF just doesn't cut it.

     t = (t == null)?(""):(t);

    Is just so much better than

    t = CType(IFF(t Is Nothing,"",t),String)

    VB makes me sad.



  • @Welbog said:

    I love the ternary operator so much, and VB makes me sad because IIF just isn't the ternary operator, and is pretty much completely useless as in the situations in which ?: is most useful, IIF just doesn't cut it.

     t = (t == null)?(""):(t);

    Is just so much better than

    t = CType(IFF(t Is Nothing,"",t),String)

    VB makes me sad.

    I think maybe because you do not understand it.

     t = (t == null)?(""):(t);

    will return either "" or the contents of t

    t = CType(IFF(t Is Nothing,"",t),String)

    Is superfluous instead use this:

    t = IFF(t Is Nothing,"",t)

    It returns either "" or the contents of t

    SO  

     IFF(t Is Nothing,"",t) is equal to (t == null)?(""):(t)

    Now if t was not a string variable you could run into problems with both of these if it actually held data.  In the C version you would have to cast it to a string the same way you tried to convert it in the VB version.  Let's not add complexity to one without showing the comparable checks on the other. 

     

     



  • t = IFF(t Is Nothing, "", t) won't work because IFF returns a type Object, but t is a String. VB won't cast that for you, so you have to cast it (unless you're using that terrible option which makes VB basically loosely typed). However, ?: returns whatever object type are in the last two arguments, without having to cast from Object (at least in Java, of which I am most familiar).

    That's why I added the explicit cast in the VB version but not the Java version.



  • You registered to post this? Where's the anger, man?

    parameter.Value = (t == null ? DBNull.Value : t);



  • @Welbog said:

    t = IFF(t Is Nothing, "", t) won't work because IFF returns a type Object, but t is a String. VB won't cast that for you, so you have to cast it (unless you're using that terrible option which makes VB basically loosely typed). However, ?: returns whatever object type are in the last two arguments, without having to cast from Object (at least in Java, of which I am most familiar).

    That's why I added the explicit cast in the VB version but not the Java version.

    Flipped back to VB.net and made sure Option strict was on (it was) and tested this.

    You are correct, under this setting it won't cast.  Bugger!

    You can get the results you want, but you do have to take the extra step of casting.  I guess because IIF() is a function and it has to return a particular type.  So yeah it is a ternary function, not a ternary operator.

    So I stand corrected. 



  • I guess the simplest form would actually be the following:

    CStr(IFF(t Is Nothing,"",t))

    Still not as clean as I would like, but gets close. 



  • The problem in VB is that IIf() is nothing more than a simple function. So it can't magically control parameter evaluation or change its return type like operators or statements do.
    Or in fact don't in VB, which shows another major annoyance: No short-cirquiting boolean operators...

    by the way, Return  is no valid VB as far as I know (except if Return() is a Method/Function). The correct syntax would be:

    Function MyFunction(...)
        ...
        MyFunction = Data.Web_enabled = "Y"
        ...
    End Function

    Which might give you a hint why it isn't done that way ;)


    By the way, for even more VB fun: The the name of the function you're inside ("MyFunction") is fully treated like a local variable. That meanst that constructs like

    Function Fac(n as Integer) as Long
        Dim I as Integer
        Fac = 1
        For I = 2 To n
            Fac = Fac * I
        Next I
    End Function

    Are valid and possible. Oh, of course VB supports recursive function calls as well :)

     



  • @PSWorx said:

    Or in fact don't in VB, which shows another major annoyance: No short-cirquiting boolean operators...

    Actually you can short-circuit evaluations.

    This is what the ANDALSO and ORELSE operators are for.  I know I don't like them either but short-circuiting in VB is possible. 



  • @KattMan said:

    @PSWorx said:

    Or in fact don't in VB, which shows another major annoyance: No short-cirquiting boolean operators...

    Actually you can short-circuit evaluations.

    This is what the ANDALSO and ORELSE operators are for.  I know I don't like them either but short-circuiting in VB is possible. 

     AFAIK, IANAVBLA, VB didn't support short circuiting... VB.NET does



  • @PSWorx said:

    by the way, Return  is no valid VB as far as I know (except if Return() is a Method/Function).

    Return is valid in VB, but it has to return the type the the function is defined as returning.  It is also only valid with a right hand value in "functions" as "subs" have no return value (or rather are functions that return void) so they just use Return.

    But you are forgiven if you do not normally code in VB. 



  • I was actually talking about VB (6.0), not .NET. But I wasn't aware they added return and short cirquiting in .NET. Sorry.



  • @webzter said:

    @KattMan said:
    @PSWorx said:

    Or in fact don't in VB, which shows another major annoyance: No short-cirquiting boolean operators...

    Actually you can short-circuit evaluations.

    This is what the ANDALSO and ORELSE operators are for.  I know I don't like them either but short-circuiting in VB is possible. 

     AFAIK, IANAVBLA, VB didn't support short circuiting... VB.NET does

    But looking at the rest of the statements, we are talking VB.Net here.  VB Classic does not have an Option Strict just an Option Explicit which does allow the automatic casting of return values.  Of course I can't check that right now, don't have VB6 available to me.

    Of course this recalls the question, since the languages are so different why we even have VB.Net instead of some other name.  Then again, why not just C#?  I know, I know, many vb classic developers felt like they were going to get short shafted. 



  • @KattMan said:

    But looking at the rest of the statements, we are talking VB.Net here.  VB Classic does not have an Option Strict just an Option Explicit which does allow the automatic casting of return values.  Of course I can't check that right now, don't have VB6 available to me.

    Of course this recalls the question, since the languages are so different why we even have VB.Net instead of some other name.  Then again, why not just C#?  I know, I know, many vb classic developers felt like they were going to get short shafted. 

    @PSWorx said:

    I was actually talking about VB (6.0), not .NET. But I wasn't aware they added return and short cirquiting in .NET. Sorry.

    To which I say, bring back Fred.NET!

    It's funny... I wrote a book that was (sort of) on VB.NET and I can't remember enough of it to code my way out of a wet paper bag. I get to help out occasionally with some of the other groups here that do VB.NET and it ends up being a bit of a mental exercise just to remember what goes where....



  • @PSWorx said:

    By the way, for even more VB fun: The the name of the function you're inside ("MyFunction") is fully treated like a local variable. That meanst that constructs like

    Function Fac(n as Integer) as Long
        Dim I as Integer
        Fac = 1
        For I = 2 To n
            Fac = Fac * I
        Next I
    End Function

    Are valid and possible. Oh, of course VB supports recursive function calls as well :)

    Your post is giving me loads of fun, and no I'm not picking on you.

    Yes the name of the function is seen as a local variable, and it also supports recursion.  Which leads to funky things like the following:

    Function MyFunct(MyInt as Int32) as Int32

         If MyInt < 10 Then

              MyFunc = MyFunc(MyInt)

         End If

    End Function

    Try debugging stuff like that one day. 



  • @KattMan said:

    Your post is giving me loads of fun, and no I'm not picking on you.

    Hehe, thanks very much.

    @KattMan said:


    Yes the name of the function is seen as a local variable, and it also supports recursion.  Which leads to funky things like the following:

    Function MyFunct(MyInt as Int32) as Int32

         If MyInt < 10 Then

              MyFunc = MyFunc(MyInt)

         End If

    End Function

    Try debugging stuff like that one day. 

    Correct me if I'm wrong, but isn't the even more insane variant of MyFunc = MyFunc(MyFunc) valid as well?



  • This seems like a rather timely post...

     http://www.panopticoncentral.net/archive/2007/05/08/20433.aspx

    Summary: IIF is being replaced by If and will act like a true ternary operator.



  • Speaking of VB, vBulletin (forum software written in PHP) has an iif() function.  A few versions ago the comment about it was changed to say that it was deprecated in favor of the ternary operator.  Of course it's still used in many places, which kind of makes me question what's going through the programmers' minds.



  • @PSWorx said:

    @KattMan said:

    Your post is giving me loads of fun, and no I'm not picking on you.

    Hehe, thanks very much.

    @KattMan said:


    Yes the name of the function is seen as a local variable, and it also supports recursion.  Which leads to funky things like the following:

    Function MyFunct(MyInt as Int32) as Int32

         If MyInt < 10 Then

              MyFunc = MyFunc(MyInt)

         End If

    End Function

    Try debugging stuff like that one day. 

    Correct me if I'm wrong, but isn't the even more insane variant of MyFunc = MyFunc(MyFunc) valid as well?

    Yes it would be but in that example the parameter to the function would always be 0 and hence never end.  My example actually does end.  Of course you could have assigned MyFunc = MyInt right before that in order to get your example working without running out of stack space.

     



  • @Welbog said:

    t = (t == null)?(""):(t);


    C# 2.0 is even easier:
    t = t ?? "";
    The ?? operator checks if the argument before it is null, if it is it will use the argument after it.



  • @PSWorx said:

    Correct me if I'm wrong, but isn't the even more insane variant of MyFunc = MyFunc(MyFunc) valid as well?

    ok let's go for insanity:

    Function MyFunct(MyInt as Int32) as Int32

         MyFunct = MyInt
         If MyFunct < 10 Then
              MyFunct = MyFunc(MyFunct)  
         End If

    Return MyFunct 

    End Function

    Perfectly valid VB.Net code.



  • @KattMan said:

    @PSWorx said:

    Correct me if I'm wrong, but isn't the even more insane variant of MyFunc = MyFunc(MyFunc) valid as well?

    ok let's go for insanity:

    Function MyFunct(MyInt as Int32) as Int32

         MyFunct = MyInt
         If MyFunct < 10 Then
              MyFunct = MyFunc(MyFunct)  
         End If

    Return MyFunct 

    End Function

    Perfectly valid VB.Net code.

     

    I fail to see the point of this code. If you pass in a number greater than or equal to ten then it'll exit and pass you back that number. If you pass a number less than ten it'll loop forever (nothing is done with said number). 



  • @PSWorx said:

    I was actually talking about VB (6.0), not .NET. But I wasn't aware they added return and short cirquiting in .NET. Sorry.

     

    The "real" WTF is that even though a number of people have since spelled circuit correctly, you've gone ahead and made a second attempt at forging new ground with "cirquit" anyway :O



  • @Kemp said:

    I fail to see the point of this code. If you pass in a number greater than or equal to ten then it'll exit and pass you back that number. If you pass a number less than ten it'll loop forever (nothing is done with said number). 

    Opps forgot the incrementing operation inside the If block:

    MyFunct += 1 



  • @webzter said:

    This seems like a rather timely post...

     http://www.panopticoncentral.net/archive/2007/05/08/20433.aspx

    Summary: IIF is being replaced by If and will act like a true ternary operator.

     

    The REAL wtf is this quote: "The result type of an If operation depends on the types of the two operands". Lord! The result type of an If operation should be a boolean. Period.



  • @holli said:

    @webzter said:

    This seems like a rather timely post...

     http://www.panopticoncentral.net/archive/2007/05/08/20433.aspx

    Summary: IIF is being replaced by If and will act like a true ternary operator.

     

    The REAL wtf is this quote: "The result type of an If operation depends on the types of the two operands". Lord! The result type of an If operation should be a boolean. Period.

    You missed the article. The If operator is new. It's a ternary. The results of a ternary depend on the type of the two operands.

    The result of the following is an int:

    int i = t=="bob" ? 1 : 0

     Whereas this is a string:

    string name = t== DBNull.Value ? string.Empty : t

    And this is an error:

    int test = t == 1 ? "bob" : 2

     



  • @webzter said:

    @holli said:
    @webzter said:

    This seems like a rather timely post...

     http://www.panopticoncentral.net/archive/2007/05/08/20433.aspx

    Summary: IIF is being replaced by If and will act like a true ternary operator.

     

    The REAL wtf is this quote: "The result type of an If operation depends on the types of the two operands". Lord! The result type of an If operation should be a boolean. Period.

    You missed the article. The If operator is new. It's a ternary. The results of a ternary depend on the type of the two operands.

    The result of the following is an int:

    int i = t=="bob" ? 1 : 0

     Whereas this is a string:

    string name = t== DBNull.Value ? string.Empty : t

    And this is an error:

    int test = t == 1 ? "bob" : 2

     

    No the real WTF is the fact that they are calling it an operator when it looks like a function.

    We have the If function:

    If(value) Then

    And now we have the if "operator"

    If((value)(trueresult)(falseresult))

    It still looks like a function because of the () Operators don't require these.  So essentially they overloaded the If function and are trying to convince us that it is now an operator when it isn't.



  • @KattMan said:

    @webzter said:
    @holli said:
    @webzter said:

    This seems like a rather timely post...

     http://www.panopticoncentral.net/archive/2007/05/08/20433.aspx

    Summary: IIF is being replaced by If and will act like a true ternary operator.

     

    The REAL wtf is this quote: "The result type of an If operation depends on the types of the two operands". Lord! The result type of an If operation should be a boolean. Period.

    You missed the article. The If operator is new. It's a ternary. The results of a ternary depend on the type of the two operands.

    The result of the following is an int:

    int i = t=="bob" ? 1 : 0

     Whereas this is a string:

    string name = t== DBNull.Value ? string.Empty : t

    And this is an error:

    int test = t == 1 ? "bob" : 2

     

    No the real WTF is the fact that they are calling it an operator when it looks like a function.

    We have the If function:

    If(value) Then

    And now we have the if "operator"

    If((value)(trueresult)(falseresult))

    It still looks like a function because of the () Operators don't require these.  So essentially they overloaded the If function and are trying to convince us that it is now an operator when it isn't.

    Why do you think that

    If(value) Then

    constitutes an "If function"? It's a syntax construct surrounding a block - functions don't require a "Then" and "End [whatever]". It also doesn't return _anything_ - it _accepts_ a boolean, and this hasn't changed.

     And the reason it's an operator isn't any aspect of its syntax, but, in this case, the fact that it controls whether the expressions are evaluated. if "value" is "false", "trueresult" (which may be a function call) never happens. Functions can't do that. (well, they can in lisp)



  • t = (t == null)?(""):(t);

     Isn't this the equivalent of

    if (t == null)   t = "";

    else t = t;

    ?

    The else part looks a bit stupid... 



  • @fist-poster said:

    t = (t == null)?(""):(t);

     Isn't this the equivalent of

    if (t == null)   t = "";

    else t = t;

    ?

    The else part looks a bit stupid... 

    My favorite C-flavor of this construct would have to be

     

    char* t = 0;

    /* stuff that presumably may or may not modify t */ 

    t?:(t="");

     

    which is legal, completely confusing, and does what you want it to do. grin



  • what about

    for (;!t;t="");

     

     


Log in to reply