Yikes. I understand that companies use these posts as a form of advertising, but seeing your "application security specialist" struggling with such a basic expression gives me pause.
I was working with this guy - he always tried to prove that everything is possible wasting time. He ALWAYS over-complicated simple things. He was horrible to work with and everyone hated him.
Not to say you are just like him etc. but this post reminded me of him because it was probably exactly what he would do.
I think it's worth pointing out the article writer recognizes this is a distraction. In the comic, nerd sniping causes people to forget they're crossing the street and they wind up being hit by a car, which is a pretty serious distraction from the task at hand.
And this is why Javascript can be such an awful language. Leaving off a single equals has such a profound effect, often without a new coder even realizing it while reading the code.
Imagine what happens to your code when someone tries to write a function for its side effects similar to the example seen in the blog post. Then releases it in production for it to break in six months with a feature change.
> And this is why Javascript can be such an awful language. Leaving off a single equals has such a profound effect, often without a new coder even realizing it while reading the code.
You get used to this as you get seasoned with javascript. Every language has it's quirks. The human brain is remarkably adaptable to using tools & dealing with intricacies. I personally utilize & appreciate the difference between == and === to reduce complexity in the code. I assume the reader also understands such differences.
I also find automated testing, logging, a module system like commonjs, and linters to be useful when programming in javascript. Once these are in place, systems written in javascript are remarkably maintainable & scale with complexity.
At the end of the article, it is demonstrated that this can happen even with strict equality by overriding the getters. Any language with getter/setter support can do this. Operator overloading can be used for even nefarious ends.
The point is that side effects in code are dangerous, and can be used to mislead a reader.
If this happens, it is not the fault of JavaScript. Anyone who writes code like that for purposes other than demonstration or learning is a moron.
There are ways to do stupid things in any language. I don't think anyone would ever tell you that redefining an integer as an object and overwriting its prototypes is an acceptable way to solve...any? problem.
I'm glad that you said, "can be" because language flexibility is a two way street. You can abuse dynamic typing for good and for evil. I, personally, don't think that's a case for declaring it not worthwhile, rather it reenforces investing the time to properly understand the language.
Fortunately, at this stage, we get the best of both worlds with syntax validators and linters. Abuse as appropriate (whatever that means) and be warned about the rest.
The differences between programming syntax and elementary/Boolean algebra are very awkward to understand clearly and deal with correctly. We clearly understand mathematical algebra to work one way, and we naturally assume programming algebra works the same way, which it doesn't at all.
Here, the antagonist says that b can't be 1 and 2 at the same time, which would be self-evident in mathematical algebra, but turns out to be quite irrelevant to Javascript and to programming paradigms generally (since two statements will never be checked simultaneously).
This difference in how syntax is understood actually presents a barrier to programming for modestly trained mathematicians, who would otherwise be expected to excel.
>This difference in how syntax is understood actually presents a barrier to programming for modestly trained mathematicians, who would otherwise be expected to excel.
Although this is true in general that syntax can be a barrier to entry, the article provides a particularly poor example. If anything, the article demonstrates how mathematical training is good preparation for many pitfalls of programming.
Mathematicians are used to working with various equivalence relations, even in the same context. So if a modestly trained mathematician saw == and ===, she would immediately ask "what is the difference between these two ER's?".
And then when she finds out the essential difference is that you can override ==, it would be clear that all bets are off.
I can't imagine any mathematician taking more than a few minutes and a google search -- let alone 11 days -- to figure out this loophole.
Umm , you missed a key point here. The first comparison is == while the second one is ===. These 2 are different. The == checks equivalent. Mathematically speaking he should have used === in both places.
These things are more of quirks of javascript than anything else. The post did nothing but made me hate javascript. Try doing the same in Java !
> Here, the antagonist says that b can't be 1 and 2 at the same time, which would be self-evident in mathematical algebra, but turns out to be quite irrelevant to Javascript and to programming paradigms generally (since two statements will never be checked simultaneously).
This isn't really a problem if b is enforced to be immutable.
There was a child went forth every day;
And the first object he look’d upon, that object he became;
And that object became part of him for the day, or a certain part of the day, or for many years, or stretching cycles of years.
It's especially bad if you'd really rather be doing something other than what you're currently doing.
Call me nitpicky, but it always bugs me when someone references some content, but doesn't link to it. Specifically the XKCD and Stackoverflow links. Link to the comic and question specifically, rather than making me go hunt for that content.
Might not be Java but still interesting, it made me think of one of my favorite little quirks in C++:
#include <cmath>
//Floating point model: Strict:Precise:Fast
//Will code execute
float a = nanf("");
if (a == a)//S:No P:No F:Yes
(do something);
if (a != a)//S:Yes P:Yes F:No
(do something);
if (a < 0.f || a > 2.f)//S:No P:No F:Yes
(do something);
if (isnan(a))//S:Yes P:Yes F:Yes
(do something);
NaN's (Not A Number) can propagate a long way through your code, possibly reaching places where they cause real problems. When dealing with input, especially networking, one should always check for NaN's. Basically the rule with NaN's is: The comparison always returns false if any NaN is involved. But as you can see; specifying the fast model throws that out of the window. (Code was otherwise unoptimized.)
In the third statement an otherwise fine check is done to make sure the value in a is sane, it doesn't get changed but its certainly not what you'd want it to be.
Whole lots of fun can be had when serving this to game servers. :D
I think there was a more general question here that was missed: can a == x && a == y ever be true for any arbitrary values of a, x, and y, where x != y.
From a logical point of view, no, this can never be true. I would suspect this can never be true in javascript, and could only be made true in a language where you can override == to always return true.
I think when most developers use the word "never", what they really mean is "never (within the current context)". This makes conversations a lot simpler. Imagine how difficult conversations would be if you always had to qualify never. "This can never be true (assuming a weird valueOf method hasn't been defined and assuming I didn't modify the javascript interpreter to always return true for == and assuming ...)".
I think there are a few cases of non-transitive equalities in JavaScript, specifically around falsey values. Part of it also has to do with whether x is the right-side input or the left-side input, because that changes type coercion rules.
Transitivity of equality can also never be relied upon when dealing with Floating Point numbers. This is correct and unavoidable behavior, but still surprising to many developers.
a = {}
a.valueOf = function() {
var caller = arguments.callee.caller.toString();
//parse the caller function, and return
//different values based on what comparison is being made.
}
But I think this is even worse than the getter on the global object.
In [3]:
class TheObjectThatIsEqualToAnything(object):
def __eq__(self, other):
return True
In [4]:
x = TheObjectThatIsEqualToAnything()
In [6]:
x == 3 and x == 5
Out [6]:
True
It's not necessarily abuse. I once had to code a dummy object that supported all arithmetic operations with normal numbers and had a special comparison logic that it is never equal to itself. Then you could test if something is a number or a dummy object by comparing it to itself.
I think the answer to "can something be fuzzy equal to one value and strictly equal to another in JS?" has an easy answer that doesn't take much effort to find. This might be cooler in another language, though.
This is what I was gonna say! I don't know much JS, but after @sgdesign 's recent primer, the answer to the first two conditions seems obvious, b=="2" and b===2. Herpderp is just a cop out, since you could have infinite other variables that b equals, if you set the value to the same thing!
newtype X = X (IORef Int)
instance Num X where
fromInteger = X . unsafePerformIO . newIORef . fromInteger
instance Eq X where
(X a) == (X b) = unsafePerformIO $ do
x <- readIORef a
y <- readIORef b
writeIORef a $ x+1
return $ x == y
ghci> a <- fmap X $ newIORef 1
ghci> a == 1 && a == 2
True
vernie|12 years ago
romanovcode|12 years ago
Not to say you are just like him etc. but this post reminded me of him because it was probably exactly what he would do.
kbenson|12 years ago
e28eta|12 years ago
mncolinlee|12 years ago
Imagine what happens to your code when someone tries to write a function for its side effects similar to the example seen in the blog post. Then releases it in production for it to break in six months with a feature change.
briantakita|12 years ago
You get used to this as you get seasoned with javascript. Every language has it's quirks. The human brain is remarkably adaptable to using tools & dealing with intricacies. I personally utilize & appreciate the difference between == and === to reduce complexity in the code. I assume the reader also understands such differences.
I also find automated testing, logging, a module system like commonjs, and linters to be useful when programming in javascript. Once these are in place, systems written in javascript are remarkably maintainable & scale with complexity.
maxbucknell|12 years ago
The point is that side effects in code are dangerous, and can be used to mislead a reader.
If this happens, it is not the fault of JavaScript. Anyone who writes code like that for purposes other than demonstration or learning is a moron.
pmelendez|12 years ago
To be fair, this is breaking Javascript and that is something you could do in other languages, for instance here is a similar version for C++:
http://pastebin.com/seySfpku
rmrfrmrf|12 years ago
sisk|12 years ago
Fortunately, at this stage, we get the best of both worlds with syntax validators and linters. Abuse as appropriate (whatever that means) and be warned about the rest.
MatthewWilkes|12 years ago
cruise02|12 years ago
The language used can hardly be blamed for that.
marknutter|12 years ago
ronaldx|12 years ago
Here, the antagonist says that b can't be 1 and 2 at the same time, which would be self-evident in mathematical algebra, but turns out to be quite irrelevant to Javascript and to programming paradigms generally (since two statements will never be checked simultaneously).
This difference in how syntax is understood actually presents a barrier to programming for modestly trained mathematicians, who would otherwise be expected to excel.
nmrm|12 years ago
Although this is true in general that syntax can be a barrier to entry, the article provides a particularly poor example. If anything, the article demonstrates how mathematical training is good preparation for many pitfalls of programming.
Mathematicians are used to working with various equivalence relations, even in the same context. So if a modestly trained mathematician saw == and ===, she would immediately ask "what is the difference between these two ER's?".
And then when she finds out the essential difference is that you can override ==, it would be clear that all bets are off.
I can't imagine any mathematician taking more than a few minutes and a google search -- let alone 11 days -- to figure out this loophole.
minusSeven|12 years ago
These things are more of quirks of javascript than anything else. The post did nothing but made me hate javascript. Try doing the same in Java !
Dewie|12 years ago
This isn't really a problem if b is enforced to be immutable.
gyepi|12 years ago
tatalegma|12 years ago
Couldn't you simply do this?:
if ((a==='80'||b==='443') && http===false) { ... }
cowsandmilk|12 years ago
if (a==='80' || (b==='443'&&http===false)) {...}
level|12 years ago
alistairjcbrown|12 years ago
You're comparing a literal number with an object, which are not the same type.
scjody|12 years ago
You probably haven't. But a less experienced programmer has learned why you should always use ===.
adamman|12 years ago
tarpherder|12 years ago
In the third statement an otherwise fine check is done to make sure the value in a is sane, it doesn't get changed but its certainly not what you'd want it to be.
Whole lots of fun can be had when serving this to game servers. :D
mfonda|12 years ago
From a logical point of view, no, this can never be true. I would suspect this can never be true in javascript, and could only be made true in a language where you can override == to always return true.
I think when most developers use the word "never", what they really mean is "never (within the current context)". This makes conversations a lot simpler. Imagine how difficult conversations would be if you always had to qualify never. "This can never be true (assuming a weird valueOf method hasn't been defined and assuming I didn't modify the javascript interpreter to always return true for == and assuming ...)".
lmkg|12 years ago
Aha, found one:
Transitivity of equality can also never be relied upon when dealing with Floating Point numbers. This is correct and unavoidable behavior, but still surprising to many developers.russellsprouts|12 years ago
tonyarkles|12 years ago
aaronem|12 years ago
antinitro|12 years ago
var b = {};
b.valueOf = function () {
};if (b==1 && b==2) {//success}
gkop|12 years ago
yeahbutbut|12 years ago
skrebbel|12 years ago
cwmma|12 years ago
gcr|12 years ago
Grue3|12 years ago
wambotron|12 years ago
var b = 2;
b == '2'; // true
b === 2; // true
mikeryan|12 years ago
(b == 1 && b===2 && b === herpderp)
neil_s|12 years ago
forrestthewoods|12 years ago
mathattack|12 years ago
drvortex|12 years ago
1 - 3 + 2.25 = 4 - 6 + 2.25
1^2 + 2(1)(1.5) + (1.5)^2 = (2)^2 - 2(2)(1.5) + (1.5)^2
Since a^2 - 2ab + b^2 = (a - b)^2
(1-1.5)^2 = (2-1.5)^2
1 = 2
QED.
peterkelly|12 years ago
Port the solution to Haskell
chrra|12 years ago
okasaki|12 years ago
unknown|12 years ago
[deleted]
cinitriqs|12 years ago
(everything == all && all == everything) == stardust/code
Dewie|12 years ago
> : a 2 ;
> : 2 3 ;
> a 2 =
> a 3 =
The two flags on the top of the stack are now equal.
ssdfsdf|12 years ago
poweribo|12 years ago