If would be greater than For, if I knew what If or Greater Than were for



  • @toshir0 said:

    @Lorne Kates said:

    AndAlso
    No language bashing intended (moreover it's just too easy to bash VB...) but.... seriously. Stop that please.

    Yeah, you should know that in the latest version of VB, it's AndWithYourSpirit...



  • @dhromed said:

    From a single atom?

    Why ? Are married atoms safer ?



  • @dhromed said:

    @toshir0 said:

    @Lorne Kates said:

    my cat ate it
    Not him.

    pukes pink goo

     

    From a single atom?

    I dunno.. radium atoms are pretty big. This isn't helium we're talking about.



  • @toshir0 said:

    @Lorne Kates said:
    @toshir0 said:

    @Lorne Kates said:

    AndAlso
    No language bashing intended (moreover it's just too easy to bash VB...) but.... seriously. Stop that please.
     

    I wish I could, but that's the only way to short circuit a logic check in VB (because somewhere, someone thought that would be a good idea)

    If foo IsNot Nothing And foo.bar() Then ' <======= This crashes on null foo
    If foo IsNot Nothing AndAlso foo.bar() Then ' <==== This stops at the AndAlso

    OK, thank you for the explanation (if I get it well, the second form being equivalent to the '&&' we can find in many other places, like, say, javascript), I'm almost VB-virgin. Not that I resent that, though.
     

    Yup.  And JavaScript got it from C, and C needed the whole ridiculous "two AND and two OR operators" thing because its type system is too weak for the compiler to tell the difference between a number and a boolean.  VB does not have that problem (and neither do Java or C#) but they've all mindlessly copied the broken, ugly C model just because that's the way C does it so it must be right.

    And since the whole boolean vs. number issue isn't an issue in a language with a halfway decent type system, they've changed the rationale for it to instead be about a side-effect of the original C behavior: one of them short-circuits on logical operations (because it's a logical operator) and one does not (because it's it originally was a bitwise operator whose arguments are two integers and should never be used for logical operations.)  Which is even stupider than the original.  If your code intentionally uses a non-short-circuiting conditional for any reason, you're doing something very wrong and need to refactor.

    Gotta love C-argo C-ult language design...



  • @Mason Wheeler said:

    Yup.  And JavaScript got it from C, and C needed the whole ridiculous "two AND and two OR operators" thing because its type system is too weak for the compiler to tell the difference between a number and a boolean.  VB does not have that problem (and neither do Java or C#) but they've all mindlessly copied the broken, ugly C model just because that's the way C does it so it must be right.

    And since the whole boolean vs. number issue isn't an issue in a language with a halfway decent type system, they've changed the rationale for it to instead be about a side-effect of the original C behavior: one of them short-circuits on logical operations (because it's a logical operator) and one does not (because it's it originally was a bitwise operator whose arguments are two integers and should never be used for logical operations.)  Which is even stupider than the original.  If your code intentionally uses a non-short-circuiting conditional for any reason, you're doing something very wrong and need to refactor.

    Gotta love C-argo C-ult language design...

    [citation needed] C originally lacked booleans, all logical operations were done on integers. It didn't need to distinguish between numbers and booleans.

    It's true languages like Java could have done without two sets of AND and OR operators, but it was likely retained to make the transition from C easier. I would consider it a pretty minor bit of overhead and not really worth complaining about.

    I do agree that non-short-circuiting conditionals are a WTF.



  • @Mason Wheeler said:

    @toshir0 said:

    @Lorne Kates said:
    @toshir0 said:

    @Lorne Kates said:

    AndAlso
    No language bashing intended (moreover it's just too easy to bash VB...) but.... seriously. Stop that please.
     

    I wish I could, but that's the only way to short circuit a logic check in VB (because somewhere, someone thought that would be a good idea)

    If foo IsNot Nothing And foo.bar() Then ' <======= This crashes on null foo
    If foo IsNot Nothing AndAlso foo.bar() Then ' <==== This stops at the AndAlso

    OK, thank you for the explanation (if I get it well, the second form being equivalent to the '&&' we can find in many other places, like, say, javascript), I'm almost VB-virgin. Not that I resent that, though.
     

    Yup.  And JavaScript got it from C, and C needed the whole ridiculous "two AND and two OR operators" thing because its type system is too weak for the compiler to tell the difference between a number and a boolean.  VB does not have that problem (and neither do Java or C#) but they've all mindlessly copied the broken, ugly C model just because that's the way C does it so it must be right.

    And since the whole boolean vs. number issue isn't an issue in a language with a halfway decent type system, they've changed the rationale for it to instead be about a side-effect of the original C behavior: one of them short-circuits on logical operations (because it's a logical operator) and one does not (because it's it originally was a bitwise operator whose arguments are two integers and should never be used for logical operations.)  Which is even stupider than the original.  If your code intentionally uses a non-short-circuiting conditional for any reason, you're doing something very wrong and need to refactor.

    Gotta love C-argo C-ult language design...

    If you enjoy good design try to use the IIF(condition,value_if_true, value_if_false) function in Microsoft Reporting Services to avoid a divide by zero error... Unlike the IF construct, that function evaluates all parameters no matter what.

    iif(BottomValue=0,0,TopValue/BottomValue) //divide by zero error is BottomValue is 0
    iif(BottomValue=0,0,TopValue/iif(BottomValue=0,1,BottomValue)) //works



  • @Mason Wheeler said:

    Yup.  And JavaScript got it from C, and C needed the whole ridiculous "two AND and two OR operators" thing because its type system is too weak for the compiler to tell the difference between a number and a boolean.  VB does not have that problem (and neither do Java or C#) but they've all mindlessly copied the broken, ugly C model just because that's the way C does it so it must be right.

    TDEMSYR. Seriously, WTF are you talking about here?



  • @boomzilla said:

    @Mason Wheeler said:
    Yup.  And JavaScript got it from C, and C needed the whole ridiculous "two AND and two OR operators" thing because its type system is too weak for the compiler to tell the difference between a number and a boolean.  VB does not have that problem (and neither do Java or C#) but they've all mindlessly copied the broken, ugly C model just because that's the way C does it so it must be right.

    TDEMSYR. Seriously, WTF are you talking about here?

     

    I'm talking about history.  As Morbs pointed out, there was no Boolean type in C.  Instead, the rule was "everything is a boolean."  Integers, pointers, floating-point numbers, anything could represent False (if 0/null) or True (if any other value.)  So because there's no Boolean type, the compiler can't do something sensible like what a Pascal compiler (invented before C, and got it right) can do:

    myBool3 := myBool1 and myBool2; //Both arguments are booleans, so this is a logical AND
    myInt3 := myInt1 and myInt2; //both arguments are integers, so this is a bitwise AND
    myError := myBool1 and myInt2; //compiler error. This operation makes no sense. (But you can still do it in C...)

    Instead, you have to do the compiler's work for it by selecting between two different versions of the operators, and heaven help you if you accidentally pick the wrong one, because the compiler's not going to.  (And for some reason that kindasorta makes sense at the bits and bytes level, but not from a consistency perspective, there's only one XOR operator.  And the bitwise and logical NOT operators are two different symbols instead of one symbol that's either used once or twice.  Go figure.)

     



  • @Mason Wheeler said:

    @boomzilla said:

    @Mason Wheeler said:
    Yup.  And JavaScript got it from C, and C needed the whole ridiculous "two AND and two OR operators" thing because its type system is too weak for the compiler to tell the difference between a number and a boolean.  VB does not have that problem (and neither do Java or C#) but they've all mindlessly copied the broken, ugly C model just because that's the way C does it so it must be right.

    TDEMSYR. Seriously, WTF are you talking about here?

     

    I'm talking about history.  As Morbs pointed out, there was no Boolean type in C.  Instead, the rule was "everything is a boolean."  Integers, pointers, floating-point numbers, anything could represent False (if 0/null) or True (if any other value.)  So because there's no Boolean type, the compiler can't do something sensible like what a Pascal compiler (invented before C, and got it right) can do:

    myBool3 := myBool1 and myBool2; //Both arguments are booleans, so this is a logical AND
    myInt3 := myInt1 and myInt2; //both arguments are integers, so this is a bitwise AND
    myError := myBool1 and myInt2; //compiler error. This operation makes no sense. (But you can still do it in C...)
    Instead, you have to do the compiler's work for it by selecting between two different versions of the operators, and heaven help you if you accidentally pick the wrong one, because the compiler's not going to.  (And for some reason that kindasorta makes sense at the bits and bytes level, but not from a consistency perspective, there's only one XOR operator.  And the bitwise and logical NOT operators are two different symbols instead of one symbol that's either used once or twice.  Go figure.)

     

    This is incorrect. According to Dennis Ritchie, C originally only had the "bitwise" & and | operators, which did short-circuiting in a boolean truth context (e.g. in a while or if statement). However, the implicit difference in behavior based on context was considered confusing, so they re-jiggered it to have additional "logical" operators which made the semantics explicit.



  • @Mason Wheeler said:

    @boomzilla said:

    @Mason Wheeler said:
    Yup.  And JavaScript got it from C, and C needed the whole ridiculous "two AND and two OR operators" thing because its type system is too weak for the compiler to tell the difference between a number and a boolean.  VB does not have that problem (and neither do Java or C#) but they've all mindlessly copied the broken, ugly C model just because that's the way C does it so it must be right.

    TDEMSYR. Seriously, WTF are you talking about here?

    I'm talking about history.  As Morbs pointed out, there was no Boolean type in C.  Instead, the rule was "everything is a boolean."  Integers, pointers, floating-point numbers, anything could represent False (if 0/null) or True (if any other value.)  So because there's no Boolean type, the compiler can't do something sensible like what a Pascal compiler (invented before C, and got it right) can do:

    myBool3 := myBool1 and myBool2; //Both arguments are booleans, so this is a logical AND
    myInt3 := myInt1 and myInt2; //both arguments are integers, so this is a bitwise AND
    myError := myBool1 and myInt2; //compiler error. This operation makes no sense. (But you can still do it in C...)
    Instead, you have to do the compiler's work for it by selecting between two different versions of the operators, and heaven help you if you accidentally pick the wrong one, because the compiler's not going to.  (And for some reason that kindasorta makes sense at the bits and bytes level, but not from a consistency perspective, there's only one XOR operator.  And the bitwise and logical NOT operators are two different symbols instead of one symbol that's either used once or twice.  Go figure.)

    Strongly typed if statements annoy me, though they do allow the compiler to catch stuff where you're assigning inside the if condition (of course, the proper way to stop that is to not allow assignments inside there). TRWTF is how you got here from talking about short circuiting, which is probably what confused me. I mean, don't let me stop you from your favorite rant or anything...the non sequitur just threw me a bit.



  • @morbiuswilters said:

    This is incorrect. According to Dennis Ritchie, C originally only had the "bitwise" & and | operators, which did short-circuiting in a boolean truth context (e.g. in a while or if statement). However, the implicit difference in behavior based on context was considered confusing, so they re-jiggered it to have additional "logical" operators which made the semantics explicit.
     

    Interesting.  I hadn't heard that before.  Do you have a source for that?  And how long did that last before they made the change?  Because as far back as I can remember, there have been double AND and OR operators in C...

     



  • @boomzilla said:

    Strongly typed if statements annoy me, though they do allow the compiler to catch stuff where you're assigning inside the if condition

    Who said anything about "strongly typed if statements," or if statements in general?  I was talking about AND and OR operators.  They can be used in conditionals, but that's hardly the only thing that can be done with them. (See my example code, where they're used to assign to another value.)

    (of course, the proper way to stop that is to not allow assignments inside there).

    The proper way to do that is to not allow the bloody assignment operator to return a value, whether you're in a conditional or not.

    TRWTF is how you got here from talking about short circuiting, which is probably what confused me. I mean, don't let me stop you from your favorite rant or anything...the non sequitur just threw me a bit.
     

    By way of toshir0's observation that the VB operator strangeness was mirroring similar strangeness in Javascript and "other languages".  I just happened to know where the root of all that was.

     



  • @Mason Wheeler said:

    @morbiuswilters said:

    This is incorrect. According to Dennis Ritchie, C originally only had the "bitwise" & and | operators, which did short-circuiting in a boolean truth context (e.g. in a while or if statement). However, the implicit difference in behavior based on context was considered confusing, so they re-jiggered it to have additional "logical" operators which made the semantics explicit.
     

    Interesting.  I hadn't heard that before.  Do you have a source for that?  And how long did that last before they made the change?  Because as far back as I can remember, there have been double AND and OR operators in C...

     

    Here's the best I could find: http://www.lysator.liu.se/c/dmr-on-or.html From the sound of it, it was implemented before K&R was even written.



  • @Mason Wheeler said:

    The proper way to do that is to not allow the bloody assignment operator to return a value, whether you're in a conditional or not.

    Do you mean that you are also against this?

    x = y = 1

    I always found this convenient, just like methods chaining (such as DateTime.AddDays(x).ToString()). But I have to say I care more about convenience than principles, unless the principles serve me better (which is then a form of convenience anyways).



  • @Mason Wheeler said:

    I was talking about AND and OR operators.  They can be used in conditionals, but that's hardly the only thing that can be done with them. (See my example code, where they're used to assign to another value.)

    So the deficiency of C is that it can't use a single operator to do short-circuiting AND/OR in a boolean assignment because it's no different than doing a bitwise AND/OR, since there is no boolean type in C. However, it could do it in a "truth context", which is where most people would use it. However, C long-ago rectified this by adding additional logical operator to do short-circuiting boolean operations. I don't consider this a big deal. Nor do I consider it a big deal that other languages inherited C's semantics, most likely as a way to make the transition for C programmers easier.

    @Mason Wheeler said:

    The proper way to do that is to not allow the bloody assignment operator to return a value, whether you're in a conditional or not.

    110% agreed.



  • @Speakerphone Dude said:

    @Mason Wheeler said:
    The proper way to do that is to not allow the bloody assignment operator to return a value, whether you're in a conditional or not.

    Do you mean that you are also against this?

    x = y = 1

    I always found this convenient, just like methods chaining (such as DateTime.AddDays(x).ToString()). But I have to say I care more about convenience than principles, unless the principles serve me better (which is then a form of convenience anyways).

    I think that's less clear than:

    y = 1;

    x = y;

    Clarity is key to maintainability and reducing the number of bugs. Whatever short-term convenience there is in allowing chained assignments is significantly overshadowed by all of the problems it has introduced.



  • @Mason Wheeler said:

    @boomzilla said:
    Strongly typed if statements annoy me, though they do allow the compiler to catch stuff where you're assigning inside the if condition

    Who said anything about "strongly typed if statements," or if statements in general?  I was talking about AND and OR operators.  They can be used in conditionals, but that's hardly the only thing that can be done with them. (See my example code, where they're used to assign to another value.)

    Well, you talked about how C doesn't have a boolean type, which is kinda required for strongly typed if statements. Using integers as boolean stand-ins has never bothered me.

    @Mason Wheeler said:

    @boomzilla said:
    (of course, the proper way to stop that is to not allow assignments inside there).

    The proper way to do that is to not allow the bloody assignment operator to return a value, whether you're in a conditional or not.

    That's quite a bit broader that the topic at hand, but that construct always seems to lead to clever code, and I wouldn't mind not having that, but it's not on the same level as allowing assignments inside of a comparison.

    @Mason Wheeler said:

    TRWTF is how you got here from talking about short circuiting, which is probably what confused me. I mean, don't let me stop you from your favorite rant or anything...the non sequitur just threw me a bit.

    By way of toshir0's observation that the VB operator strangeness was mirroring similar strangeness in Javascript and "other languages".  I just happened to know where the root of all that was.

    Yeah, except that it was pretty orthogonal (maybe tangential, at best) to short circuiting.



  • @morbiuswilters said:

    @Speakerphone Dude said:
    @Mason Wheeler said:
    The proper way to do that is to not allow the bloody assignment operator to return a value, whether you're in a conditional or not.

    Do you mean that you are also against this?

    x = y = 1

    I always found this convenient, just like methods chaining (such as DateTime.AddDays(x).ToString()). But I have to say I care more about convenience than principles, unless the principles serve me better (which is then a form of convenience anyways).

    I think that's less clear than:

    y = 1;

    x = y;

    Clarity is key to maintainability and reducing the number of bugs. Whatever short-term convenience there is in allowing chained assignments is significantly overshadowed by all of the problems it has introduced.

     

    This.  Plus, the concept just makes me vaguely uncomfortable.  I can't really articulate why very well, but I sort of have the feeling that if you're initializing two variables to the same value, one immediately after the other like that (and that value is not zero/null/other "empty value") then you're probably doing something wrong, or at least there's a better way to accomplish whatever it is you're doing.

     



  • @Mason Wheeler said:

    @morbiuswilters said:

    @Speakerphone Dude said:
    @Mason Wheeler said:
    The proper way to do that is to not allow the bloody assignment operator to return a value, whether you're in a conditional or not.

    Do you mean that you are also against this?

    x = y = 1

    I always found this convenient, just like methods chaining (such as DateTime.AddDays(x).ToString()). But I have to say I care more about convenience than principles, unless the principles serve me better (which is then a form of convenience anyways).

    I think that's less clear than:

    y = 1;

    x = y;

    Clarity is key to maintainability and reducing the number of bugs. Whatever short-term convenience there is in allowing chained assignments is significantly overshadowed by all of the problems it has introduced.

     

    This.  Plus, the concept just makes me vaguely uncomfortable.  I can't really articulate why very well, but I sort of have the feeling that if you're initializing two variables to the same value, one immediately after the other like that (and that value is not zero/null/other "empty value") then you're probably doing something wrong, or at least there's a better way to accomplish whatever it is you're doing.

     

    Basically agree. I can think of contrived examples where you would want to start two variables at the same value because one is going to quickly diverge (e.g. a startIndex and currentIndex value for a vector just before a loop which will increment currentIndex), but in those cases it's still fine to just explicitly have two assignments on their own lines instead of a single chained assignment. The cost of getting rid of chained assignments is very small and the potential benefits are large.



  • @Speakerphone Dude said:

    Do you mean that you are also against this?

    x = y = 1

    I've got no problem with it in PL/1, except that to avoid confusion it should be written:

     x = (y = 1);

    and anyone not trying to be cute will probably write it as:

    if y=1 then x = '1'b; else x = '0'b;

    (Oh, and we had your AndAlso as well.  It's called Then If.)

     



  • @Mason Wheeler said:

    there's only one XOR operator.

     

    !=

    EDIT:  I'm way off on that one, != won't properly logical-XOR two "True" yet different values, i.e. 1 and 2.



  • Just for added confusion (as far as I can tell), Perl allows

    ($x = $y) = 1;

    which assigns $y to $x, then 1 to $x.

    I can't think of any reason why you'd actually want to do that, but hey, the option is there!



  • @Mason Wheeler said:

    @morbiuswilters said:

    @Speakerphone Dude said:
    @Mason Wheeler said:
    The proper way to do that is to not allow the bloody assignment operator to return a value, whether you're in a conditional or not.

    Do you mean that you are also against this?

    x = y = 1

    I always found this convenient, just like methods chaining (such as DateTime.AddDays(x).ToString()). But I have to say I care more about convenience than principles, unless the principles serve me better (which is then a form of convenience anyways).

    I think that's less clear than:

    y = 1;

    x = y;

    Clarity is key to maintainability and reducing the number of bugs. Whatever short-term convenience there is in allowing chained assignments is significantly overshadowed by all of the problems it has introduced.

     

    This.  Plus, the concept just makes me vaguely uncomfortable.  I can't really articulate why very well, but I sort of have the feeling that if you're initializing two variables to the same value, one immediately after the other like that (and that value is not zero/null/other "empty value") then you're probably doing something wrong, or at least there's a better way to accomplish whatever it is you're doing.

     

    That was a simplified syntax example. One could meet a situation where the output value of a method can be used to chain updates on properties for objects that need the same information without running the method twice.

    Here is an example in manufacturing where distinct areas of the supply chain need to be kept in sync.

    /*short notation*/

    AVCO.PurchasedTotal = ERP.O2C = GL.Consolidate(item);




    /long notation/

    ERP.O2C = GL.Consolidate(item);

    AVCO.PurchasedTotal = ERP.O2C;

    IMHO the long notation does not convey the same visual logic that all those values are related, and this is the nature of the business to have some kind of multicasting on the source value. I see nothing wrong with the short notation but it's not something I would refactor one way or the other if I had to maintain some code anyways. Maybe it's just me.



  • @Speakerphone Dude said:

    @Mason Wheeler said:

    @morbiuswilters said:

    @Speakerphone Dude said:
    @Mason Wheeler said:
    The proper way to do that is to not allow the bloody assignment operator to return a value, whether you're in a conditional or not.

    Do you mean that you are also against this?

    x = y = 1

    I always found this convenient, just like methods chaining (such as DateTime.AddDays(x).ToString()). But I have to say I care more about convenience than principles, unless the principles serve me better (which is then a form of convenience anyways).

    I think that's less clear than:

    y = 1;

    x = y;

    Clarity is key to maintainability and reducing the number of bugs. Whatever short-term convenience there is in allowing chained assignments is significantly overshadowed by all of the problems it has introduced.

     

    This.  Plus, the concept just makes me vaguely uncomfortable.  I can't really articulate why very well, but I sort of have the feeling that if you're initializing two variables to the same value, one immediately after the other like that (and that value is not zero/null/other "empty value") then you're probably doing something wrong, or at least there's a better way to accomplish whatever it is you're doing.

     

    That was a simplified syntax example. One could meet a situation where the output value of a method can be used to chain updates on properties for objects that need the same information without running the method twice.

    Here is an example in manufacturing where distinct areas of the supply chain need to be kept in sync.

    /*short notation*/

    AVCO.PurchasedTotal = ERP.O2C = GL.Consolidate(item);




    /long notation/

    ERP.O2C = GL.Consolidate(item);

    AVCO.PurchasedTotal = ERP.O2C;

    IMHO the long notation does not convey the same visual logic that all those values are related, and this is the nature of the business to have some kind of multicasting on the source value. I see nothing wrong with the short notation but it's not something I would refactor one way or the other if I had to maintain some code anyways. Maybe it's just me.

    /*best notation*/
    decimal consolidation = GL.Consolidate(item);
    ERP.O2C = consolidation;
    AVCO.PurchasedTotal = consolidation;
    

Log in to reply

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.