Re:Nerdsniping: A glimpse into a stubborn mind
by vernie on Monday April 14, 2014 @05:40PM
(#7589131)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by romanovcode on Monday April 14, 2014 @08:56AM
(#7585824)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by Orangeair on Monday April 14, 2014 @03:50PM
(#7588405)
I think the difference really lies in WHEN you do the examining. If you think to yourself, "Hey, that's cool, I'll check it out later," then there's no problem. However, when it gets to the point where you're thinking, "My code must be 110% correct! This is an immediate priority!" then maybe you should be re-evaluating your decision making process.
Re:Nerdsniping: A glimpse into a stubborn mind
by jmngomes on Monday April 14, 2014 @11:47AM
(#7586852)
I think he's referring to some people's inability to balance technical issues and product commitments (deadlines).
Focusing solely on the means and disregarding the ends is a good way to not deliver anything useful. Most times, things need to be good enough, not technically perfect...
Re:Nerdsniping: A glimpse into a stubborn mind
by spenuke on Monday April 14, 2014 @11:46AM
(#7586838)
Is it really fair to call poor code an edge case? If not for the double-equals typo, which most code reviews would fix, this wouldn't work.
I'm more interested that this team has conversations where person A asks a really simple question that should be able to be tested in 11 seconds, person B gives a patently false answer that mistakes && for ||, which is the very thing person A is asking about. Meanwhile person C goes and spends 11 days looking for a loophole and writing a blog about it.
As a person gearing up for my first web dev position, I really wonder if this is what constitutes professional Javascript development and ask myself if I shouldn't be applying to jobs already.
Re:Nerdsniping: A glimpse into a stubborn mind
by kbenson on Monday April 14, 2014 @02:29PM
(#7587913)
No, person C saw an interesting question, and decided to go on an exploratory journey to see what's possible. In any job requiring mental aptitude, you'll find natural curiosity an asset, as long as you keep it within bounds.
To be clear, anyone that's presented a question about a tool they are using that may pertain to it's use (be it efficiency or correctness) that shows zero interest in the answer (whether or not they have time to pursue an answer) is not someone I want to work with or manage, and should probably find another career, because the one they are in isn't holding their interest. Work doesn't have to be the most important thing to you, but if you don't like your job, the people around you WILL notice.
Re:Nerdsniping: A glimpse into a stubborn mind
by spenuke on Monday April 14, 2014 @03:53PM
(#7588425)
I'm not sure your second paragraph is clear, to me, at least. Person C admitted that their only contribution to the conversation was to announce that they had been nerd-sniped. Which means that they showed zero interest in the "question they were presented with", because they were sidetracked by another, more interesting (to them) problem.
Meanwhile, person A's question went unanswered. I would consider this a case of not keeping curiosity within bounds. Wouldn't you?
I agree wholeheartedly that curiosity is a great motivator, one that I would want driving all my coworkers. But as this blog presents it, the curiosity suffers from the greatest threat to curiosity, which is a lack of discipline that ensures the curious person never rises above a dilettante. I speak from first hand knowledge here - I've wasted more than my share of time doing something just for fun that benefits nobody.
If it were not the case that Person B, the implicit authority figure in the scenario, gave a totally backwards answer to Person A, OR ( || ) if it were not the case that Person C failed to alleviate the confusion of Persons A and B, then I would not see any problem with going off on a trip down pedantry lane. As it is, the whole organization looks like a gang of clowns. Nobody can answer the most basic of syntax questions, and one person even takes a faulty intuition ("b can be both 80 and 443") and follows it on a Quixotic quest into the arcana of the language spec. It's almost as though he stumbled on the real value of the quest (how evaluations of == and === are actually implemented) by sheer accident, in spite of himself. Luckily, many quests follow this pattern.
For what it's worth, I do find the discussion interesting. But it's interesting in way different than that of edge cases. Deliberately breaking something by using it in a way it was never intended to be used can be enlightening if you want to fend off would-be attackers. It exploits the system's implementation constraints. On the other hand, an edge case highlights the edges of legitimate use which the system was never designed to account for. It exploits the system's lack of comprehensiveness. The distinction is a good one, I think.
For example, consider a chair. An edge case might be a 600-pound man. The engineers didn't take this legitimate use of the chair into account when they determined the thickness of the material. That's an edge case. It's not quite the same as saying that the engineers didn't take into account that wood is flammable. This example is not the best, but I'm now well too far into my own trip down pedantic lane to spend any more time trying to improve it. :)
Re:Nerdsniping: A glimpse into a stubborn mind
by philip_roberts on Monday April 14, 2014 @04:33PM
(#7588714)
It's not made clear from my post, because I felt it was entirely irrelevant to the context of the post itself (which was merely intended as an interesting meander through the thought process and experiments my mind went through over time) but I stripped a number of comments from the screencap wherein the question was in fact answered.
Had I suspected the quality of my team, or my discipline would be under question, I would have left them in :)
Re:Nerdsniping: A glimpse into a stubborn mind
by hackinthebochs on Monday April 14, 2014 @06:18PM
(#7589267)
It's interesting because it looks at the implementation of '==' vs '===' and how this behavior can be modified at runtime. Every good "hacker" should find this interesting on some level.
Re:Nerdsniping: A glimpse into a stubborn mind
by e28eta on Monday April 14, 2014 @04:35PM
(#7588735)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by mncolinlee on Monday April 14, 2014 @10:49AM
(#7586442)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by briantakita on Monday April 14, 2014 @12:54PM
(#7587295)
> 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.
Re:Nerdsniping: A glimpse into a stubborn mind
by mncolinlee on Monday April 14, 2014 @02:27PM
(#7587893)
Nothing you said actually differs from what I said.
I spent seven years as a Perl programmer. Like Perl, a language can be extremely productive in the hands of a veteran and dangerous with a newcomer due to the unnecessary confusion it generates. At least eq and == are syntactically easier to grok than == and ===.
Re:Nerdsniping: A glimpse into a stubborn mind
by mrkipling on Tuesday April 15, 2014 @04:39AM
(#7590897)
Try JSHint instead. It catches actual problems and everything else is customisable, so you're not forced to change your coding style to fall in line with the whims of a stubborn author.
Re:Nerdsniping: A glimpse into a stubborn mind
by maxbucknell on Monday April 14, 2014 @11:15AM
(#7586612)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by mikeash on Monday April 14, 2014 @12:24PM
(#7587083)
Not all languages with getter/setter support will invoke them automatically like this.
For example, it's not possible in Java or Objective-C to make an expression of the form a == b, where a and b are plain variables, have any side effects.
Re:Nerdsniping: A glimpse into a stubborn mind
by jacalata on Tuesday April 15, 2014 @03:31AM
(#7590740)
Do you mean it is obvious to people who know objective C? I've never used the language, but its not obvious to me just from the other c-family languages I know.
Re:Nerdsniping: A glimpse into a stubborn mind
by userbinator on Tuesday April 15, 2014 @06:43AM
(#7591148)
> #define int INT
This makes it somewhat obvious that you can't change how basic types work in C++. On the other hand, JS's dynamicity makes for some interesting situations, as seen here. I wouldn't consider it "awful" but it's certainly a language with more "deep complexity" than appears at first glance.
Re:Nerdsniping: A glimpse into a stubborn mind
by mncolinlee on Monday April 14, 2014 @02:48PM
(#7588022)
Pedantry aside... are you really going to defend Javascript's core method of function handling as good design by using the C function pointer as an example?
On some level, defending JS using C is like saying you can also make a souffle by instead cooking the chicken with the egg still inside it. Both JS and its bad paradigms came from C. You don't arrive at good design by showing that other people also got it wrong.
Re:Nerdsniping: A glimpse into a stubborn mind
by pmelendez on Monday April 14, 2014 @03:00PM
(#7588089)
I think you are missing my higher point. I am not defending JS or C++ for that matter (please note that I was not using C), but the fact that giving enough time you can break most languages to do something silly, in which case I don't blame the tool but the people using it.
Re:Nerdsniping: A glimpse into a stubborn mind
by rmrfrmrf on Monday April 14, 2014 @01:32PM
(#7587550)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by sisk on Monday April 14, 2014 @11:37AM
(#7586760)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by ronaldx on Monday April 14, 2014 @08:58AM
(#7585831)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by nmrm on Monday April 14, 2014 @09:05AM
(#7585866)
>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.
Re:Nerdsniping: A glimpse into a stubborn mind
by ronaldx on Monday April 14, 2014 @04:59PM
(#7588900)
> 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?".
This perhaps illustrates my point. While you say == and === are equivalence relations (I would argue they are not), there is a wider problem.
= itself is an assignment operator and should never be considered as an equivalence relation.
But it is normal to consider = as algebraic equality for anyone who has completed high school math.
It's a great loss to intuitive understanding that we use = for assignment. If anything, considering Javascript's == and === is a net benefit as programmers are more acutely aware of the issue here.
What percentage of time spent learning to program and recovering bugs is caused by overcoming this misintuition? It's surely a lot.
Re:Nerdsniping: A glimpse into a stubborn mind
by nmrm on Monday April 14, 2014 @09:26AM
(#7585963)
> If anything, mathematicians are incredibly used to overloaded equals operators.
That's my point. The == sign meaning many things is unsurprising (and key to this "hack"), whereas explicitly using two different symbols for equivalence in the same expression is a huge, glaring signpost to pay attention.
Re:Nerdsniping: A glimpse into a stubborn mind
by resu_nimda on Monday April 14, 2014 @10:07AM
(#7586199)
As demonstrated in the postscript, it can still be accomplished when the symbols are all the same. So that difference is not the key to the hack. As ronaldx noted, the key is that a variable can change value in between two equivalence evaluations within a single statement.
Re:Nerdsniping: A glimpse into a stubborn mind
by philip_roberts on Monday April 14, 2014 @10:22AM
(#7586300)
Arguably the thing that tripped me up for the majority of the time was latching on to the fact that == and === are different, and trying to _always_ satisfy the two conditions, rather than just spotting that I can change the reference to b from within the first valueOf call. I'm not sure how much I'd read into the "if I was more of a mathematician and less of a dumb programmer this would have been solved trivially" argument.
Re:Nerdsniping: A glimpse into a stubborn mind
by nmrm on Monday April 14, 2014 @10:49AM
(#7586443)
If a == b iff a === b, then == ~ ===. If == and === are different (which they presumable are, because otherwise we would only use one symbol) then by definition there exist counter-examples of the thing you were trying to _always_ satisfy.
In other words, it would never even occur to a mathematician to make your mistake...
More to the point, a mathematician wouldn't assume that some arbitrary predicate that you are allowed to define at will behaves the same way as a system-defined equivalence operator.
Edit: Added last paragraph and readability changes. Also, ~ is another symbol for equality, this time equality over binary relations.
Re:Nerdsniping: A glimpse into a stubborn mind
by nmrm on Monday April 14, 2014 @10:32AM
(#7586357)
The postscript is irrelevant to the claim made in the original post on this thread. It's a conflated example and not indicative of real programming.
if "get" returns different values when called multiple times within a single expression, one of two things must be true:
* Someone's overriding "get" with a mutation to the variable. In all but the very rarest of circumstances, that someone should be publicly shamed. It's a nice hack for the purpose of the article, but not real code.
* there's some very fine-grained concurrency. This case is irrelevant to the OP's claim because concurrency of this sort is very likely a fundamental characteristic of the system at hand, and never an artifact of the language.
Re:Nerdsniping: A glimpse into a stubborn mind
by resu_nimda on Monday April 14, 2014 @11:21AM
(#7586646)
Which claim is that, exactly? And are you implying that the author's original solution is more indicative of real programming?
Both solutions work the same way - when accessing the value of "b" for the first check, b is mutated such that the next check will return a different value. Both of them are equally bad practices.
The == vs. === issue is the part that's actually irrelevant, it served as a red herring.
Re:Nerdsniping: A glimpse into a stubborn mind
by nmrm on Monday April 14, 2014 @01:24PM
(#7587517)
> Which claim is that, exactly? A
"This difference in how syntax is understood actually presents a barrier to programming for modestly trained mathematicians, who would otherwise be expected to excel."
> And are you implying that the author's original solution is more indicative of real programming?
Well, neither is... but yes, overriding == or .equals is somewhat common.
> when accessing the value of "b" for the first check, b is mutated such that the next check will return a different value.
The difference is that you could easily imagine a sane example where x == y != x === y, whereas it's hard to imagine a situation where I would want to override get (or ==) with a method that mutates the requested variable.
> The == vs. === issue is the part that's actually irrelevant, it served as a red herring.
For the claim re: syntax and compatibility with mathematician's expectation, it's exactly the other way around.
FWIW I feel the quoted claim re: syntax claim is interesting, whereas the contents of the article (summarily, "you can override == or .get and cause crazy stuff to happen") is unsurprising and kind of silly to most programmers even moderately experienced with OOP in dynamic languages (for the reasons given in this post and others -- everyone knows about it, it shouldn't take 11 days to figure it out, and in practice no one does purposefully obscure stuff like mutating values when == or .get is called).
Re:Nerdsniping: A glimpse into a stubborn mind
by minusSeven on Tuesday April 15, 2014 @02:19AM
(#7590549)
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 !
Re:Nerdsniping: A glimpse into a stubborn mind
by Dewie on Monday April 14, 2014 @09:21AM
(#7585942)
> 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.
Re:Nerdsniping: A glimpse into a stubborn mind
by gyepi on Monday April 14, 2014 @10:36AM
(#7586381)
Nerdsniping reminds me of the Walt Whitman poem:
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by ssharp on Monday April 14, 2014 @09:54AM
(#7586114)
I think you're right, but it's funny that both the code and the written explanation do not make that clear. Missing parenthesis in one case and missing comma in the other.
I feel like I tend to use parenthesis when they are not required, but I err on the side of caution and I think it makes things more readable.
Re:Nerdsniping: A glimpse into a stubborn mind
by blt on Monday April 14, 2014 @03:15PM
(#7588165)
I use a lot of unneeded parentheses. Makes the intent of the program clear. If the expression gets ugly, factor out subexpressions into boolean variables. If you are depending on short circuiting to avoid computing costly subexpresions, make the dependency explicit with a nested `if`.
I had a thought the other day: Complicated code should look complicated. Don't try to hide your convoluted logic. In the end, someone will have to mentally unpack it into the multi-line verbose version to understand it anyway.
Re:Nerdsniping: A glimpse into a stubborn mind
by methodover on Monday April 14, 2014 @03:28PM
(#7588249)
That's an excellent thought.
I feel like programmers too often try to make something complicated "pretty" -- but really this just usually has the effect of making it that much more difficult to understand.
Re:Nerdsniping: A glimpse into a stubborn mind
by mox1 on Monday April 14, 2014 @10:53AM
(#7586473)
Either way, it's called "Boolean Logic" and as far as I knew every Computer Scientist had to take this class in college...Not sure how you could get a job as a programmer without understanding that...
Re:Nerdsniping: A glimpse into a stubborn mind
by level on Monday April 14, 2014 @12:11PM
(#7587004)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by tarpherder on Monday April 14, 2014 @02:54PM
(#7588047)
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
Re:Nerdsniping: A glimpse into a stubborn mind
by mfonda on Monday April 14, 2014 @01:12PM
(#7587424)
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 ...)".
Re:Nerdsniping: A glimpse into a stubborn mind
by lmkg on Monday April 14, 2014 @01:38PM
(#7587597)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by gsg on Monday April 14, 2014 @03:16PM
(#7588174)
That's not due to transitivity: ['0'] == ['0'] (and for that matter, ['0'] === ['0']) is also false. These operators compare objects for identity, not structural equality.
Re:Nerdsniping: A glimpse into a stubborn mind
by russellsprouts on Monday April 14, 2014 @05:03PM
(#7588925)
Something like this could work, to some degree:
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by gcr on Monday April 14, 2014 @08:27PM
(#7589687)
This kind of abuse is also available in Python!
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
Re:Nerdsniping: A glimpse into a stubborn mind
by Grue3 on Tuesday April 15, 2014 @07:44AM
(#7591305)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by wambotron on Monday April 14, 2014 @10:29AM
(#7586334)
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.
Re:Nerdsniping: A glimpse into a stubborn mind
by neil_s on Monday April 14, 2014 @11:41AM
(#7586802)
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!
Re:Nerdsniping: A glimpse into a stubborn mind
by chrra on Monday April 14, 2014 @01:01PM
(#7587341)
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
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.
Focusing solely on the means and disregarding the ends is a good way to not deliver anything useful. Most times, things need to be good enough, not technically perfect...
This sentence means almost literally nothing, given how varied both "good enough" and "technically perfect" definitions are for each developer.
I'm more interested that this team has conversations where person A asks a really simple question that should be able to be tested in 11 seconds, person B gives a patently false answer that mistakes && for ||, which is the very thing person A is asking about. Meanwhile person C goes and spends 11 days looking for a loophole and writing a blog about it.
As a person gearing up for my first web dev position, I really wonder if this is what constitutes professional Javascript development and ask myself if I shouldn't be applying to jobs already.
To be clear, anyone that's presented a question about a tool they are using that may pertain to it's use (be it efficiency or correctness) that shows zero interest in the answer (whether or not they have time to pursue an answer) is not someone I want to work with or manage, and should probably find another career, because the one they are in isn't holding their interest. Work doesn't have to be the most important thing to you, but if you don't like your job, the people around you WILL notice.
Meanwhile, person A's question went unanswered. I would consider this a case of not keeping curiosity within bounds. Wouldn't you?
I agree wholeheartedly that curiosity is a great motivator, one that I would want driving all my coworkers. But as this blog presents it, the curiosity suffers from the greatest threat to curiosity, which is a lack of discipline that ensures the curious person never rises above a dilettante. I speak from first hand knowledge here - I've wasted more than my share of time doing something just for fun that benefits nobody.
If it were not the case that Person B, the implicit authority figure in the scenario, gave a totally backwards answer to Person A, OR ( || ) if it were not the case that Person C failed to alleviate the confusion of Persons A and B, then I would not see any problem with going off on a trip down pedantry lane. As it is, the whole organization looks like a gang of clowns. Nobody can answer the most basic of syntax questions, and one person even takes a faulty intuition ("b can be both 80 and 443") and follows it on a Quixotic quest into the arcana of the language spec. It's almost as though he stumbled on the real value of the quest (how evaluations of == and === are actually implemented) by sheer accident, in spite of himself. Luckily, many quests follow this pattern.
For what it's worth, I do find the discussion interesting. But it's interesting in way different than that of edge cases. Deliberately breaking something by using it in a way it was never intended to be used can be enlightening if you want to fend off would-be attackers. It exploits the system's implementation constraints. On the other hand, an edge case highlights the edges of legitimate use which the system was never designed to account for. It exploits the system's lack of comprehensiveness. The distinction is a good one, I think.
For example, consider a chair. An edge case might be a 600-pound man. The engineers didn't take this legitimate use of the chair into account when they determined the thickness of the material. That's an edge case. It's not quite the same as saying that the engineers didn't take into account that wood is flammable. This example is not the best, but I'm now well too far into my own trip down pedantic lane to spend any more time trying to improve it. :)
Had I suspected the quality of my team, or my discipline would be under question, I would have left them in :)
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.
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.
I spent seven years as a Perl programmer. Like Perl, a language can be extremely productive in the hands of a veteran and dangerous with a newcomer due to the unnecessary confusion it generates. At least eq and == are syntactically easier to grok than == and ===.
Except when I use JSLint. Talk about bringing you back to Earth when you think you've done something remarkable with JS.
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.
For example, it's not possible in Java or Objective-C to make an expression of the form a == b, where a and b are plain variables, have any side effects.
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
This makes it somewhat obvious that you can't change how basic types work in C++. On the other hand, JS's dynamicity makes for some interesting situations, as seen here. I wouldn't consider it "awful" but it's certainly a language with more "deep complexity" than appears at first glance.
On some level, defending JS using C is like saying you can also make a souffle by instead cooking the chicken with the egg still inside it. Both JS and its bad paradigms came from C. You don't arrive at good design by showing that other people also got it wrong.
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 language used can hardly be blamed for that.
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.
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.
This perhaps illustrates my point. While you say == and === are equivalence relations (I would argue they are not), there is a wider problem.
= itself is an assignment operator and should never be considered as an equivalence relation. But it is normal to consider = as algebraic equality for anyone who has completed high school math.
It's a great loss to intuitive understanding that we use = for assignment. If anything, considering Javascript's == and === is a net benefit as programmers are more acutely aware of the issue here.
What percentage of time spent learning to program and recovering bugs is caused by overcoming this misintuition? It's surely a lot.
Wikipedia has further discussion: https://en.wikipedia.org/wiki/Assignment_%28computer_program...
If anything, mathematicians are incredibly used to overloaded equals operators.
That's my point. The == sign meaning many things is unsurprising (and key to this "hack"), whereas explicitly using two different symbols for equivalence in the same expression is a huge, glaring signpost to pay attention.
In other words, it would never even occur to a mathematician to make your mistake...
More to the point, a mathematician wouldn't assume that some arbitrary predicate that you are allowed to define at will behaves the same way as a system-defined equivalence operator.
Edit: Added last paragraph and readability changes. Also, ~ is another symbol for equality, this time equality over binary relations.
if "get" returns different values when called multiple times within a single expression, one of two things must be true: * Someone's overriding "get" with a mutation to the variable. In all but the very rarest of circumstances, that someone should be publicly shamed. It's a nice hack for the purpose of the article, but not real code. * there's some very fine-grained concurrency. This case is irrelevant to the OP's claim because concurrency of this sort is very likely a fundamental characteristic of the system at hand, and never an artifact of the language.
Both solutions work the same way - when accessing the value of "b" for the first check, b is mutated such that the next check will return a different value. Both of them are equally bad practices.
The == vs. === issue is the part that's actually irrelevant, it served as a red herring.
"This difference in how syntax is understood actually presents a barrier to programming for modestly trained mathematicians, who would otherwise be expected to excel."
> And are you implying that the author's original solution is more indicative of real programming?
Well, neither is... but yes, overriding == or .equals is somewhat common.
> when accessing the value of "b" for the first check, b is mutated such that the next check will return a different value.
The difference is that you could easily imagine a sane example where x == y != x === y, whereas it's hard to imagine a situation where I would want to override get (or ==) with a method that mutates the requested variable.
> The == vs. === issue is the part that's actually irrelevant, it served as a red herring.
For the claim re: syntax and compatibility with mathematician's expectation, it's exactly the other way around.
FWIW I feel the quoted claim re: syntax claim is interesting, whereas the contents of the article (summarily, "you can override == or .get and cause crazy stuff to happen") is unsurprising and kind of silly to most programmers even moderately experienced with OOP in dynamic languages (for the reasons given in this post and others -- everyone knows about it, it shouldn't take 11 days to figure it out, and in practice no one does purposefully obscure stuff like mutating values when == or .get is called).
edit: grammar
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 !
This isn't really a problem if b is enforced to be immutable.
Couldn't you simply do this?:
if ((a==='80'||b==='443') && http===false) { ... }
if (a==='80' || (b==='443'&&http===false)) {...}
I feel like I tend to use parenthesis when they are not required, but I err on the side of caution and I think it makes things more readable.
I had a thought the other day: Complicated code should look complicated. Don't try to hide your convoluted logic. In the end, someone will have to mentally unpack it into the multi-line verbose version to understand it anyway.
I feel like programmers too often try to make something complicated "pretty" -- but really this just usually has the effect of making it that much more difficult to understand.
You're comparing a literal number with an object, which are not the same type.
You probably haven't. But a less experienced programmer has learned why you should always use ===.
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
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 ...)".
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.var b = {};
b.valueOf = function () {
};if (b==1 && b==2) {//success}
For N ports, or for a port list defined from a config file however it could be. It's even nicer in python:
Or with underscore: Good collections make it better than manually checking the return code or checking an explicit set of port values. Also configuration > magic_nums.var b = 2;
b == '2'; // true
b === 2; // true
(b == 1 && b===2 && b === herpderp)
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.
Port the solution to Haskell
(everything == all && all == everything) == stardust/code
> : a 2 ;
> : 2 3 ;
> a 2 =
> a 3 =
The two flags on the top of the stack are now equal.