• (disco)

    :blink.apng:

    Time for count the :wtf:s:

    1. Comparing boolean values with a boolean const
    2. Comparing with the != operator
    3. If this uses lazy evaluation, won't the download button be enabled for anyone except administrators (at least if the file exists)? Writing the condition in such a way that 50% of the readers get tricked by precedence rules. Use parentheses dammit!
  • (disco) in reply to JBert
    JBert:
    won't the download button be enabled for anyone except administrators (at least if the file exists

    Non-admins can download the file if it exists. Admins can download it whether it exists or not.

  • (disco)

    != true is truly awful.

  • (disco)

    OK, there are minor WTF's with the semantics, and the logic is totally borked, but where is there a "tri-state-boolean"?

  • (disco) in reply to TheCPUWizard

    The title really is TRWTF.

  • (disco) in reply to HardwareGeek
    HardwareGeek:
    Non-admins can download the file if it exists. Admins can download it whether it exists or not.

    Are you sure? Here's the condition again:

    userCanDownload != true && file != null || userCanDownload != false
    

    I believe you can equivalently rewrite it like this:

    ! userCanDownload && (file != null || userCanDownload)

    If that's correct, if admins have the userCanDownload boolean set to true and lazy evaluation rules are used, the whole statement should immediately evaluate to false for admins. If you aren't an admin, the button will show up if the file variable is non-null.

    EDIT: Never mind, I'm done in by precedence rules. Belgium this code.

  • (disco)

    She needed 3 hours to find this bug? In a codebase she's familiar with, I assume? Wow

  • (disco) in reply to Arnold_Schwarzer
    Arnold_Schwarzer:
    She needed 3 hours to find this bug? In a codebase she's familiar with, I assume? Wow
    The fix may be simple; doesn't mean tracking the fault was
  • (disco) in reply to JBert

    && precedes || in all languages I know

  • (disco) in reply to Arnold_Schwarzer
    Arnold_Schwarzer:
    && precedes || in all languages I know

    I have no idea what the precedence is, because I always use brackets to make damn sure && and || are evaluating in the order I mean

  • (disco) in reply to TheCPUWizard

    It's a classic bait-and-switch. I can't believe you weren't expecting something like that. You better never go in against a Sicilian.

  • (disco) in reply to Arnold_Schwarzer

    In many languages precedence is the same for && and ||, so the expressions will be evaluated in the order they are encounted. Which may or may not be from left to right (depending on the language, and is indetermined for some languages).

    I always use parentheses in these situations to prevent FILE_NOT_FOUND, having encountered similar WTFs far too often.

  • (disco) in reply to Jaloopa
    Jaloopa:
    I have no idea what the precedence is, becausehence I always use brackets to make damn sure && and || are evaluating in the order I mean

    FTFY. That's why you always get it wrong when reading someone else's code.

    You'd easily remember the preferences if you knew anything about boolean algebras: && is multiplication and || is addition.

  • (disco) in reply to Planar
    Planar:
    you always get it wrong when reading someone else's code

    No I don't, I look it up when I need it and then promptly forget it

    Planar:
    && is multiplication and || is addition.
    implementation detail. No guarantee any particular language will adhere to that
  • (disco) in reply to Jaloopa
    Jaloopa:
    implementation detail
    Actually, part of the definition of Boolean logic
    Jaloopa:
    No guarantee any particular language will adhere to that
    The ones that don't therefore don't implement Boolean logic
  • (disco) in reply to Planar
    Planar:
    || is addition.

    TIL 1 || 1 = 2. Who would have known? I always thought it was 1

  • (disco) in reply to Arnold_Schwarzer

    Not in VHDL.

  • (disco) in reply to Vault_Dweller

    That's wrong, though. 1 || -1 is not 0

  • (disco) in reply to aliceif

    Well, what is it? i?

  • (disco) in reply to Snowman25

    In most languages I know of? 1.

  • (disco) in reply to aliceif

    That doesn't seem intitive at all. But then, -1 isn't a boolean value, hence || isn't a boolean addition but a comparison.

  • (disco) in reply to Snowman25

    In languages like JavaScript and Ruby, || works as follows:

    • If the left operand is truthy, return it.
    • Otherwise return the right operand.
  • (disco) in reply to Vault_Dweller
    Vault_Dweller:
    TIL 1 || 1 = 2. Who would have known? I always thought it was 1

    Obviously there ain't no 2, so it can't be 2. But addition in ℤ₂ is 1 ⊕ 1 = 0, so 1 || 1 = 1 still does not actually qualify.

  • (disco) in reply to Bulb

    There is a 2. It means "super true"

  • (disco) in reply to Vault_Dweller

    And what is -1 then?

  • (disco) in reply to aliceif

    "Not likely"

  • (disco) in reply to Vault_Dweller
    Vault_Dweller:
    TIL <code> 1 || 1 = 2</code>. Who would have known? I always thought it was 1

    Argh, you guys take everything so literally. Here is the correct statement (from wikipedia)

    Boolean algebra satisfies many of the same laws as ordinary algebra when one matches up ∨ with addition and ∧ with multiplication.

  • (disco) in reply to aliceif

    FILE_NOT_FOUND, obviously

  • (disco) in reply to BobbyTables
    BobbyTables:
    "Not likely"

    And -2 is, of course, "Not bloody likely".

    Filed under: -3, no fucking way

  • (disco) in reply to Planar
    Planar:
    Boolean algebra satisfies many of the same laws as ordinary algebra when one matches up ∨ with addition and ∧ with multiplication.

    It does, but not that way. ({0, 1}, 0, 1, ⊻, ∧) is a field just like ℤ or ℝ. But since ({0, 1}, 0, ∨) is not a group, only a monoid, and since all the two-operation algebras (ring, field) require group in the first operation, ({0, 1}, 0, 1, ∨, ∧) is not any of them.

  • (disco) in reply to Arnold_Schwarzer
    Arnold_Schwarzer:
    She needed 3 hours to find this bug? In a codebase she's familiar with, I assume?

    There's your mistake. I used to work with a modified version of SugarCRM. Whenever there was an issue, finding it and fixing it could easily take hours, as the codebase was criminally obscure. Whether or not I was familiar with it was relative. I was more familiar than anyone else, but ultimately the only rule I learned for certain was that SugarCRM was unlikely to do something in a commonly intuitive way. Nevermind the modifications made by the developers of the product for our company.

    if(userCanDownload != true && file != null || userCanDownload != false) { EnableDownloadButton(); } Else { DisableDownloadButton(); }

    If this is javascript, the client can just go and look for the file without having permissions to see it, right? Let's hope they don't. Based on that assumption, one would assume she had been looking on the backend or in the ACL interface or equivalent, finding nothing. I guess we're also assuming that the software doesn't have about 50 non-SPA pages between itself and the developer over a slow connection.

    It could have been worse. After 3 hours, she could have come across this:

    var enabled = (userCanDownload && file != null);

    "What's wrong?" you might ask. You'd rather see an explicit 'userCanDownload === true' rather than a vague, truthy condition? Maybe the fact that I've created an unnecessary new variable. Those might be your nightmares, but in my nightmares, I've found this code, and I have to keep looking.

  • (disco) in reply to Vault_Dweller

    Actually since we don't have a 2 to work with, the correct answer is 1 + 1 == -1. -1, expressed in twos complement notation with a single bit, is 1.
    Therefore 1 + 1 == 1. Duh.

  • (disco) in reply to mruhlin

    Whats cool about this website is that often, the WTF moments are in the comments, which add to the pile.. :smile:

  • (disco) in reply to Buddy
    Buddy:
    You better never go in against a Sicilian.
    Or start a land war in Asia. INCONCEIVABLE!
  • (disco) in reply to Jaloopa

    I can confirm that there exists at least one programming language that reverses this implementation detail. It was a 4GL written by accountants. I was part of the team trying, and failing, to modernise it. This was one sticking point. because we couldn't fix it without breaking legacy code in hard to detect ways.

  • (disco) in reply to mruhlin

    Odd, I would have thought if we didn't have a 2 to work with that 1 + 1 == 10.

  • (disco)

    !!! BIG WARNING !!!

    Be sure to check permissions again when serving the actual file!

    Button availability is not so important, it's better to show button to everyone and fail due to permissions after clicking on it than allowing some hacker with a Web Development Console to download the file even with disabled button.

  • (disco) in reply to powerlord

    Sorry, i left out a step. We only have one bit to work with, so we end up in overflow condition: MAX_BOOL + 1 == MIN_BOOL.
    Since these are presumed to be signed bools, MAX_BOOL = 1; MIN_BOOL = -1

  • (disco) in reply to TheCPUWizard

    Right here: https://msdn.microsoft.com/en-us/library/microsoft.office.core.msotristate.aspx

    Note that this "tri-state" actually has 5 states, 3 of which have description "Not Supported."

  • (disco) in reply to aliceif
    aliceif:
    ```!= true``` is trulynot falsely awful.

    FTFY

  • (disco)
    Lindsay closed her eyes, picturing the Maui...

    Am I the only one that first read that as "Maul"?

    And does that make me TRWTF?

  • (disco) in reply to numberone
    Arnold_Schwarzer:
    She needed 3 hours to find this bug? In a codebase she's familiar with, I assume? Wow

    Not that familiar ... I can guarantee she never saw this line before. This would trigger alarms with anyone sane.

    aliceif:
    That's wrong, though.1 || -1 is not 0

    Boolean math is a separate mathematical system; the rules are slightly different than normal math. There are only two values to begin with, 1 and 0. There's no carry, and the results are always in the same set. So in that system:

    • 0+0⇒0; 0+1⇒1; 1+0⇒1;1+1⇒1 ... we call this "or", but in Boolean scheme, it is addition
    • 0x0⇒0; 0x1⇒0; 1x0⇒0;1x1⇒1 ... we call this "and", but in Boolean scheme, it is multiplication

    That leads indirectly to the precedence rules. As Boolean math developed, most equations came to be of the form ab+cd+efg ... that is, the sum of the products. Therefore, it made hierarchical sense to treat the Boolean add and the Boolean multiply with the same precedence as the normal mathematical equations. Now, of course, we use && for Boolean multiply and || for Boolean add; and the hierarchy rules track.

    In computers, hierarchy came to be subdivided further, because in an equation like a==b||c==d we want the comparisons to be done first, to save parenthesis. For some weird reason, saving parenthesis was a very important thing to language designers back in the 50's and 60's. (But APL solved precedence confusion by saying "always right-to-left unless you use parenthesis"; it's actually one of the great things about that language.)

    But now we know (at least we're supposed to know) that parenthesis are cheap and we should use them. Human understanding of programs is far more important than compiler nanoseconds.

    numberone:
    Button availability is not so important, it's better to show button to everyone and fail due to permissions after clicking on it than allowing some hacker with a Web Development Console to download the file even with disabled button.

    Hear, hear!

    I think this is one of the most overlooked elements of web page security. Clients (browsers) are inherently insecure; security cannot be controlled by disabling elements in the browser--or by using "display:none". A certain system I work with sends data to the "browser" with data the user is not permitted to see set to "display:none". All they have to do to see the actual data is to scrape the underlying log...which any user can do. :facepalm:

  • (disco) in reply to numberone
    numberone:
    Be sure to check permissions again when serving the actual file!

    Button availability is not so important, it's better to show button to everyone and fail due to permissions after clicking on it than allowing some hacker with a Web Development Console to download the file even with disabled button.

    Are you sure this CodeSOD is client-side?

  • (disco) in reply to CoyneTheDup
    CoyneTheDup:
    But now we know (at least we're supposed to know) that parenthesis are cheap and we should use them. Human understanding of programs is far more important than compiler nanoseconds.

    So you switched from APL to LISP?

  • (disco) in reply to aliceif
    aliceif:
    So you switched from APL to LISP?

    Lots of Irritating Silly Parenthesis?

    No, I've never used that language. My understanding is that, in that language, the parenthesis have meaning besides just order of execution: They also indicate sets and sets of sets and sets of sets of sets; and language bracketing (equivalent to braces in C) and probably things related to color, shape, ...well, parenthesis are just used for everything.

    It sounds worse, to me.

  • (disco)

    Easy: Tri-state: Not True, Not False, FILE_NOT_FOUND

  • (disco) in reply to mruhlin
    mruhlin:
    Actually since we don't have a 2 to work with, the correct answer is 1 + 1 == -1. -1, expressed in twos complement notation with a single bit, is 1. Therefore 1 + 1 == 1. Duh.
    No, actually. A one-bit two's complement field holds two different values: 0 and -. (No, there is nothing missing between the - and the . I really mean it, although you could make a case that the two values are + and -, because there is only a sign bit...)

    But that does yield the interesting possibility that:

          • == +
          • == + (In both cases, assuming a normal two's complement addition circuit (bit+bit+carry in => bit+carry out, not a hard circuit to build), we observe that 0+0=0 in the bits, and 1+1=0 in the bits, assuming carry in == 0 and carry out == discarded.)
  • (disco) in reply to Steve_The_Cynic

    I've always loved the concept of negative and positive zero... Seemed edgy to me, like the rising and falling edges of a pulse...

  • (disco) in reply to CoyneTheDup
    CoyneTheDup:
    **L**ots of **I**rritating **S**illy **P**arenthesis?

    No, I've never used that language. My understanding is that, in that language, the parenthesis have meaning besides just order of execution: They also indicate sets and sets of sets and sets of sets of sets; and language bracketing (equivalent to braces in C) and probably things related to color, shape, ...well, parenthesis are just used for everything.

    It sounds worse, to me.

    No. Parentheses in LISP mean just one thing: a list of zero or more elements. If you try to evaluate the list, the first item in the list is an operation and the rest of the items are arguments. A list may include multiple lists, each evaluatable... and there's your program.
  • (disco) in reply to Steve_The_Cynic

    No, actually. A one-bit two's complement field holds two different values: 0 and -. (No, there is nothing missing between the - and the . I really mean it, although you could make a case that the two values are + and -, because there is only a sign bit...)

    That's one's complement. In one's complement, a byte ranges from -127 to +127, with the high bit storing the sign. A signed bit would range from -0 to +0. I honestly don't know why they still teach one's complement - processors stopped using it decades before I went to school decades ago.

    In two's complement, a byte ranges from -128 to +127. A signed bit would range from -1 to 0. (8 bits: -128 to +127, 7 bits: -64 to +63, 6 bits: -32 to +31, 5 bits: -16 to +15, 4 bits: -8 to 7, 3 bits: -4 to 3, 2 bits: -2 to 1, 1 bit: -1 to 0. One of my favorite bogus interview questions is "what's the range of a signed bit?" I throw it into conversations for fun, but I've never asked it in a serious interview, but one day.. one day...

Leave a comment on “Tri-State Boolean”

Log In or post as a guest

Replying to comment #449274:

« Return to Article