Javascript doublespeak



  • So get this...

     In Javascript, the following expressions apparently hold:

    !"false" == false

    and

    "true" != true

    So Javascript is a typed language, blah blah blah, but let's take into consideration this scenario:

    myHtmlElement.something = "false";

    ...code...

    if (!myHtmlElement.something) { alert("It's false, as expected"); } else { alert("My God! The basic tenets of boolean logic appear to be broken!"); }

    Now, one might EXPECT that since myHtmlElement is an HTML element, and HTML is composed of strings, that you would get the expected message... but NO! Javascript apparently thinks that the string "false" is true for purposes of boolean logic, because - well, it's not BOOLEAN false, and it's not undefined! And because it's a dynamically typed language, you don't even get a warning! You'd think that a dynamically typed language would treat "false" as false to avoid these kinds of headaches... or am I the WTF for being an English-speaking WASP who is insensitive to the needs of international programmers (why isn't "faux" evaluated as false too? Gotta be fair to our Freedom-speaking friends!)



  • @ekolis said:

    You'd think that a dynamically typed language would treat "false" as false to avoid these kinds of headaches... or am I the WTF for being an English-speaking WASP who is insensitive to the needs of international programmers (why isn't "faux" evaluated as false too? Gotta be fair to our Freedom-speaking friends!)

     

    So naturally, you'd expect "false"=="faux" to evaluate as true also.

    And by extension, "Tuesday"=="mardi".



  • Arg!  TRWTF is Javascript developers who get confused at coersion.  It's really not that hard, and this one is so fundamental!  It's easy to avoid if you don't like it, you just have to be more verbose and explicit.

    So tell me again, why do you think "false" should evaluate to false..?  Do you think the string "return 99" should do something special too? 



  • @ekolis said:

    Now, one might EXPECT that since myHtmlElement is an HTML element, and HTML is composed of strings, that you would get the expected message...

    One might expect that if one didn't know how type coercion worked in JavaScript, I suppose. Empty strings are false; all other strings are true. That's how it works.

    @ekolis said:

    You'd think that a dynamically typed language would treat "false" as false to avoid these kinds of headaches...

    I think that would cause more headaches than it cured. What about the string "False"? What about "FaLsE"? What about "cake"? It's not "true", so by your logic it must be false. But it's not "false", so by your logic it must be true.

     



  • @ekolis said:

    In Javascript, the following expressions apparently hold:

    !"false" == false

    and

    "true" != true

    Doesn't the same thing hold true for C/C++?



  • TRWTF is the old idiom that 0 is false, and all other things are true. Semantically, it just makes no sense - if you have zero apples, that doesn't mean that you have false apples, and if you have 10 apples, that doesn't mean you have true apples!

    What makes it even worse are the languages that extend it such that certain default values are also false - the empty string is not false, it is empty! If your name is lambda, that doesn't mean your name is false!



  • @Tacroy said:

    TRWTF is the old idiom that 0 is false, and all other things are true. Semantically, it just makes no sense - if you have zero apples, that doesn't mean that you have false apples, and if you have 10 apples, that doesn't mean you have true apples!
    I guess you're good for Java, then.  Only booleans are booleans.  (Well, Booleans are too with unboxing.)

    IMO, this is annoying.  I wish null would evaluate to false, then I could just write [code]if (object) {...}[/code] like in C rather than [code]if (object != null) {...}[/code].  In (most implementations of) C, it's obvious: if the object is null, then its address is zero, which evaluates to false.

    Coercion is about convenience.  If it's not convenient to you, then do it the long way.



  • @Xyro said:

    I guess you're good for Java, then.  Only booleans are booleans.  (Well, Booleans are too with unboxing.)

    IMO, this is annoying.  I wish null would evaluate to false, then I could just write <font face="Lucida Console" size="2">if (object) {...}</font> like in C rather than <font face="Lucida Console" size="2">if (object != null) {...}</font>.  In (most implementations of) C, it's obvious: if the object is null, then its address is zero, which evaluates to false.

    Coercion is about convenience.  If it's not convenient to you, then do it the long way.

     

    But that's exactly what I meant about the idiom being semantically confused - null is neither false nor zero, it is null. 

    For example: let's say you had a language with nullable primitives, and null is the default value of a primitive (this could be C or C++, in fact). You declare <font face="Lucida Console" size="2">int x = 0;</font> and <font face="Lucida Console" size="2">int y;</font>

    In your model, <font face="Lucida Console" size="2">(x == y) </font>is true - but it shouldn't be! <font face="Lucida Console" size="2">x</font> is known, and it's known to be zero; <font face="Lucida Console" size="2">y</font>, on the other hand, is unknown. <font face="Lucida Console" size="2">x</font> simply should not be equal to <font face="Lucida Console" size="2">y</font>. And yet C and C++ say it is - they say "a value known to be zero is equivalent to an unknown value", which is, as I said, semantically nonsensical



  • @ekolis said:

    Now, one might EXPECT that since myHtmlElement is an HTML element, and HTML is composed of strings, that you would get the expected message...
     

    Of course not, don't be ridiculous.

    @ekolis said:

    Javascript apparently thinks that the string "false" is true for purposes of boolean logic, because - well, it's not BOOLEAN false, and it's not undefined!

    Dear lord! It cannot interpret strings as a human does! It behaves in a strictly predictable way! How unfathomable!

    @ekolis said:

    You'd think that a dynamically typed language
    would treat "false" as false

    If you truly rely in this kind of behaviour I must place serious doubts on the quality of your code.

    @ekolis said:

    to avoid these kinds of headaches...

    They're not headaches.

    @ekolis said:

    or am I the WTF
    Quite.

     

    Look, the first step to fixing your nonsense would to quit wielding the strings "true" and "false". If you have some other bit of code that generates HTML with these literals, do one of the following:

    • change it. It is shit.
    • wrap the getter in a function that casts to a proper boolean. This is your option if you cannot change the HTML-writing code. 

    I sometimes transfer booleans through attribute values, and as such strictly use "0" and "1", which I cast though Number() and Boolean() to get real bools. To convert back, I cast the bool with Number(). It's excellent habit to type explicitly.

    Off you go.



  • @Tacroy said:

    But that's exactly what I meant about the idiom being semantically confused - null is neither false nor zero, it is null.
     

    I avoid null in my code, and the libraries we use always return an empty something if they don't return anything, instead of returning null which has absolutely no effect except making you pad your code with null checks.



  • TRWTF might be the OP. Seriously, few (popular) languages are strict enough to require the condition to be a boolean, including statically typed languages. Of course dynamic languages don't care either. Most treat 0 as false (which might seem pointless, but hey, it does shorten null pointer checks etc), some also treat empty collections (which seems pointless too - although I'd consider an object that is always true even more dangerous) as false, etc. Either way, silently turning "false" into false would be, as others have already pointed out, be a much worse WTF than anything else that's propably posted here.

    I don't see the problem with this behaviour, btw. The people who get bugs by this are the same people that don't get anything else right because their coding is so incredibly sloppy that not even Standard ML could make their code work (instead, it would just fail to compile). Like the lost soul that wrote the code you showed - WhoTF uses "false" instead of false for e.g. an isUpdated property?



  • I actually love languages that have relatively strong type checks. That's why I expect my favourite language to yell at me when I try to check if "true" != true.

     

    It simply makes no sense to compare a string to a boolean value, because they are different types, so they can't be equal. Sure, in some cases it might be somewhat useful, e.g. comparing a 64 bit long (long) to an (32 bit) integer, that is, when one of the types is a subset of the other type.

     

    However, using a string type variable (or any kind of nullable type) when the language syntax asks for a boolean expression, that's just wrong. I see that it makes live easier in some situations, but I simply don't like it.



  • @Tacroy said:

    TRWTF is the old idiom that 0 is false, and all other things are true. Semantically, it just makes no sense - if you have zero apples, that doesn't mean that you have false apples, and if you have 10 apples, that doesn't mean you have true apples!


    It's a perfectly sane metaphor in my opinion.

    If you have zero apples, you don't have apples.
    If you have more than one, you do.

    Don't, do => false, true



  • @dhromed said:

    @ekolis said:
    or am I the WTF
    Quite.
    I totally disagree. Whilst it is entirely understandable that for practical reasons it's impossible to do what he says, it's a sensible thing to say, in a way.

    False is not the same as zero. Using 0 for boolean false makes all kind of sense, but it's still entirely arbitrary. It makes just as much (non-pragmatic) sense to arbitrarily use a string "false". The logic is slightly different as a result, but generally behaves the same way. VBA at least is quite happy with the concept that the string "false" is the same as boolean false in a boolean compare, despite the boolean values actually being 2-byte integers.



  •  Javascript works about as I would expect based on my experience with C++, Perl, Python, Ruby, Groovy.  The only possible confusion is with zero and the empty string, which are both false.



  • @Tacroy said:

    TRWTF is the old idiom that 0 is false, and all other things are true. Semantically, it just makes no sense - if you have zero apples, that doesn't mean that you have false apples, and if you have 10 apples, that doesn't mean you have true apples!

    Well, no.  But it does mean that if you have zero apples, it is false that you have apples, and if you have 10 apples, it is true that you have apples.  You're just putting the words in the wrong order.




  • @ekolis said:

    myHtmlElement.something = "false";

    if (!myHtmlElement.something) { alert("It's false, as expected"); } else { alert("My God! The basic tenets of boolean logic appear to be broken!"); }

    Now, one might EXPECT that since myHtmlElement is an HTML element, and HTML is composed of strings, that you would get the expected message... but NO! Javascript apparently thinks that the string "false" is true for purposes of boolean logic

    No, there's a third player here that often gets forgotten.  Most of the stuff that's done in Javascript is inside a web browser and it's usually working on the HTML Document Object Model.  HTML might be transmitted over the wires as strings but when it arrives at the browser it's parsed into the DOM before it reaches your screen.

    Assigning "false" to an HTML boolean attribute causes the DOM to parse the string and store the result as false.  Depending on the attribute, "none", "default", "0" will have the same effect.  Assigning "false" to any extendo properties that you created will pass "false" to any setter function that you've created or it will just store the string.  The DOM lets you do stuff like myHTMLElement.style.height="12px" which will set the height of the object to 12 pixels and x=myHTMLElement.style.height will return the number 12.

     

    Working out where Javscript stops and the DOM begins is very difficult.  It is something that I struggle with regularly.  Try this:

    function utilGetXmlAttribute( node, sAttrib )
    {
     return node.getAttribute( sAttrib );
    }

    Is getAttribute a DOM function or is it a function defined in a class somewhere else in the Javascript source?  Maybe it's both.  If the thing that calls this already has the node, then why doesn't it call getAttribute on the node?

     



  • @Shondoit said:

    @Tacroy said:

    TRWTF is the old idiom that 0 is false, and all other things are true. Semantically, it just makes no sense - if you have zero apples, that doesn't mean that you have false apples, and if you have 10 apples, that doesn't mean you have true apples!


    It's a perfectly sane metaphor in my opinion.

    If you have zero apples, you don't have apples.
    If you have more than one, you do.

    Don't, do => false, true

    Arg you beat me to it, instead of asking how many apples, your now asking do you have any apples, and 0 -> false, i have no apples; 10 -> true; yes i have apples.

     

    @Tacroy said:

    @Xyro said:

    I guess you're good for Java, then.  Only booleans are booleans.  (Well, Booleans are too with unboxing.)

    IMO, this is annoying.  I wish null would evaluate to false, then I could just write <font face="Lucida Console" size="2">if (object) {...}</font> like in C rather than <font face="Lucida Console" size="2">if (object != null) {...}</font>.  In (most implementations of) C, it's obvious: if the object is null, then its address is zero, which evaluates to false.

    Coercion is about convenience.  If it's not convenient to you, then do it the long way.

     

    But that's exactly what I meant about the idiom being semantically confused - null is neither false nor zero, it is null. 

    For
    example: let's say you had a language with nullable primitives, and
    null is the default value of a primitive (this could be C or C++, in
    fact). You declare <font face="Lucida Console" size="2">int x = 0;</font> and <font face="Lucida Console" size="2">int y;</font>

    In your model, <font face="Lucida Console" size="2">(x == y) </font>is true - but it shouldn't be! <font face="Lucida Console" size="2">x</font> is known, and it's known to be zero; <font face="Lucida Console" size="2">y</font>, on the other hand, is unknown. <font face="Lucida Console" size="2">x</font> simply should not be equal to <font face="Lucida Console" size="2">y</font>.
    And yet C and C++ say it is - they say "a value known to be zero is
    equivalent to an unknown value", which is, as I said, semantically
    nonsensical

    I can't quite tell if your an idiot or a troll, so ill assume your just dumb.  According to C++ (and C),  the statment (x == y) is also undefined, most of the time it will evaluate to false, only in debug, and randomly, could it evaluate to true. This is only due to the fact that most implementations of the debug CRT are going to zero out your memory (with new/malloc() extra memory gets allocated, and filled with sentinal values to detect buffer overruns). In release mode the CRT is not going to do any of its debug behaviors and Y will have whatever value happened to be at that memory location. 

    Oh C & C++ do not have nullable primatives, you would have to create these by boxing the primitive into a class, and using pointers to refer to them so that you could have a null pointer. C# has nullable primatives, but your example is still wrong, even if you had int? y; instead.



  • @Qwerty said:

    Working out where Javscript stops and the DOM begins is very difficult.  It is something that I struggle with regularly.

    Really? Pro-tip: all the stuff that doesn't suck shit is JavaScript. The rest is DOM.

    More seriously, if you look at the ECMA spec, you'll see JS is actually pretty damned sparse. It defines the Math object. And... that's about it really. Since it's designed to be embedded, it doesn't have any kind of library associated with it, and virtually everything you do in a browser is DOM.

    @Qwerty said:

    Try this:

    function utilGetXmlAttribute( node, sAttrib )
    {
     return node.getAttribute( sAttrib );
    }

    Is getAttribute a DOM function or is it a function defined in a class somewhere else in the Javascript source?  Maybe it's both.  If the thing that calls this already has the node, then why doesn't it call getAttribute on the node?

    It was probably written for some perceived compatibility purpose, like IE or Netscape used to have a different syntax 10 years ago. That's all I can imagine... you're right, if you have the DOM object, just call getAttribute on it yourself. And why is XML in the name?

    This could also be useful if you have code that calls getAttribute a *lot*, and you run it through a shrinker/obfuscator. In that case, you'd save a lot of disk space. (getAttribute can't be minimized, but your function name can.)



  • @ekolis said:

    You'd think that a dynamically typed language would treat "false" as false to avoid these kinds of headaches... or am I the WTF

    You are 1ly the real WTF. You make the 0 assumption that everything should be strings because you're dealing with HTML, but you're writing Javascript, not HTML.



  • @esoterik said:

    Oh C & C++ do not have nullable primatives, you would have to create these by boxing the primitive into a class, and using pointers to refer to them so that you could have a null pointer. C# has nullable primatives, but your example is still wrong, even if you had int? y; instead.

     

    Err... I'll admit that it's been a while since I did anything esoteric with C or C++, but I was under the impression that in those languages <font face="Lucida Console" size="2">null == 0</font>. You can set any primitive <font face="Lucida Console" size="2">x</font> such that <font face="Lucida Console" size="2"> (x == 0)</font> is true, and therefore <font face="Lucida Console" size="2"> (x == null)</font> is true. Thus, you can null any primitive - that is, set it equal to null. Am I mistaken?

    Also I thought that the newer versions of C/C++ always zero out whatever variables you create; I remember making a silly joke program when I was a kid that woud ask you for two numbers and then just output the contents of an uninitialized variable when I was a kid, but I thought that sort of thing wouldn't work nowadays.

     

    @DaveK said:

    Well, no.  But it does mean that if you have zero apples, it is
    false that you have apples, and if you have 10 apples, it is true that
    you have apples.  You're just putting the words in the wrong order.

    Yes, I'll agree that that works - but it does change what <font face="Lucida Console" size="2">if</font> means, doesn't it? If you don't use that meaning, <font face="Lucida Console" size="2">if</font> means "is this true"; now <font face="Lucida Console" size="2">if</font> means "is this true" and also "is this not equal to zero" - so we're back at things being semantically confused.



  • @Tacroy said:

    Err... I'll admit that it's been a while since I did anything esoteric with C or C++, but I was under the impression that in those languages <FONT size=2 face="Lucida Console">null == 0</FONT>. You can set any primitive <FONT size=2 face="Lucida Console">x</FONT> such that <FONT size=2 face="Lucida Console">(x == 0)</FONT> is true, and therefore <FONT size=2 face="Lucida Console">(x == null)</FONT> is true. Thus, you can null any primitive - that is, set it equal to null. Am I mistaken?

    Null is defined as zero. And you can compare certain primitives to null, which is exactly the same as comparing them to zero, except more confusing.

     @Tacroy said:

    Also I thought that the newer versions of C/C++ always zero out whatever variables you create;

    I hope you don't ever write another program.



  • @Tacroy said:

    @esoterik said:

    Oh C & C++ do not have nullable primatives, you would have to create these by boxing the primitive into a class, and using pointers to refer to them so that you could have a null pointer. C# has nullable primatives, but your example is still wrong, even if you had int? y; instead.

     

    Err... I'll admit that it's been a while since I did anything esoteric with C or C++, but I was under the impression that in those languages <font face="Lucida Console" size="2">null == 0</font>. You can set any primitive <font face="Lucida Console" size="2">x</font> such that <font face="Lucida Console" size="2"> (x == 0)</font> is true, and therefore <font face="Lucida Console" size="2"> (x == null)</font> is true. Thus, you can null any primitive - that is, set it equal to null. Am I mistaken?

    I guess it comes down to semantics; i.e. what do we really mean when we say null. Primitives are
    not nullable since 0 is a valid value for primitives; pointers however can be nulled, since 0 is dissallowed as vallid address (IIRC the 'bootstrap' rom is located there). In C & C++ null is only 'defined' for pointers, and is defined by convention. (presumably if the another architecture bootstrapped near the end of the memory address space, that value may have been used for null, as 0 suddenly became vallid (infact the XT/AT switch on really really old Keyboards, actually did switch where the 'bootstrap' rom got mapped into the address space!))

     C# has a null keyword, C++/CLI has a nullptr keyword. In C++/CLI 0 != nullptr. 

    @Tacroy said:

    Also I thought that the newer versions of C/C++ always zero out whatever variables you create; I remember making a silly joke program when I was a kid that woud ask you for two numbers and then just output the contents of an uninitialized variable when I was a kid, but I thought that sort of thing wouldn't work nowadays.

    IIRC uninitialized variables are undefined, which really means that the compiler or CRT implementation has latitude on what to actually do, so depending on your tools, the result may vary. VC6/7/8/9 & their corresponding MSCRTs don't do anything extra in release, but does alot in debug. I don't know if VC10 or the corresponding MSCRT changed this behavior or not. I have no idea what GCC and the linux CRT does.

    C# (actually the CLR) on the other hand, defines all uninitalized varibles as initalized to 0; which sholud be distinct from the null keyword.

     

    @Tacroy said:

    @DaveK said:

    Well, no.  But it does mean that if you have zero apples, it is
    false that you have apples, and if you have 10 apples, it is true that
    you have apples.  You're just putting the words in the wrong order.

    Yes, I'll agree that that works - but it does change what <font face="Lucida Console" size="2">if</font> means, doesn't it? If you don't use that meaning, <font face="Lucida Console" size="2">if</font> means "is this true"; now <font face="Lucida Console" size="2">if</font> means "is this true" and also "is this not equal to zero" - so we're back at things being semantically confused.

     

    I suspect the confusion comes down to how one would translate between english questions and logic (i.e. code).

    "do you have any apples?" if(apples) 

    "do you have more than X apples?" if(apples > X)

    nb. the above are all boolean questions; non boolean questions can't be put into if form e.x. "how many apples do you have" would either be GetApples(); or answer = apples.

    So no it doesn't change what if means, 'if' is a logical test, it cannot know anything about semantics it only operates on boolean conditions. the meaning a human puts on a boolean conditon is completly seperate from the condition itself.

     



  • Javascript apparently thinks that the string "false" is true for purposes of boolean logic

    How would treating the string "false" as boolean false make any sense? If you had some code like this:

    var test = prompt('Enter something');
    if (test)
    {
    	alert('You entered: ' + test);
    }
    else
    {
    	alert('You did not enter anything');
    }

    and used your logic, it would fall into the else branch if the user entered the word "false" into the prompt (which really makes no sense, as strings are meant to be literal).



  •  Yes, check 1 up to the YATRWTF count. ('You Are', in case there are any text-brain-dead ones here)

     The correct response to ("false" == false) is ILLEGAL COMPARISON BETWEEN BOOLEAN AND STRING LITTERAL.

     



  • @Faxmachinen said:

     @Tacroy said:

    Also I thought that the newer versions of C/C++ always zero out whatever variables you create;

    I hope you don't ever write another program.

    I'll second that, because that assumption will work when you're debugging but when you do a release build... *BOOM!*



  • @Daniel15 said:

    Javascript apparently thinks that the string "false" is true for purposes of boolean logic

    How would treating the string "false" as boolean false make any sense? If you had some code like this:

    var test = prompt('Enter something');
    if (test)
    {
    	alert('You entered: ' + test);
    }
    else
    {
    	alert('You did not enter anything');
    }

    and used your logic, it would fall into the else branch if the user entered the word "false" into the prompt (which really makes no sense, as strings are meant to be literal).

    That's a good illustration of the problem, but look at what boolean false actually means. This is a practical problem, not a matter of principle or logic. Different languages handle it differently. Certainly, "false" being boolean true makes no more sense, so you're just swapping one problem for another. The only strictly correct thing to do is not to allow comparisons of strings and booleans. The alternative is to decide which way round will be the most useful in most situations, and define in your language how you will treat the comparison.



  • @Qwerty said:

    Assigning "false" to an HTML boolean attribute causes the DOM to parse the string and store the result as false.  Depending on the attribute, "none", "default", "0" will have the same effect.  Assigning "false" to any extendo properties that you created will pass "false" to any setter function that you've created or it will just store the string.  The DOM lets you do stuff like myHTMLElement.style.height="12px" which will set the height of the object to 12 pixels and x=myHTMLElement.style.height will return the number 12.

    Actually, the DOM coerces everything into string form.

    e = document.createElement('div');
    e.style.width = "50%";
    alert(e.style.width); //50%

    e.style.width = 1234;
    alert(e.style.width); //1234px (and a css error)
    alert(typeof e.style.width); //string

    But, thanks for trying.

    @davedavenotdavemaybedave said:

    @Daniel15 said:
    Javascript apparently thinks that the string "false" is true for purposes of boolean logic

    How would treating the string "false" as boolean false make any sense? If you had some code like this:

    var test = prompt('Enter something');
    if (test)
    {
    	alert('You entered: ' + test);
    }
    else
    {
    	alert('You did not enter anything');
    }

    and used your logic, it would fall into the else branch if the user entered the word "false" into the prompt (which really makes no sense, as strings are meant to be literal).

    That's a good illustration of the problem, but look at what boolean false actually means. This is a practical problem, not a matter of principle or logic. Different languages handle it differently. Certainly, "false" being boolean true makes no more sense, so you're just swapping one problem for another. The only strictly correct thing to do is not to allow comparisons of strings and booleans. The alternative is to decide which way round will be the most useful in most situations, and define in your language how you will treat the comparison.

    Why can't you compare them? It's 100% accurate to say that "false" != false. You can't relate them (<, >, etc), but comparing them is easy.



  • @pkmnfrk said:

    Why can't you compare them? It's 100% accurate to say that "false" != false. You can't relate them (<, >, etc), but comparing them is easy.
     

    I was always lead to believe that > and < (among others) are comparison operators.  You're comparing the thing on the left hand side of the operator to the thing on the right hand side and returning true or false.



  • @Tacroy said:

    Err... I'll admit that it's been a while since I did anything esoteric with C or C++, but I was under the impression that in those languages <font size="2" face="Lucida Console">null == 0</font>.
    You perhaps meant NULL. And it's always a #define, not a const variable.
    You can set any primitive <font size="2" face="Lucida Console">x</font> such that <font size="2" face="Lucida Console"> (x == 0)</font> is true, and therefore <font size="2" face="Lucida Console"> (x == null)</font> is true. Thus, you can null any primitive - that is, set it equal to null. Am I mistaken?
    0 in a pointer context is not necessarily equivalent to 0 in any other context. Since a 0 pointer is to indicate that a pointer points to nothing, the internal representation of such a pointer, that is guaranteed not to point to any valid object, may not be all bits zero. Thus the following:

    int* pointer = 0;
    int integer = 0;
    if (pointer != integer){
    printf("null pointer not all bits zero\n");
    }

    May validly print something. For most it's unlikely to, but the provision is there to allow it. In addition the representation of a 0 pointer for one type may be different to that for a different type:

    int* int_pointer = 0;
    float* float_pointer = 0;
    if (int_pointer != float_pointer){
    printf("different types have different 0 representations\n");
    }



    For the avoidance of confusion, a pointer that has been set to 0 will always subsequently compare equal to a literal 0 in code, or something that after pre-processing ends up as a 0 (until, of course, changed to point elsewhere.) What it might not compare equal to is a variable (pointer or otherwise) that has been separately set to 0.


    @Tacroy said:
    Also I thought that the newer versions of C/C++ always zero out whatever variables you create;
    Only those variables of types that are built-in (int, char, float etc.) that exist for the lifetime of the program (globals and statics.) No guarantee is made about the value of automatic or dynamically (using malloc()/new) allocated variables of built-in types.



    calloc() of course returns zero'd memory, which for all but pointer have predictable and portable results. Pointers not so much.



    The behaviour of user defined classes depends entirely on the behaviour of the constructor, and basically depends (recursively) on what, if any, initialisation it performs on its components.



    Of course, a particular compiler with certain switches may helpfully zero out all auto variables for you, but it's not portable, you shouldn't rely on it, and it's likely to cause your code to appear on here when someone else doesn't use those switches or that compiler on your code.



  • @Qwerty said:

    Assigning "false" to an HTML boolean attribute causes the DOM to parse the string and store the result as false.
     

    No. getAttribute() always returns a string.

    @Qwerty said:

    The DOM lets you do stuff like myHTMLElement.style.height="12px" which will set the height of the object to 12 pixels

    Yes, because the string "12px" is forwarded to the CSS parser, which turns it into the equivalent of { value: 12, unit: 'px' } which is then forwarded to the layout engine.

    @Qwerty said:

    x=myHTMLElement.style.height will return the number 12.

    No. It returns "12px".

    I must conclude that you've never worked with the style object.

     



  • @esoterik said:

    I can't quite tell if your an idiot or a troll, so ill assume your just dumb. 
     

    Calling someone dumb, a troll and/or and idiot, three posts in, without being able to spell "I'll" or "you're". Good job.



  • @davedavenotdavemaybedave said:

    This is a practical problem, not a matter of principle or logic. Different languages handle it differently. Certainly, "false" being boolean true makes no more sense, so you're just swapping one problem for another. The only strictly correct thing to do is not to allow comparisons of strings and booleans.
     

    I principally disagree that dynamically treating "false" as false makes sense.

    I agree that you shouldn't be comparing strings and bools directly in the first place.

    I might agree that the language could have a method of prohibiting it.

    @davedavenotdavemaybedave said:

    The alternative is to decide which way round will be the most useful in most situations, and define in your language how you will treat the comparison.

    There's a tradeoff in that decision, between formally predictable vs. handy. In this particular case, I prefer it being predictable, because if it were handy, you would be comparing bools to strings, and we both agree that this shouldn't happen.

    But perhaps we can agree to disagree on this one :)

     



  • @robbak said:

     Yes, check 1 up to the YATRWTF count. ('You Are', in case there are any text-brain-dead ones here)

     The correct response to ("false" == false) is ILLEGAL COMPARISON BETWEEN BOOLEAN AND STRING LITTERAL.

     

     

    AMEN TO THAT! All I'm saying is, if Javascript is going to be so "friendly" to let me compare false to "false", it ought to at least give me a "friendly" answer! Call me a statically typed language Nazi or whatever, but if you're going to screw around with dynamic types, they sure as hell better work as the end user would expect... and since there are apparently so many "expectations" as to said behavior, maybe it's best to not even HAVE dynamic types!

     



  • @ekolis said:

    Call me a statically typed language Nazi or whatever, but if you're going to screw around with dynamic types, they sure as hell better work as the end user would expect... and since there are apparently so many "expectations" as to said behavior, maybe it's best to not even HAVE dynamic types!

    Then don't use the coercions!!


    var str = "false";
    if (str == false || str == "false" || str == "faux" || str == "That's a negative, chief.") {
        return "Yup, it's false as I expect."
    }



  • @ekolis said:

    but if you're going to screw around with dynamic types, they sure as hell better work as the end user would expect...
     

    They do.

    Did you read this thread? Do you have any questions?



  • @dhromed said:

    @davedavenotdavemaybedave said:

    This is a practical problem, not a matter of principle or logic. Different languages handle it differently. Certainly, "false" being boolean true makes no more sense, so you're just swapping one problem for another. The only strictly correct thing to do is not to allow comparisons of strings and booleans.
     

    I principally disagree that dynamically treating "false" as false makes sense.

    I agree that you shouldn't be comparing strings and bools directly in the first place.

    I might agree that the language could have a method of prohibiting it.

    @davedavenotdavemaybedave said:

    The alternative is to decide which way round will be the most useful in most situations, and define in your language how you will treat the comparison.

    There's a tradeoff in that decision, between formally predictable vs. handy. In this particular case, I prefer it being predictable, because if it were handy, you would be comparing bools to strings, and we both agree that this shouldn't happen.

    But perhaps we can agree to disagree on this one :)

    I think to a large extent we're not disagreeing. From my perspective, though, you're not giving enough weight to the totally abstract nature of a boolean variable, and the resultant necessity for kludging whenever and however you de-abstract it to make it useful. It always has to be a compromise of some nature, so perhaps I didn't go far enough last night. By bringing a boolean into the real world, you compromise it to start with. Everything else is just about the best way to handle those compromises. Unless you have a computer that, instead of using high and low voltages to indicate 1/0, can deal in abstract logical concepts such as true and false, everything is an arbitrary interpretation.



  • @dhromed said:

    @ekolis said:

    but if you're going to screw around with dynamic types, they sure as hell better work as the end user would expect...
     

    They do.

    Did you read this thread? Do you have any questions?

    I do. Ekolis, are you originally a VBA (Access) programmer?

    @VBA said:

    foo = "true": if foo = true then print "Yes" else print "No"
    Yes

    foo = "false": if foo = true then print "Yes" else print "No"
    No

     

     



  • @ekolis said:

    @robbak said:

     Yes, check 1 up to the YATRWTF count. ('You Are', in case there are any text-brain-dead ones here)

     The correct response to ("false" == false) is ILLEGAL COMPARISON BETWEEN BOOLEAN AND STRING LITTERAL.

     

     

    AMEN TO THAT! All I'm saying is, if Javascript is going to be so "friendly" to let me compare false to "false", it ought to at least give me a "friendly" answer! Call me a statically typed language Nazi or whatever, but if you're going to screw around with dynamic types, they sure as hell better work as the end user would expect... and since there are apparently so many "expectations" as to said behavior, maybe it's best to not even HAVE dynamic types!

     

    Or maybe it's best to not have "expectations", and just learn the fricken language?



  • @b-redeker said:

    are you originally a VBA (Access) programmer?

    I thought I posted that was where I was starting from, but it seems to have vanished into the ether. It's just another way of handling it - not better or worse in general, and no more or less logically correct. Due to the way the whole language works, I don't think it presents a problem in practice, because whilst it's easy to demonstrate the behaviour, it's not something you'd be likely to do. Why would you test a string to see if it was boolean true or false? Only reason I can think of would be as a horrible hack relying on the odd result comparing booleans to strings gives, instead of checking the contents properly.@b-redeker said:

    @VBA said:

    foo = "true": if foo = true then print "Yes" else print "No"
    Yes

    foo = "false": if foo = true then print "Yes" else print "No"
    No

     

    You should be using [if (isnull(foo)=true)] instead of [if foo= true] - or whatever check it is you actually want to do.



  • @davedavenotdavemaybedave said:

    You should be using [if (isnull(foo)=true)] instead of [if foo= true] - or whatever check it is you actually want to do.

    I didn't want to do a check; I wanted to show that variants in VBA/VBscript will take a string and treat it as a boolean, which was I think what the OP expected JavaScript to do.



  • @b-redeker said:

    @davedavenotdavemaybedave said:

    You should be using [if (isnull(foo)=true)] instead of [if foo= true] - or whatever check it is you actually want to do.

    I didn't want to do a check; I wanted to show that variants in VBA/VBscript will take a string and treat it as a boolean, which was I think what the OP expected JavaScript to do.

    Sorry, on re-reading it seems I slightly misunderstood your original post. Anyway, it still served as a good starting point for my explication. Can you think of any good reason to do it that isn't just to prove the concept?



  • @davedavenotdavemaybedave said:

    Can you think of any good reason to do it that isn't just to prove the concept?

    Keep in mind that VBA is not really for developers, but more for a power-user. So we don't bother them with "hard" concepts, like static typing etc; let the interpreter figure out what they want to do. Oh, you're taking sth that looks like a number and add sth else to it? well, good for you. You have a number and now you do a string operation on it? Yes can do too.

    @VBA said:

    foo = "1": print foo + 1 & "hahaha (maniacal laughter)"
    2hahaha (maniacal laughter)

    foo = "1": print foo + 1 + "hahaha (maniacal laughter)"
    Run-time error 13: type mismatch

    I'm not saying that's actually a GOOD reason (I don't really want to get into the whole static/weak/dynamic typing debate) but I think at least that's the philosophy.



  • @b-redeker said:

    Oh, you're taking sth that looks like a number and add sth else to it?

    What is STH? You keep using this acronym with the assumption we all know it... Season Ticket Holder? So The Heck?



  • For what is worth, I think Lua gets it right.

    Only <font face="courier new,courier">nil</font> and <font face="courier new,courier">false</font> are false, every thing else is considered true, period. Any two values of different types are considered not equal, no exceptions.

    If you want to compare apples to oranges, either coerce the apple to an orange or the orange to an apple (or both to peaches).



  • @blakeyrat said:

    What is STH? You keep using this acronym with the assumption we all know it... Season Ticket Holder? So The Heck?
    I think it means something.

     

     

     

    But what could it be?



  • @Spectre said:

    @ekolis said:

    @robbak said:

     Yes, check 1 up to the YATRWTF count. ('You Are', in case there are any text-brain-dead ones here)

     The correct response to ("false" == false) is ILLEGAL COMPARISON BETWEEN BOOLEAN AND STRING LITTERAL.

     

     

    AMEN TO THAT! All I'm saying is, if Javascript is going to be so "friendly" to let me compare false to "false", it ought to at least give me a "friendly" answer! Call me a statically typed language Nazi or whatever, but if you're going to screw around with dynamic types, they sure as hell better work as the end user would expect... and since there are apparently so many "expectations" as to said behavior, maybe it's best to not even HAVE dynamic types!

     

    Or maybe it's best to not have "expectations", and just learn the fricken language?



    I'm going to assume you wrote 'expectations' between quotes on purpose, so this reply is in general.



    It's not wrong to have expectations. Languages should abide by expectations (keyword: should, not must)

    Same goes for programs themselves; if you press Ctrl+X it shouldn't Exit.

    Nor should the most left item in a menu bar be Exit (Yes, I've seen the last one in the wild)



    There's nothing wrong with having expectations. What is wrong is having ungrounded expectations.

    Just because you think something should behave a certain way doesn't mean it must.

    There's a perfectly sane reason for programming language not to evaluate the string "false" as being false.

    There are casts and conversions for that purpose.



  • @Zecc said:

    @blakeyrat said:

    What is STH? You keep using this acronym with the assumption we all know it... Season Ticket Holder? So The Heck?
    I think it means something.

     

     

     

    But what could it be?

    Third base!



  • I understand the difference between strong and weak typing - and explicitly declaring it in VBA where necessary* - but that wasn't really what I was asking. I was just trying to think of a scenario in which you might use "false"=true as a test for any reason other than as a short-cut exploiting a trick of the language. The main effect of the string/boolean behaviour in VBA is really just that "false" and FALSE are alternate ways of referring to the boolean.



  • @Faxmachinen said:

    @Tacroy said:

    Err... I'll admit that it's been a while since I did anything esoteric with C or C++, but I was under the impression that in those languages <font size="2" face="Lucida Console">null == 0</font>. You can set any primitive <font size="2" face="Lucida Console">x</font> such that <font size="2" face="Lucida Console">(x == 0)</font> is true, and therefore <font size="2" face="Lucida Console">(x == null)</font> is true. Thus, you can null any primitive - that is, set it equal to null. Am I mistaken?

    Null is defined as zero. And you can compare certain primitives to null, which is exactly the same as comparing them to zero, except more confusing.

     

    @esoterik said:

    In C & C++ null is only 'defined' for pointers, and is defined by convention. (presumably if the another architecture bootstrapped near the end of the memory address space, that value may have been used for null, as 0 suddenly became vallid (infact the XT/AT switch on really really old Keyboards, actually did switch where the 'bootstrap' rom got mapped into the address space!))

    C# has a null keyword, C++/CLI has a nullptr keyword. In C++/CLI 0 != nullptr.

    NULL in C++ is nothing more than 0 (the size depending on the size of a adress), thus it is totally valid to compare it to primitives since they can be 0 (that is, zero bytes, e.g. 0.0F or 0.0D != NULL).

    This is exactly why C++x0 introduces the "nullptr" keyword as a replacement for "null". And it can't be compared with primites and only returns true if a pointer/reference is NULL. They did choose to keep the origional meaning of null because it could break old code.

    Also NULL should not equal zero, as "undefined" or "nonexistent" is something different from "zero" or 0. SQL handles it quite nicely.


Log in to reply
 

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