[HN Gopher] JavaScript Is Weird
       ___________________________________________________________________
        
       JavaScript Is Weird
        
       Author : robin_reala
       Score  : 345 points
       Date   : 2021-06-28 09:12 UTC (13 hours ago)
        
 (HTM) web link (jsisweird.com)
 (TXT) w3m dump (jsisweird.com)
        
       | s_gourichon wrote:
       | Website content on a web browser:
       | 
       | > This website is literally about JavaScript. I mean what did you
       | expect, a .NET application? This website is 99.9% poorly
       | optimized and highly questionable JS. And yet, you have JS turned
       | off.
       | 
       | Yes, a website can be about Javascript and still be a collection
       | of documents in web standards, like HTML+CSS, possibly with
       | optional interactive features that could be implemented in
       | Javascript.
       | 
       | I mean, what did you expect? That it is impossible to edit a book
       | on paper about Javascript because obviously paper cannot run
       | Javascript code? Even I have books about Javascript, and they
       | render fine.
        
       | stared wrote:
       | Judging by the title, it sounded like the biggest discovery of
       | 2021... by someone waking after a long coma. It was discovered in
       | 2012: https://www.destroyallsoftware.com/talks/wat
       | 
       | I really enjoyed the questions... and even though I am working in
       | TypeScript, I got only 9/25. Precisely because I avoid f---ed up
       | parts of JS, except for trivia games
       | (https://dorey.github.io/JavaScript-Equality-Table/unified/,
       | http://www.jsfuck.com/).
       | 
       | Some parts of code need not to be understood. They need to be
       | blocked by types, tests, and linters
       | (https://p.migdal.pl/2020/03/02/types-tests-typescript.html).
        
         | hajile wrote:
         | https://xkcd.com/1053/
         | 
         | There are a lot of people being born every year. If a 16-18
         | year old teenager is getting into web development, they were
         | 4-6 when that talk was given in 2012. Sure, that talk still
         | appears here and there, but it's past its prime and you'd have
         | to be in the right place at the right time to run into it.
         | 
         | Crockford's book (JS: The Good Parts) was ubiquitous among JS
         | devs who were coding between 2008 and 2015 (give or take).
         | These days, younger devs have never heard of it. Due to the
         | Seinfeld Effect, if they read it, it would seem trite and
         | obvious not realizing how revolutionary it was at the time.
        
           | jonny_eh wrote:
           | It's amazing how much of a positive effect that short comic
           | has had on my life.
        
           | edgeform wrote:
           | Not to mention just because I was alive in 2012 doesn't mean
           | I know or knew about this.
           | 
           | The parent comments floating to the top here seem to have a
           | common theme of "I knew that already how did the rest of the
           | world not also get the memo at the same exact moment I did?"
        
       | AtNightWeCode wrote:
       | There are some real problems with the quirks of Javascript too
       | even if the examples are not that common. Some JS coders for
       | instance use the oneof pattern and if you then forget somewhere
       | to check if you got a Number instead of a Boolean you can end up
       | with something weird. I have seen it several times.
        
         | itsbits wrote:
         | JS is a loose type language by definition.
         | 
         | Biggest problem for JS, from the beginning was people start
         | writing without completely understanding it. Even myself seeing
         | my initial JS code feel embarrassed. Noone understand what is
         | or handle loose typing, prototype, closures, functional
         | concepts like currying before coding. I took almost an year to
         | understand same. Although that time there are hardly my
         | resources like now. But I still see, people directly jumping
         | into JS.
        
       | vorticalbox wrote:
       | if you block JS you get this message
       | 
       | > This website is literally about JavaScript. I mean what did you
       | expect, a .NET application? This website is 99.9% poorly
       | optimized and highly questionable JS. And yet, you have JS turned
       | off.
        
         | franciscop wrote:
         | If you open the console to check after you're finished, it
         | says:
         | 
         | "What, are you going to check if the results are accurate? Go
         | ahead "
         | 
         | But if you open it console _while_ doing the test, it says:
         | 
         | "Hey, stop cheating! "
        
           | amelius wrote:
           | Why the hell can websites tell that I'm in the console? If I
           | want to inspect some parts of a website (perhaps save an
           | image), then I don't want that website to interfere.
        
             | woutr_be wrote:
             | They don't. They just use "console.log", you see it because
             | you opened the console. It's not like they know you're
             | there and then write a message.
        
               | hmsimha wrote:
               | Devtools can actually be detected to a certain extent -
               | https://github.com/sindresorhus/devtools-detect
        
               | khasan222 wrote:
               | Seems like this guy is just using a width a height
               | difference to detect this. Also some 'window.FireBug'
               | property, that doesn't turn up much currently in chrome
               | or ff console on Ubuntu
        
               | amelius wrote:
               | This entire project should be copied verbatim into
               | browser bug trackers, imho.
        
               | pityJuke wrote:
               | > Doesn't work if DevTools is undocked and will show
               | false positive if you toggle any kind of sidebar.
               | 
               | This annoys me every time because I use Tree Style Tab,
               | and a website tries to detect DevTools. See Samy Kamkar's
               | website [0].
               | 
               | [0]: https://samy.pl/
        
             | LW9ucKsYuvuVeBa wrote:
             | Not used in this case but if you open the console docked
             | (which is the default as opposed to a separate window) then
             | the resolution of the window will change.
        
             | timvdalen wrote:
             | While there are some ways to detect having devtools
             | open[1], this website isn't actually using them. Instead,
             | it just always writes these messages to the console. Before
             | navigating to the answers, it clears the console so you
             | don't see the messages that were logged before.
             | 
             | [1]: https://stackoverflow.com/a/7809413/451847
        
               | shoeffner wrote:
               | This answer how facebook does (did?) it and why is also
               | very interesting: https://stackoverflow.com/a/21693931
        
       | zelphirkalt wrote:
       | And now imagine, if you had to deal with a programming language,
       | which does not warn you or error out, when you are using null or
       | undefined bindings in procedures, where you should be using
       | strings or other things ... Wait, people actually invented such a
       | language ...
        
       | dahart wrote:
       | NaN++ is sometimes a TypeError in environments that define NaN as
       | read only, that one's sometimes wrong.
       | 
       | The float examples aren't weird in JS, they're the same in all
       | languages that use IEEE 754 floats, which specifies that NaN !=
       | x, where x is anything.
       | 
       | "This is due to a decision made by the IEEE-754 committee for a
       | few reasons, such as space efficiency and the fact that the
       | function isNaN didn't exist at the time."
       | 
       | This explanation feels like it's trying hard to downplay the
       | reasons and make it sound arbitrary and almost whimsical. It
       | doesn't make sense to allow NaN - NaN = 0 (Note that Infinity -
       | Infinity == NaN), and it's important that NaNs used as input to
       | computation produce NaNs as output (other than when using boolean
       | tests).
        
       | dzonga wrote:
       | silly questions, some of these expressions you don't use on a
       | daily basis. language has quirks, but allows you to do a lot in a
       | much expressive manner.
        
       | tinco wrote:
       | Ironically I got a bunch of these wrong because JavaScript is
       | less weird than I thought it was. For example for some reason I
       | thought ![] would be true, because JavaScript would do something
       | weird, but it's not and JavaScript does exactly what you'd expect
       | any sensible language to do.
       | 
       | I didn't enjoy the quiz, it just reminds me how depressing the
       | base layer of the thing I'm most passionate about in life is. The
       | expression [1,2,3]+[4,5,6] returning what it does is just a
       | bummer, it just sucks. Calling it weird is giving it undue merit,
       | as if it's cute somehow that it's so awful.
        
       | dgb23 wrote:
       | I use JS since almost a decade and only got half of them right.
       | Specifically I failed at the last one because I got impatient,
       | the octal one got me too (never use those in JS), the true++ and
       | the ones that require you to know that arrays are converted to
       | strings when used in arithmetic.
       | 
       | I'll just externalize my embarrassment and say that JS _is_
       | indeed weird! Another excuse is that I typically try to avoid
       | implicit type conversion except for idiomatic  "tricks" such as
       | using !! to convert to a boolean.
       | 
       | Cool website though!
        
         | woutr_be wrote:
         | I have been using JS for almost 10 years, and have written
         | quite a few big apps with it, both front- and back-end, but
         | only a handful of times have I experienced this "weird" issues.
         | Nobody writes code like that, I only know of these things
         | because there have been many websites like this over the years.
        
       | slver wrote:
       | Every language has undefined or unexpected behaviors.
       | 
       | The real lesson is that this doesn't necessarily matter, if
       | they're not essential to the code you write most of the time.
       | 
       | Also some of those about floating point math, which is not JS
       | being weird, but rather about needing to know what a float is.
        
       | GlennS wrote:
       | I guess this is why people seem to like Typescript so much.
        
       | jjice wrote:
       | TypeScript to the rescue! I just prefer strongly typed languages,
       | but it's things like this that disappear (for the most part) when
       | you have types. I personally can't keep types in my head as well
       | as some, so when the language forces me to, it helps a lot.
       | Vanilla JS just makes me feel like I'm walking on egg shells.
       | 
       | Then we can get into a lot of fun when we get to type systems
       | like SML and Rust where you start to really touch on some power
       | (but can become intimidating). I'm still a bit weary of trying to
       | hop into Haskell.
        
         | tabtab wrote:
         | I just wish TypeScript supported optional named parameters.
         | Once I got used to them in C#, it's hard to live without. They
         | make adding enhancements so much easier. The work-arounds, such
         | as object literals, are just not the same.
        
       | onion2k wrote:
       | _0.2 + 0.1 === 0.3_
       | 
       | That's not really a JS problem, that's a floating point problem.
       | Plenty of languages will have the same issue.
       | 
       |  _+!![]_
       | 
       |  _" " - - ""_
       | 
       |  _(null - 0) + "0"_
       | 
       | Calling these things weird is fair enough but I can't help
       | thinking this is code you'd never actually write outside of the
       | context of a "Look how weird JS is!" post. It's like picking
       | examples from the Annual Obfuscated C Contest to show how hard it
       | is to understand C. Yes, some languages enable you to write weird
       | garbage code that's hard to reason about, and ideally they
       | wouldn't because enforcing sane code would be great, but _come
       | on_. Most of these things aren 't a big problem that we suffer
       | every day. Just be _moderately_ careful about casting things from
       | one data type to another and _all_ these problems go away.
        
         | z3t4 wrote:
         | Also things like +!![] is because while JS is dynamic it does
         | have a very strict type system! ![] becomes a boolean +true
         | becomes a number.
        
           | viraptor wrote:
           | This is a result of the implicit type conversion feature
           | rather than a strict type system.
        
           | simiones wrote:
           | JS has a very _weak_ type system, full of implicit
           | conversions. In dynamic languages with _strong_ type systems,
           | like Common Lisp, such operations typically result in errors:
           | (+ (not (not '())))             The value NIL is not of the
           | expected type NUMBER.
           | 
           | Similarly in Ruby:                 +!![]
           | undefined method `+@' for true:TrueClass (NoMethodError)
           | [Condition of type TYPE-ERROR]
           | 
           | Interestingly, Python does the same thing as JS in this case,
           | even though it is typically quite strongly typed. Edit: not
           | quite the same, as the empty array is converted to False in
           | Python, just as it is in Ruby (in CL, nil/'() IS the
           | canonical false value); but still, Python outputs 0, it
           | doesn't complain like the other two.
        
             | epidemian wrote:
             | > Interestingly, Python does the same thing as JS in this
             | case, even though it is typically quite strongly typed.
             | [...] > Python outputs 0, it doesn't complain like the
             | other two.
             | 
             | yep, this is one of those Python weird bits. in Python,
             | booleans _are_ ints, True is 1 and 0 is False. and i don 't
             | mean it in a JS-ish way like "they can be converted to...".
             | no, True is the integer value 1. in fact, the type bool is
             | a subtype of int. if you think of types as sets of values,
             | and subtypes as subsets of their parent set, that `book <
             | int` relation suddenly makes a lot of sense ;)
             | >>> +(not not [])       0       >>> (not not [])
             | False       >>> 0 == False       True       >>> 1 == True
             | True       >>> True + True       2       >>> True - False +
             | True * 0.5       1.5       >>> isinstance(False, bool)
             | True       >>> isinstance(False, int)       True       >>>
             | bool < int       True
             | 
             | so, if you accept that the operation `not []` makes sense
             | to be defined as True (because `bool([])` is False), and
             | that it makes sense for False to be the integer 0, then
             | `+(not not [])` being 0 is just a logical consequence of
             | that :)
             | 
             | for the record, i _do_ think it 's weird for Python to
             | define bools as ints, and to make all values define a
             | boolean semantics via __bool__().
        
               | dwheeler wrote:
               | Python was created February 1991, but it didn't have a
               | boolean type until 2002 per PEP 285
               | <https://www.python.org/dev/peps/pep-0285/>
               | 
               | The rationale for making bool a subset of integers is for
               | ease of implementation and substitutability (which aids
               | backwards compatibility)47, as explained here:
               | 
               | > In an ideal world, bool might be better implemented as
               | a separate integer type that knows how to perform mixed-
               | mode arithmetic. However, inheriting bool from int eases
               | the implementation enormously (in part since all C code
               | that calls PyInt_Check() will continue to work -- this
               | returns true for subclasses of int). Also, I believe this
               | is right in terms of substitutability: code that requires
               | an int can be fed a bool and it will behave the same as 0
               | or 1.
               | 
               | I have some Python code where there are still a number of
               | uses of 0 and 1 for false and true, because it was
               | written before Python added a boolean type.
        
         | zelphirkalt wrote:
         | I am sure a reasonable person and educated computer programming
         | person will be able to avoid these traps, by adhering to
         | certain standards. However, you often have that other person on
         | your team, who does not care about being careful and writes
         | code like it is to be once written and never touched again. And
         | that's where the danger creeps in.
        
           | saurik wrote:
           | Entirely orthogonal to these operator semantics being
           | unreasonable, that person should not be on your team: replace
           | them with someone who cares.
        
         | giancarlostoro wrote:
         | Someone had linked on here a website that showed the 0.3 thing
         | in practically almost every programming language and their
         | output. I wish I could remember the domain / url cause it is
         | interesting to compare languages defaults. I know most
         | languages have ways to handle it correctly.
        
           | dvlsg wrote:
           | https://0.30000000000000004.com/
        
             | giancarlostoro wrote:
             | Yes this is it! Thanks for that, I do appreciate that they
             | show multiple approaches in each language to showcase which
             | one gives you the desired result.
        
           | onion2k wrote:
           | _I know most languages have ways to handle it correctly._
           | 
           | Including JS - http://mikemcl.github.io/decimal.js/
        
             | dvlsg wrote:
             | There's a proposal to add a decimal type to the spec, too.
             | 
             | https://github.com/tc39/proposal-decimal
             | 
             | Seems like it's a long ways away from being available,
             | though.
        
         | rileytg wrote:
         | We have this on our interview test. It was the one almost
         | everyone got wrong except for a couple people who ended up
         | being really detail oriented and had deep knowledge (as opposed
         | to broad).
         | 
         | We consider >70% passing.
        
           | mewpmewp2 wrote:
           | I'd honestly consider these types of questions one of the
           | poorest ways to test front end developers.
           | 
           | The only reason I have learned some of that oddball stuff
           | with JavaScript is because of some job interviews e.g. when I
           | was earlier in my career, I used to Google things like "top
           | 30 questions asked in a JS interview", etc, but I forget it
           | after that until I'm about to look for another job. However I
           | wouldn't do this type of learning any longer, since I
           | wouldn't want to apply for a company asking these types of
           | questions.
           | 
           | In the end at work you should use ES6/TypeScript with
           | linting, proper tests and these cases would never occur.
        
         | holtalanm wrote:
         | > Calling these things weird is fair enough but I can't help
         | thinking this is code you'd never actually write outside of the
         | context of a "Look how weird JS is!" post.
         | 
         | That is the whole premise of the site, though. They even say
         | that these examples aren't common syntax or patterns before you
         | start.
        
           | some_random wrote:
           | The site is called "JavaScript Is Weird", not "Weird
           | Javascript", even if they tell you that the examples aren't
           | common they're still saying that this weirdness is unique to
           | JS. Which definitely isn't true in the case of basic floating
           | point precision problems
        
             | holtalanm wrote:
             | > The site is called "JavaScript Is Weird", not "Weird
             | Javascript"
             | 
             | am i being punkd?
        
         | bruce343434 wrote:
         | Yup, garbage in garbage out. I'm not a huge fan of JS, but this
         | sort of criticism is absurd.
        
           | wdroz wrote:
           | I rather have the language say "Error, this is garbage!" than
           | silently output garbage.
        
             | madeofpalk wrote:
             | Which is why we use Typescript
        
               | AnIdiotOnTheNet wrote:
               | The fact that there has to be a different language on top
               | of your language to make it same days all that needs
               | saying really.
        
               | AnIdiotOnTheNet wrote:
               | Man do I hate my phone's autocorrect. For anyone confused
               | as shit:
               | 
               | The fact that there has to be a different language on top
               | of your language to make it _sane says_ all that needs
               | saying really.
        
               | madeofpalk wrote:
               | Pragmatism of an runtime/ecosystem that highly favors
               | backwards compatibility above all else.
        
               | Griffinsauce wrote:
               | This goes for all compiled languages?
        
               | AnIdiotOnTheNet wrote:
               | We invented compiled languages because of issues with
               | writing everything in assembly. In other words, we
               | invented C because assembly wasn't very good.
               | 
               | Just like we invented TypeScript because JavaScript
               | wasn't very good.
        
               | [deleted]
        
               | lotsofcows wrote:
               | I keep having this argument with my boss but he refuses
               | to let me write machine code.
        
               | dangerbird2 wrote:
               | If the good lord wanted us to code in assembly language,
               | he'd have made transistors operate on mnemonics, not
               | electric currents.
        
               | lostcolony wrote:
               | If the good lord had wanted us to interact with
               | transistors based on mnemonics, not electrical currents,
               | he'd have implemented our brains in mnemonics, not
               | electrical currents.
        
               | akiselev wrote:
               | Nitpick: voltage potentials and ion channels. There's not
               | much actual current flowing.
        
               | cygned wrote:
               | Typescript doesn't save you from all the weird things
               | happening at runtime. A missing check at a context
               | boundary and you can have a wild time (been there).
        
               | kevinmgranger wrote:
               | Context boundary meaning where it interfaces with
               | javascript?
        
               | cygned wrote:
               | The points where you parse JSON, for example.
        
             | hajile wrote:
             | The sad truth is that this stuff was not in the first
             | version of JS. It was added AT THE REQUEST OF DEVS (a
             | decision Eich has said he regrets).
             | 
             | Like most bad things, it's only around because a big
             | company said so.
             | 
             | Like all bad things in JS, there was a push to remove it at
             | ECMA, but Microsoft had reverse-engineered JS into JScript
             | and refused to go along with the changes to fix the
             | weirdness.
        
             | blacktriangle wrote:
             | The root of the problem is the original intent of
             | Javascript. Javascript was intended to be a small layer of
             | dynamism added to web pages that were mostly defined via
             | HTML which were presented to a human for interpretation.
             | When your user agent is a human trying to look up an
             | address for a restaurant, they can look at a garbled piece
             | of crap where the JS crashed and still maybe find what they
             | were looking for in the rendered text. Limp along the best
             | you can is a great failure strategy for Javascript's
             | original use-case. Only now that we've turned Javascript
             | into a general purpose programming language is this a
             | failure.
             | 
             | Even Javascript's weak typing makes sense in this case. Why
             | automatically convert everything? Becausethe expectation
             | was that inputs to your Javascript would be HTML attributes
             | which are all strings. Automating type conversions from
             | strings made sense. But once you move to larger scale
             | programing, Javascript's weak typing is awful
        
         | wruza wrote:
         | The same for "== considered harmful". I scanned the entire
         | comparison table and the only unobvious or error-prone cases
         | are those you never really do in programming.
         | 
         | https://stackoverflow.com/a/23465314
         | 
         | For me it's only rows [[]], [0], [1], i.e. array-unfolding
         | related, but all others are regular weak-typed comparisons like
         | in perl and other dynamic semantics. <snip> Edit: just realized
         | "if (array)" is okay, nevermind.
        
           | emteycz wrote:
           | undefined and null sometimes make problems. IMHO it's good
           | that undefined == null but some people don't realize.
        
             | wruza wrote:
             | I agree. If native apis didn't return nulls in some cases,
             | and undefined was named "undef" at least, null could be
             | ditched. But then again, it's only because js has no bad
             | habit of treating the same of non-existence and
             | undefinedness^. If not json (which has no undefined), we
             | could ditch null. But it's there and with === it leads to
             | either                 object.someField === null ||
             | object.someFeild === undefined
             | 
             | madness, or to a potential error if a programmer thinks
             | that null can not be there.
             | 
             | We could do an exception for null === undefined, but it's
             | against its spirit and will not be accepted.
             | 
             | ^ languages that treat non-existent key as undefined are
             | usually doomed to introduce Null atom in some form, or to
             | work around that limitation constantly in metaprogramming
        
               | blacktriangle wrote:
               | null and undefined is one of the things Javascript
               | actually got right imo. Undefined is what lets Javascript
               | turn what other dynamic language would throw as a runtime
               | error into a value. "I do not have a definition for the
               | thing you want" and "the thing you want is known to be
               | unknown" are two totally different concepts that
               | languages with only null to lean on must collapse into a
               | single concept.
        
               | Jasper_ wrote:
               | I've never found this to be a useful difference in
               | practice. Also, JavaScript really doesn't use it
               | correctly to begin with. Arrays are a mess. Like the
               | poster below, I usually cast to one of them, except I
               | cast to null.
        
               | Sankozi wrote:
               | The problem is undefined is used in places null makes
               | much more sense (like a result of the find function). I
               | follow the rule to never use null and convert to/from
               | undefined if needed by some library.
        
               | blacktriangle wrote:
               | Leave it to javascript to pull defeat from the jaws of
               | victory.
        
           | Liquid_Fire wrote:
           | > the only unobvious or error-prone cases are those you never
           | really do in programming.
           | 
           | You never do them on purpose. The problem is when you do them
           | by accident because of a mistake in your code, and the error
           | slips through unnoticed, doing the wrong thing.
           | 
           | > weak-typed comparisons like in perl
           | 
           | Perl has separate operators for working on strings vs
           | numbers, so you are always explicit about performing a
           | numerical vs string comparison etc. Not so for JavaScript.
        
             | denton-scratch wrote:
             | Agree. The tests are silly, but each test highlights a
             | gotcha that you might bump into while debugging some
             | horrible heap of legacy code.
        
         | blowski wrote:
         | Exactly. Finding flaws in a language doesn't mean the language
         | is bad, just that it has... flaws. The proof that JS is
         | actually pretty good is that it has been used to build so many
         | things. Like the old adage about economics, these criticisms
         | are taking something that works in practice and trying to see
         | if it works in theory.
        
           | anoncake wrote:
           | No. Popularity does not indicate quality. Judging the quality
           | of something by its popularity is a form of cyclical
           | reasoning. Especially when there is an obvious alternative
           | explanation, namely that JS is the only language you can in
           | the browser without transpiling and for a long time the only
           | one period.
           | 
           | While the fact JS can be used to build all these things puts
           | a floor on its quality, that floor is uselessly low.
        
             | blowski wrote:
             | I'm not using popularity as the metric. "1 million
             | identical websites were built with JavaScript" wouldn't say
             | much beyond the first website.
             | 
             | But that there is a very broad range of successful
             | applications partly relying on JavaScript for their success
             | undercuts the idea that JavaScript is inherently rubbish.
             | Whether it has some subjective "quality" is a conversation
             | best left for art galleries.
        
               | joelfolksy wrote:
               | "The proof that JS is actually pretty good is that it has
               | been used to build _so many_ things. "
               | 
               | [French Narrator] 5 minutes later...
               | 
               | "I'm not using popularity as the metric."
        
               | anoncake wrote:
               | If you say JS is "pretty good" how is that not a
               | statement about its quality?
        
               | blowski wrote:
               | Fair point. I guess I could rephrase it as "JavaScript
               | provides a lot of value".
        
           | foepys wrote:
           | Just because something is popular isn't reason for it to be
           | good. Examples: fossil fuels, (over)fishing, rage-based
           | engagement, hard drugs.
        
             | blowski wrote:
             | On the contrary - the number of people taking hard drugs to
             | get high is fantastic evidence that they are good for
             | getting high. Otherwise, why would people be buying and
             | taking them?
        
               | anoncake wrote:
               | People use hard drugs to cope with their problems, and
               | they're rubbish for that.
        
             | Blikkentrekker wrote:
             | Excepting fossil fuels, none of those things are popular.
        
             | ufmace wrote:
             | Uh Fossil Fuels powered the Industrial Revolution and
             | literally created the modern economy.
             | 
             | It's true that being popular doesn't necessarily make
             | something good. But it's also true that having some flaws
             | discovered later doesn't make something that revolutionized
             | the world and massively uplifted the standard of living of
             | basically everyone in it bad.
        
             | HotDogLinux wrote:
             | Just to add to your list: Ed Sheeran
        
         | fenomas wrote:
         | Yeah, a lot of these have nothing to do with JS. I have no idea
         | what the site is trying to accomplish.
         | 
         | I mean:                   !!!true
         | 
         | In what language does that (or its equivalent) _not_ evaluate
         | to false?
        
           | dolmen wrote:
           | In Go: https://play.golang.org/p/G8jOKtIj4AY
        
             | 7steps2much wrote:
             | One might want to add that it does work when you use a
             | variable however. https://play.golang.org/p/6UfNFWm_-JR
        
               | [deleted]
        
               | jakelazaroff wrote:
               | The issue isn't that they're constants, but that GP
               | called them "true" and "false" and assigned the opposite
               | values you'd expect. You can break it in exactly the same
               | way with variables: https://play.golang.org/p/EVU84l0A57I
               | 
               | Kinda crazy to me that Go doesn't reserve the words
               | "true" and "false", but -\\_(tsu)_/-
        
             | fenomas wrote:
             | Great point, I'll edit my comment to say "(or its
             | equivalent)", instead of "(that precise sequence of
             | characters, no matter what you've redefined true and false
             | to be)". Not sure why I originally wrote it that way.
        
             | Sebb767 wrote:
             | Can anyone explain this to me?
        
               | svieira wrote:
               | Looks like the `true` and `false` _bindings_ in Go are
               | mutable and can be re-assigned. The same thing was
               | possible in Python 2, IIRC:                   False, True
               | = True, False # Have fun debugging!
        
               | Sebb767 wrote:
               | Ah, I missed that line. Now I feel stupid ;)
        
               | Cthulhu_ wrote:
               | They're defining a const named true and false to their
               | inverse values, shadowing the builtin true/false
               | keywords.
        
               | carl_dr wrote:
               | !!!true is equal to false in JS, and in Go (and in any
               | other language I can think of.)
               | 
               | In that Go example above, the author is reassigning true
               | and false to be their opposites.
        
               | JoeCortopassi wrote:
               | `!` is added to values in most languages as a shorthand
               | for saying "give me the opposite boolean value of this.
               | So `!true` would equal `false`
               | 
               | Some people add two exclamation points as a shorthand to
               | cast a value to a boolean. So if you wanted to see if
               | something was 'truthy', you could say `!!truthyValue` and
               | it would return ` true` instead of the value itself.
               | Literally what your asking the language is "give me the
               | opposite boolean value of the opposite boolean value of
               | `truthyValue`"
               | 
               | Now you can probably see why three exclamation points is
               | silly, it's not giving you anything that a single
               | exclamation point wouldn't give you. Both `!truthyValue`
               | and `!!!truthyValue` evaluate to false, you are literally
               | saying "give me the opposite boolean value of the
               | opposite boolean value of the opposite boolean value of
               | `truthyValue`"
               | 
               | The example in Go is intentionally misleading because Go
               | lets you reassign the values for `true` and `false`. It's
               | going through all the same steps I described above, but
               | it's starting with a value opposite of what you think it
               | is
        
         | wartijn_ wrote:
         | The site does say so in the introduction
         | 
         | > Even if you're a JS developer, most of this syntax is
         | probably, and hopefully, not something you use in your daily
         | life.
         | 
         | So I think you should look at this site more as something fun
         | you might not have known if you're an js developer than as
         | criticism of js.
         | 
         | That being said, the !!"" isn't that weird of a syntax is it? I
         | see and use the double exclamation mark all the time.
        
           | TheCoelacanth wrote:
           | I doubt that anyone who hasn't written JS will recognize !!
           | as an idiom for converting to boolean.
        
             | tyingq wrote:
             | That kind of type coercion predates JS.
             | perl -e 'print !!"whee"'       1       php -r 'print
             | !!"whee";'       1       awk 'BEGIN {print !!"whee"}'
             | 1
        
           | leoc wrote:
           | > that weird of a syntax
           | 
           | ought to be "that weird a syntax": it's 'so [adjective] a
           | [noun]' not 'so [adjective] of a [noun]'. It's 'so much of a
           | syntax' but that's because 'much' is a determiner not an
           | adjective, which really makes a much difference. Or if you
           | want to be plain-spoken you can ofc just say 'such a weird
           | syntax'.
        
             | KMnO4 wrote:
             | English is as weird as JavaScript.
        
               | bryanrasmussen wrote:
               | no, it's fine - you just need the right education
               | https://publicdomainreview.org/collection/english-as-she-
               | is-...
        
             | blowski wrote:
             | https://english.stackexchange.com/a/30012/7762
        
               | leoc wrote:
               | Yes, the quotation from dictonary.com exactly supports
               | what I am saying. It's a piece of spoken dialect not
               | standard English. It's as if I was after using hiberno-
               | English constructions in a HN comment. Will you go on out
               | of that.
        
               | [deleted]
        
               | fenomas wrote:
               | There is no such thing as standard English. The link says
               | only that the usage is _informal_ , and HN comments are
               | not formal writing.
        
               | blowski wrote:
               | If your comments were comprehensible to most HN readers,
               | I wouldn't see the problem in using Hiberno-English, or
               | any other colloquialisms.
        
               | leoc wrote:
               | If you consistently wrote in the way that Goofy talks
               | then most HN readers would understand you just dandy but
               | you wouldn't look no ways good. 'so [adjective] of a
               | [noun]' is a Goofyism which doesn't belong in even
               | middle-register spoken English. (Of course writing in
               | dialect is completely fine if you're doing it for effect
               | or for some other specific reason.)
        
               | blowski wrote:
               | That's completely your opinion, though - there's nothing
               | in the guidelines or FAQs that say that.
               | 
               | When on HN, I engage with things I find interesting,
               | irregardless of how good their ritten. If we intimidate
               | users with an expected level of ability in written
               | English, we'll be excluding a lot of interesting
               | comments.
        
           | zdragnar wrote:
           | The output is "weird" if you don't know the rules for
           | operator precedence and how things convert to their primitive
           | values.
           | 
           | Most people arent going to "know" what '+!![]' will resolve
           | to because it makes literally no sense to combine those
           | operators into a single expression in anything approaching
           | normal code.
        
             | denton-scratch wrote:
             | This is true; a lot of the questions are about automatic
             | type conversions.
        
             | zarzavat wrote:
             | I have definitely used the +!! "operator" before. It
             | coerces a value into a boolean integer. It's not weird at
             | all, just a mechanical application of the not ! and Number
             | coercion operators +.
             | 
             | The fact that [] is truthy is something everybody learns in
             | their first weeks of JS programming otherwise you would be
             | writing `if (someArray)` and wondering why your code is
             | broken.
             | 
             | A weird one would be to explain why +[] is 0 and +{} is
             | NaN. _That_ is nonsensical.
        
         | e3bc54b2 wrote:
         | In my humble and admittedly little experience, its not what you
         | intentionally write, but what gets unintentionally written and
         | needs to be debugged later.
         | 
         | Carmack-like people utilising this stuff for good are few and
         | far between, for your everyday joe programmer this is a
         | footgun, a very-nonobvious and non-intuitive one (hence footgun
         | moniker) that they write in crunch, it slips past reviews
         | because reviewers are just joes with couple extra years, if at
         | all, and then whrn things break after deployment, its an
         | absolute pain to debug.
        
         | moron4hire wrote:
         | Those last examples happen when you have variables containing
         | those values. Without strict type checking, it gets really hard
         | to know in all situations (especially when you're pulling
         | values from a service) what you will have in there. And if a
         | service changes, you won't have a lot of warning in your client
         | code. So yes, these kinds of errors are very common.
        
         | lkjoi23j3oijf wrote:
         | In C# you don't have such a problem and 0.2 + 0.1 is exactly
         | 0.3. Proof:
         | 
         | https://dotnetfiddle.net/qTiq6U
        
           | viraptor wrote:
           | In every language where you can use a decimal the result will
           | match exactly. That's... not what's discussed here and it's
           | not a default in c# either.
        
             | lkjoi23j3oijf wrote:
             | Unlike other languages, in JS you don't have decimals... So
             | you stuck writing a garbage code by multiplying all
             | floating point numbers by a factor to avoid rounding
             | errors.
        
               | esrauch wrote:
               | I don't think that's fair: C# has decimals but everyone
               | uses floating point numbers by default so C# developers
               | still need to know that 0.1+0.2 != 0.3
        
               | hajile wrote:
               | The last couple generations of POWER chips from IBM have
               | implementations of decimal32, decimal64, and decimal128.
               | To my knowledge, no other big-name, general-purpose CPU
               | has these.
               | 
               | To "implement decimal numbers" in .net on x86 hardware
               | simply means writing a custom decimal implementation in
               | software.
               | 
               | JS had implicit integers since the beginning. It has had
               | arrays of integers (what's necessary for fast decimal
               | implementations) since BEFORE the release of WebGL a
               | decade ago. It has also added BigInt this year. Just like
               | .net, there's decimal libraries available if you know to
               | use them.
               | 
               | https://github.com/MikeMcl/decimal.js/
               | 
               | The real takeaway is that modern processors should
               | definitely add hardware support for decimal numbers.
        
         | nly wrote:
         | > That's not really a JS problem, that's a floating point
         | problem
         | 
         | More accurately it's a _binary_ problem. 0.1 and 0.3 have non-
         | terminating representations in binary, so it 's completely
         | irrelevant whether you're using fixed or floating point.
         | 
         | Any number that can be represented as the sum of powers of 2
         | and 5 have a terminating decimal representation, whereas only
         | numbers that can be represented as the sum of powers of 2 have
         | a terminating representation in binary. The latter is clearly a
         | subset of the former, so it seems obvious that we should be
         | using decimal types by default in our programming languages.
         | 
         | Oh well.
        
           | tpm wrote:
           | It's not a binary problem, it's a particular binary
           | representation problem. You can represent 0.1 and 0.3 such
           | that it terminates. In Java for example just use BigDecimal
           | (integer unscaled value + integer scale) and you are ok.
        
             | josefx wrote:
             | The floating point standard defines various float types,
             | the common float/double types are called binary32 and
             | binary64. It also defines decimal types.
             | 
             | > integer unscaled value + integer scale
             | 
             | binary float does the same, just using 2^exp instead of
             | 10^exp for scale.
        
           | simiones wrote:
           | In pure mathematics, you can get perfect precision with non-
           | terminating fractions. For example, 0.(6) + 0.(3) = 1 is
           | true. The decimal (or binary) representation is just "syntax
           | sugar" for the actual fraction - in this case, 2/3 + 1/3 = 1;
           | or, if you prefer, 10/11 + 1/11 = 1, or 0.(10) + 0.(01) = 1.
           | 
           | Note: I'm using a notation for infinitely repeating decimals
           | that I learned in school - 0.(6) means 0.6666666...; 0.(01)
           | means 0.010101010101...
        
             | Tainnor wrote:
             | Yes, it's a theorem that every rational number can be
             | represented by a decimal number that is either terminating
             | or repeating.
        
           | denton-scratch wrote:
           | Bring back BCD hardware (hmm. Does x86 hardware have built-in
           | BCD arithmetic?)
        
           | otabdeveloper4 wrote:
           | > 0.1 and 0.3 have non-terminating representations in binary
           | 
           | No. "1", "3" and "10" can all fit easily in just four bits.
           | 
           | Just use rational numbers and solve the problem for good.
        
           | rottc0dd wrote:
           | No, it is problem for any base. For example decimal system
           | can represent 1/5,1/4, 1/8 and 1/2 properly. But, what about
           | 1/3, 1/7, 1/6, 1/9 as decimal numbers with finite number of
           | digits.
           | 
           | This will be a problem for any base representation when it
           | has to be boxed in finite number of digits or memory.
           | 
           | One good thing is decimal is widely used format, so it is
           | good to go with that for representing stuff. But, it is more
           | of an accidental advantage that decimal has. Nothing more.
        
             | rottc0dd wrote:
             | Did not read the whole parent comment and my message is
             | redundant. But, yes, objectively decimal can represent more
             | numbers (the numbers that are composed of 1/2 and 1/5).
             | 
             | I think there are arguments to use decimal as
             | representation is there, (where I originally came to know
             | about this problem) [1].
             | 
             | [1] - https://www.crockford.com/dec64.html
        
               | rottc0dd wrote:
               | Discussion on hn about this :
               | https://news.ycombinator.com/item?id=16513717
        
           | xingyzt wrote:
           | Floating bar numbers are an interesting way of giving
           | terminating representations to more commonly used decimals.
           | Each number is essentially a numerator and denominator pair,
           | with some bits to indicate the position of the division bar
           | separating them.
           | 
           | https://iquilezles.org/www/articles/floatingbar/floatingbar..
           | ..
        
           | Tainnor wrote:
           | While true, there will be rational numbers you can't
           | represent as floating-point numbers no matter which base you
           | choose. And the moment you start calculating with inexactly
           | represented numbers, there is a risk that the errors might
           | multiply and the result of your computation will be
           | incredibly wrong. This is the much bigger "problem" of
           | floats, not the fact that 0.3 is not "technically" 0.3, but
           | off by some minuscule number.
        
         | jandrese wrote:
         | Knowing that the underlying representation will vary is CS101
         | material. It applies to almost every language because that's
         | how the hardware works.
        
           | BrissyCoder wrote:
           | Hardware doesn't exist in any meaningful way for 90% or
           | professional programmers anymore.
           | 
           | Way too much abstraction for that to be an argument.
        
             | denton-scratch wrote:
             | I don't agree. Even if you aren't programming
             | microcontrollers, even if you're just building brochure
             | websites for mobiles, you'll do it better if you understand
             | hardware.
        
               | BrissyCoder wrote:
               | > you'll do it better if you understand hardware.
               | 
               | Oh for sure. I agree. That's not what we're arguing
               | though.
        
         | [deleted]
        
         | SuchAnonMuchWow wrote:
         | Some of them are stretched examples, others comes from other
         | languages/constraints (floating point, octal, ...), but some
         | other are legitimately weird and error prone:
         | 
         | [1, 2, 3] + [4, 5, 6] // -> "1,2,34,5,6"
         | 
         | [,,,].length // -> 3
        
           | zdragnar wrote:
           | The first is only weird if you expect the + operator to
           | perform an operation on arrays. It doesn't, so each array
           | becomes a string and those two strings are concatenated.
           | 
           | The second is only weird in that you are constructing an
           | array with implicit undefined values, which is exactly what I
           | would expect to happen if my linter didn't complain about the
           | syntax and I had to guess what might be happening.
        
             | Izkata wrote:
             | > The first is only weird if you expect the + operator to
             | perform an operation on arrays.
             | 
             | Like GP said, comes from other languages. That line can be
             | copy/pasted into python and it performs concatenation.
        
           | lampe3 wrote:
           | I could also make a php is weird page and say:
           | 
           | "WAT $a .= "World!"; ?"
        
             | [deleted]
        
             | guipsp wrote:
             | Yes. You could.
        
           | Sebb767 wrote:
           | > [,,,].length // -> 3
           | 
           | I don't think this is too weird if you think about it. JS
           | allows trailing commas, so the last one is ignored.
           | Effectively this is `[ undefined, undefined, undefined, ]`. A
           | syntax error would have made sense here, but the length of
           | three is a result of the usual syntax rules, not a particular
           | strange quirk of JS.
        
             | SCLeo wrote:
             | Sorry to be pedantic, but `[,,,]` creates holes instead of
             | undefined. They are different, because for example
             | `[,,,].forEach(() => console.info(1))` doesn't do anything,
             | but `[undefined,undefined,undefined,].forEach(() =>
             | console.info(1))` prints three "1"'s.
        
           | FrontAid wrote:
           | Both of these examples are well-known (and not unexpected)
           | behaviours. I assume you already know _why_ it behaves like
           | that. If not, I can explain it.
           | 
           | > [1, 2, 3] + [4, 5, 6] // -> "1,2,34,5,6"
           | 
           | What would you expect instead?
           | 
           | > [,,,].length // -> 3
           | 
           | Is there any use case where you would want to deal with
           | sparse arrays?
        
             | realo wrote:
             | [1,2,3] + [4,5,6]
             | 
             | An addition operation over two numerical vectors of length
             | 3.
             | 
             | I would expect the result to match its inputs and provide a
             | numerical vector of length 3.
             | 
             | Thus: [5, 7, 9]
        
               | fenomas wrote:
               | The issue there is that arrays aren't first class types
               | in JS, they're just objects with numeric property names.
               | 
               | So if applying an operator to arrays spread the operation
               | across all the elements that way, it would imply that the
               | same should happen generally for all object properties,
               | with whatever weird implications that would entail.
               | a.foo = 1         b.foo = 'there'         a + b // { foo:
               | '1there' } ?
        
               | meowface wrote:
               | What language has this behavior by default?
        
               | DangitBobby wrote:
               | Fortran :)
        
             | e3bc54b2 wrote:
             | > [1, 2, 3] + [4, 5, 6] // -> "1,2,34,5,6"
             | 
             | > What would you expect instead?
             | 
             | If I let my first instinct speak:
             | 
             | [1,2,3,4,5,6]
             | 
             | And then if I think a little more, then maybe:
             | 
             | [5,7,9] //with obvious caveats
             | 
             | In no way do I expect what GP actually provided.
        
               | FrontAid wrote:
               | I understand where you are coming from. But the addition
               | operator simply does not have any special handling of
               | arrays. The specification [1] clearly defines what it
               | should be used for: "The addition operator either
               | performs string concatenation or numeric addition." As
               | JavaScript is weakly typed, it is the programmer's
               | responsibility to use proper value types with these
               | operators. That limitation (or advantage?) is also well-
               | known and applies to all weakly-typed languages.
               | 
               | [1] https://tc39.es/ecma262/multipage/ecmascript-
               | language-expres...
        
               | kristiandupont wrote:
               | It seems that by "expected", you mean "expected, by
               | anyone who read the spec" which I don't think is a fair
               | use of that word. Obviously, most JS developers have not
               | and will not read the spec.
               | 
               | I am very happy with JS and TS and I think the coercion
               | rules are easily worked around with linter rules and
               | policies, but they are _definitely_ weird and I think the
               | language would be better if it simply threw exceptions
               | instead. But then, such an issue shoud not be surprising
               | for a language that was designed in 10 days.
        
               | FrontAid wrote:
               | No, I meant "expected by anyone who learned the
               | language". Knowing the addition operator including its
               | limitations is quite basic. I'm not saying you need to be
               | able to solve all this "JavaScript is weird" puzzles as
               | they are mostly non-sense. But you definetely have to
               | know what you can us `+` for.
               | 
               | If someone does not like the ECMAScript specification,
               | that is fine. But at least use a proper unofficial
               | documentation like MDN.
        
               | bryanrasmussen wrote:
               | well I guess the question is then not just what would you
               | expect instead but at what familiarity with the language
               | should one be asking people what they expect of it?
               | 
               | If you ask experts it is because you want to get an
               | actual correct answer, but if you ask neophytes it is
               | because you want to get an answer that might be obvious
               | even if not correct.
        
             | kilburn wrote:
             | > Is there any use case where you would want to deal with
             | sparse arrays?
             | 
             | Not really. Now explain why [,,,].map((e,i) => i) is [,,,]
             | instead of [1,2,3] please ;)
        
               | fenomas wrote:
               | (assuming you're really asking) It's because JS has a
               | notion of array elements being "empty", and the map
               | operation skips empty elements. Basically "empty" means
               | the element has never had a value assigned to it, but its
               | index is less than the array's length property.
               | Array(4)               // [empty x 4]         a=[];
               | a.length=4; a    // [empty x 4]         Array(4).map(n =>
               | n)   // [empty x 4]         [,,1,,].map(n => n)    //
               | [empty x 2, 1, empty]
               | 
               | My go-to way of avoiding this annoyance is
               | "Array.from(Array(N))":
               | Array.from(Array(4)).map((n,i) => i)  // [0, 1, 2, 3]
               | 
               | Alternately there's a recent "fill" method, that assigns
               | all elements (including empty ones) to a given value:
               | Array(4).fill(1)      // [1, 1, 1, 1]
        
         | Tainnor wrote:
         | I've been thinking for a while that modern languages shouldn't
         | default to floating point computations. They're exactly the
         | right thing if you do data stuff or scientific computing, but
         | given how much of the internet relies on things like e-commerce
         | and how often floating point is still misused for dealing with
         | money, coupled with the fact that even many senior developers
         | aren't fully aware of the subtleties of floating point, I don't
         | understand why we keep making them the default.
         | 
         | If a user does need to do scientific computing, they could use
         | a "# use-floating-point" pragma or something so that literals
         | get interpreted as floating point. Otherwise, we map them to
         | rationals.
         | 
         | Of course, doing rational arithmetic is much slower (for
         | example, Gaussian elimination is exponential for arbitrary
         | precision rationals, while it's famously O(n^3) for floating
         | point), so there's a danger of people accidentally using it in
         | triply nested loops etc., but I have a feeling that if you need
         | to do that kind of thing you know that you might run into
         | performance issues and you think twice.
        
           | denton-scratch wrote:
           | > "# use-floating-point" pragma
           | 
           | I haven't come across the "pragma" directive in a Javascript
           | context. I guess it's another new feature (I have trouble
           | keeping up these days).
        
             | Tainnor wrote:
             | I don't think they have it (although, you can do whatever
             | you want with babel nowadays, I guess). It was a suggestion
             | aimed at programming languages in general.
        
               | akiselev wrote:
               | The javascript equivalent would be an expression like
               | 'use strict';
        
           | otabdeveloper4 wrote:
           | Having the full number stack supported (natural numbers -
           | integers - rationals - reals) would be, indeed, awesome.
           | 
           | Sadly, most people don't understand the distinctions, so this
           | will never happen. (Even in reply to your post people keep
           | talking about "decimals", as if the number base is at all
           | relevant here.)
        
             | JoshuaDavid wrote:
             | "Decimal" usually refers to a data type which is "integer,
             | shifted by a known number of decimal places". So, for
             | example, if you had an amount of money $123.45, you could
             | represent that as a 32-bit floating point number with
             | (sign=0 (positive), exponent=133, mantissa=7792230) which
             | is 123.4499969482421875, but you would probably be better
             | off representing it with a decimal type which represents
             | the number as (integer part=12345, shift=2), or as just a
             | straight integer number of cents.
             | 
             | The number base _is_ relevant, because money is discrete,
             | and measured in units of exactly 1 /10^n, and if you try to
             | use floating point numbers to represent that you will cause
             | your future self a world of pain.
        
           | Flimm wrote:
           | I agree. I think a high level programming language like
           | JavaScript should default to the more "correct" (least
           | surprising) behaviour, and let the programmer opt in to
           | floating point numbers when needed for performance.
           | 
           | In modern JavaScript, you can use BigInt literals by
           | suffixing an _n_ , like this:                 const
           | maxPlusOne = 9007199254740992n;
           | 
           | If I could magically redesign the language, I would make all
           | integer literals be effectively BigInt values, and I would
           | make all decimal literals be effectively decimal values so
           | that 0.1 + 0.2 === 0.3. I would reserve the letter suffixes
           | for more performant types like 64-bit floating point numbers
           | that have surprising behaviour.
        
         | epidemian wrote:
         | you're right in both points technically, but if that means that
         | somehow these things don't make JS "weird" for people to
         | learn/program, then i disagree
         | 
         | > that's a floating point problem. Plenty of languages will
         | have the same issue.
         | 
         | yes, many (most) other languages do have the same floating
         | point issues, but that doesn't make them less weird. JS numbers
         | are IEEE floating point numbers, therefore floating point
         | issues/weirdness _are_ also JS issues /weirdness :)
         | 
         | > Calling these things weird is fair enough but I can't help
         | thinking this is code you'd never actually write outside of the
         | context of a "Look how weird JS is!" post.
         | 
         | the verbatim code snippets in particular, yes, you're
         | completely right. but the underlying problems that these
         | snippets exemplify are still there on actual "real" running
         | code. they just look less suspicious on the surface.
         | 
         | > Just be moderately careful about casting things from one data
         | type to another and all these problems go away.
         | 
         | true. but still, these things _can_ happen, and when they
         | happen, they tend to sneakily manifest as weird UI bugs, like
         | rendering  "NaN" or "undefined" on the screen (we have all seen
         | those... there's plenty of meme images about them too), instead
         | of noisily breaking with an exception, which is way more
         | noticeable and actionable for us programmers when doing
         | introducing these bugs in the first place hehe.
         | 
         | it's true that they are not the most common kind of bugs, i'll
         | give you that, but when they happen, they can be incredibly
         | frustrating in my experience, because you may only realize
         | after they have been affecting user for a looong time (maybe
         | years), but you just didn't know because JS decided it was a
         | good idea to carry on after one of these nonsense operations
         | like adding an array to a number, giving you nonsense results
         | instead of useful (runtime) type errors.
         | 
         | story time!
         | 
         | i remember an ugly case of this which involved some search
         | filters on a big-ish system. the JS code was quite generic in
         | how it handled filters, and looked fine. for some time, all
         | filters were single-value, as simple strings, but at some point
         | the system started handling multi-value filters, which were
         | encoded as arrays of strings. well, the programmers who
         | implemented the UI for multi-valued filters just tried sending
         | array of strings as filters to the existing filtering system,
         | and it seemed to work correctly in the results it yielded, so
         | they assumed the code was prepared for that too (it looked
         | generic enough), and so they shipped the feature that way.
         | 
         | it was only years later, when i was porting some of that code
         | to typescript, that typescript complained about invalid type
         | operations. i was converting between languages pretty willy-
         | nilly and assuming the existing system worked correctly, so i
         | suspected typescript was being dumb with that type error. but
         | no, it was actually complaining about an actual bug. when
         | passing arrays of strings as filters, the underlying filtering
         | system was at some point coercing those arrays to strings by
         | accident. so ['apples', 'oranges'] became 'apple,oranges'.
         | 
         | the search results were always right when the multi-valued
         | filters had only one value (because ['apples'] coerced to
         | string is 'apples') and _kinda_ right in some naive cases of
         | multi-valued filters (because of how the text search engine
         | worked), which was probably why the original programmers
         | thought it was working correctly and didn 't give it much more
         | though or more thorough testing. but the search results were
         | definitely _not_ correct in most non-naive cases of multi-
         | valued filters.
         | 
         | so our users had been affected by this bug of multi-value
         | search filters basically not working for _years_ , and we only
         | discovered it by accident when porting some of the JS code to
         | typescript because typescript was kind enough to tell us about
         | this nonsense operation statically, without having to even run
         | the code. i wish that JS were also kind enough to complain
         | about these nonsense operations, albeit at runtime. it would
         | have made this problem obvious from the get go, and would have
         | prevented the original programmers from shipping a broken
         | feature to thousands of users.
         | 
         | plot twist: although the story may make it seem that i was the
         | competent programmer that figured it all out when porting the
         | code to typescript, in reality "the original programmers" also
         | included me (probably, i don't remember really), just some time
         | before the typescript port :/
        
         | viraptor wrote:
         | I think the situation is a bit different. This situation looks
         | different in reality. The result may be (null-0)+"0", but the
         | actual code will be foo()-bar()+baz(). And C will at least give
         | you warning about types, even if NULL-0+"0" could give you an
         | address. Plain JS without extra tooling would happily give you
         | the unexpected result. Some other dynamic languages would at
         | least throw an exception about incompatible types for -/+.
        
           | bboylen wrote:
           | Yeah guess this is where Typescript comes in
        
             | _nub3 wrote:
             | TypeScript wont magically fix type errors. It is not that
             | hard, to sanitize any expected parameter for functions and
             | their output, typescript wont do that for you. So if you
             | typecheck i/o values per se, using typescript only slows
             | down dev process, as this can be easily done in vanilla
             | javascript. no need for more bloat, but only for some
             | defensive programming.
        
               | applecrazy wrote:
               | > no need for more bloat
               | 
               | What bloat are you referring to? TS compiles down to
               | plain JS.
        
               | blacktriangle wrote:
               | Toolchain bloat is still bloat.
        
               | nawgz wrote:
               | To call TypeScript, a very strong type system which
               | compiles down to terse JS with no extra JS for even
               | complex types, and thus accordingly removes the need for
               | all sorts of tests, "toolchain bloat" is just exceedingly
               | ignorant.
        
               | nawgz wrote:
               | TypeScript "magically" fixes the need for defensive
               | programming by ensuring you won't write unsanitary code
               | or invoke functions with possibly null&undefined values
               | by accident. So then clearly the defensive programming is
               | the bloat, because you could avoid it entirely by putting
               | a type system in place to prevent you ever putting
               | yourself in a situation where null&undefined get passed
               | to functions you don't want it to be.
        
           | Guthur wrote:
           | Because it's more to do with weak typing as opposed to
           | dynamic typing. Many dynamic languages are strongly typed.
        
           | brobdingnagians wrote:
           | We've had these exact same sorts of issues in PHP. It can go
           | undetected for awhile and cause subtle bugs. A good type
           | system helps a lot. I appreciate that Kotlin is more
           | stringent than Java with no implicit conversions between
           | Int/Long/Float/Double.
        
             | deergomoo wrote:
             | I once lost most of an afternoon debugging an issue where
             | orders in a PHP e-commerce system would very occasionally
             | fail.
             | 
             | Turns out several months before, someone was doing some
             | refactoring, moved some methods around, but also changed a
             | "==" to a "===" in the process. Generally a good idea, but
             | it slipped through to production without anyone noticing or
             | breaking any tests.
             | 
             | The issue ended up being that a rare code path in a
             | tangentially related method would cause that method to
             | return a float instead of an int. This propagated through,
             | eventually causing a check of 0.0 === 0 to fail where
             | previously 0.0 == 0 passed.
        
               | irrational wrote:
               | The problem here is == was used in the beginning. Always
               | use ===.
        
               | johnmaguire wrote:
               | Unfortunately "use X from the beginning" is rarely a
               | solution when you're no longer at the beginning.
        
       | lkj23ioj233i wrote:
       | What's wrong with JavaScript? It's existence.
        
       | GlennS wrote:
       | This covers most of the weirdness with primitive types, but then
       | we have an oddly designed OO system on top of that: prototypes +
       | `this` and constructors + classes bolted on.
        
         | sesm wrote:
         | It may seem odd, but it got clear to me once I understood the
         | basic idea.
         | 
         | In a language like Java you have objects and classes at the
         | bottom of the language. How would you add maps to the language?
         | Well, you create a Map class, implement put, get, has methods,
         | etc.
         | 
         | Now imagine a language where you have functions and maps as
         | your basic primitives, but you don't have classes and objects.
         | How do you add objects and classes to the language? You can do
         | something like this: objects are maps, information about their
         | basic class is saved in 'prototype' property, constructor is a
         | function that returns an object, etc. That's how JavaScript
         | works. You can read about this in more details here
         | https://exploringjs.com/impatient-js/ch_proto-chains-classes...
         | , if you keep the basic idea in mind the details are easy to
         | follow.
        
       | chrismorgan wrote:
       | > _25. - "" + + "1" * null - [,]_
       | 
       | > _Output: 0_
       | 
       | > _You answered: I give up_
       | 
       | > _You answered incorrectly._
       | 
       | No I didn't.
       | 
       | (Not my fault there were two potentially correct answers!)
        
       | dna_polymerase wrote:
       | > JavaScript is a great programming language
       | 
       | I have no idea how you could come up with this sentence after
       | this brilliant display of what an insanely stupid language
       | JavaScript is.
        
         | krylon wrote:
         | To be fair, just because a language allows you to do stupid
         | things, doesn't mean that it's bad.
         | 
         | C, C++, Perl (oh, Perl!) allow you to do weird things, too, so
         | do lots and lots of other languages.
         | 
         | A certain knowledge of this weirdness is very helpful, though,
         | in avoiding it.
        
           | dolmen wrote:
           | In fact Perl 5 has less weird coercion rules than JavaScript.
        
       | Zababa wrote:
       | I really think we should stop pushing things like that or the wat
       | talk (https://www.destroyallsoftware.com/talks/wat). Sure it's
       | funny and all, but it's not helping people understand. We're
       | presenting Javascript as some kind of stupid black magic tool,
       | which is not. You can very easily find the standard online, and
       | go through the examples to understand. Sure it's unintuitive, I
       | agree, but lots of things in programming are unintuitive, and
       | when you can't change them you have to learn them.
        
         | snet0 wrote:
         | I don't even think it is unintuitive. There are very few things
         | here (if any) that make _no_ sense, and a few are literally
         | just basic understanding of floating point spec. And then of
         | course a few questions are basically obfuscated-C levels of
         | code, where you won 't get the answer correct unless you get
         | your pen and paper out.
         | 
         | I'd argue that if you don't know about type coercion in JS, you
         | don't _really_ know JS. It 's a feature; none of these
         | operators will throw; it's a conscious design choice.
        
       | vvoyer wrote:
       | I stopped at the first example (true + false).
       | 
       | If you write code like this, you have bigger problems than using
       | JavaScript. For most of the examples, it's like saying "Here's
       | what happens when you plug a fan to a faucet". There's no point
       | really.
       | 
       | JavaScript is weird just like any other language can be weird
       | when you use it in weird ways. And yes, it's certainly one of the
       | weirdest.
       | 
       | If you want to talk about things weird in JavaScript, let's talk
       | about ES modules in Node.js and the Browser, or the number of
       | decisions you have to make to bootstrap a simple web app in
       | JavaScript, and how a language written in 10 days is shipped to
       | billion of devices today.
       | 
       | But, this kind of content, (while well made technically) is
       | always the same one about JavaScript.
        
         | qayxc wrote:
         | > I stopped at the first example (true + false).
         | 
         | So you never did something like this:                 x =
         | performCalculation(getParam1())       y =
         | performCalculation(getParam2())       sum = x + y
         | 
         | only to discover that "performCalculation()" sometimes returns
         | a boolean instead of a number? JS is a dynamically typed
         | language after all and functions like                 function
         | f(x) {         if (x >= 0) {           return Math.sqrt(x)
         | } else {           return false         }       }
         | 
         | are perfectly valid. If you use a 3rd party library that uses
         | return values like this, you might run into such case without
         | realising it.
         | 
         | Sure, you won't explicitly write "true + false", but "f(x) +
         | g(x)" is not uncommon and might indeed evaluate to "true +
         | false".
        
           | hajile wrote:
           | I've not run into that kind of issue in years. Read the docs
           | of the function you're attempting to call.
           | 
           | Also, in this case, the function should return NaN so it's
           | not polymorphic.
        
             | qayxc wrote:
             | > Also, in this case, the function should return NaN so
             | it's not polymorphic.
             | 
             | Sure. But what if that's function comes from a 3rd party
             | component that doesn't have great documentation or relies
             | on another package and thus a behaviour like this simply
             | bubbles up through the call chain?
             | 
             | And don't think this can't happen - NPM in particular
             | notorious for this kind of deep dependencies. Also mixins
             | and monkey patching are a thing in JS, so just importing a
             | module can lead to an unexpected change in behaviour.
        
           | DarkWiiPlayer wrote:
           | some people will be quick to say "oh but then the library is
           | just awful". Yes. Yes it is. Sometimes one _has_ to work with
           | brain-dead stupid libraries, and in those cases, it 'd be
           | much easier if JS would just give you an error saying what
           | happened: You're trying to multiply apples with oranges.
        
           | wwosik wrote:
           | Typescript to the rescue ;)
        
       | ecmascript wrote:
       | Yes Javascript is weird but at the same time you almost never
       | face many of these issues in the real world. Bad things exist in
       | all languages, for some maybe there isn't the same in the sense
       | of actual quirks in the language but rather other things that
       | limit the language in some way.
       | 
       | I have been a web dev for about 10 years now and I rarely if ever
       | run into these issues. More likely, I face issues and bugs
       | regarding state and just flaws in the logic rather than issues
       | based on that the language wasn't designed so great.
       | 
       | For sure this can be worrying if you do something really
       | important but at the same time you have a lot of other languages
       | to choose from.
        
       | lampe3 wrote:
       | Why are people wasting time on sites like this?
       | 
       | Every programming language has some weird stuff in it.
       | 
       | If you are writing code like that then you are the problem not
       | the language.
       | 
       | Is this just for the clicks? Is this developer click bait?
        
         | leodriesch wrote:
         | I took the quiz and enjoyed it. Just have some fun, I don't
         | think the quiz wants to convey any deeper message.
        
         | vvoyer wrote:
         | ^ This! It's "learning content" for tiktok-devs I guess.
        
       | pdpi wrote:
       | I have plenty of complaints about Javascript, but most of these
       | aren't it. I haven't done any serious javascript in something
       | like 6 years, and I still got most of this right without much
       | effort.
       | 
       | #4, #13, #14, #21 and #24 are floating point problems and are
       | nothing to do with JavaScript.
       | 
       | A bunch of them are just "learn the language" issues:
       | 
       | #2 I only got wrong because I never noticed JS allows trailing
       | commas. Trailing commas are pretty damn common in most modern
       | languages though. The syntax for empty initialisation of arrays
       | is weird (and I'd argue is a mistake), but the behaviour is
       | exactly what you'd expect.
       | 
       | #5 is the comma operator as also seen in C and C++.
       | 
       | #8 is something nobody should get wrong. Three nots in front of a
       | true is false. Of course it is.
       | 
       | #10 is just an octal literal. They're becoming increasingly rare
       | in modern languages, and were never quite as common as hex
       | literals, but they're also not terribly obscure.
       | 
       | #15 is one I'm slightly ashamed I got wrong. It makes no sense to
       | use increment operators on a bare value. This is common to just
       | about all languages that support increment operators (and it's
       | those, if any, that don't agree are in the wrong)
       | 
       | #22 is a slightly surprising counterpoint, but it also makes
       | sense. I don't know of a language that has a NaN literal, and
       | JavaScript is no exception. So that NaN is actually a global that
       | is bound to the floating point value NaN. Because it is a global,
       | it can be incremented (but incrementing NaN is still NaN).
       | 
       | Everything else is a type coercion issue.
       | 
       | #18 and #23 are coercions I really disagree with. Coercing things
       | to a number shouldn't produce NaN. That truly is crazy. Throwing
       | is the only reasonable behaviour here. Ruby is even worse than JS
       | here ("true".to_i produces 0), Python gets it right.
       | 
       | Other than that, the coercions are all fairly make sense, and are
       | consistent with what other languages do. Now, implicit type
       | coercion (especially under the guise of abstract equality) is a
       | terrible idea because it's easy to do it by accident and get
       | nonsensical results, but the coercions themselves are, by and
       | large, pretty sane.
        
         | Izkata wrote:
         | > #2 I only got wrong because I never noticed JS allows
         | trailing commas.
         | 
         | No one used to risk it because IE was inconsistent with what it
         | meant.
        
       | Demiurge wrote:
       | I love that 1/0 = infinity in JS. It's as pragmatic as a tired
       | student doing their algebra homework at 1AM :))
        
         | an1sotropy wrote:
         | Like others have already noted; 1/0 == inf is something about
         | JS, it is a consequence of JS defaulting to IEEE754 floating
         | point representation for all numbers. Any language that
         | supports IEEE754 FP will have the same result.
        
       | davidkunz wrote:
       | Nobody programs like that, so it's not an issue in real-world
       | applications.
        
         | qayxc wrote:
         | I would agree if wasn't for the fact that JS is a dynamically
         | typed language.
         | 
         | You can (and sometimes will) run into instances of this without
         | noticing, because while you won't explicitly write
         | true++
         | 
         | you might do something like                 x = someFunction()
         | x++
         | 
         | not realising that someFunction() might return a boolean under
         | some circumstances.
         | 
         | Anyone who worked with a sufficiently large JS codebase ran
         | into one of these cases and got unexpected results at some
         | point due to this.
        
           | davidkunz wrote:
           | This is true, one must always make sure to handle all
           | possible return types, but that's true for all dynamic
           | languages.
        
           | wruza wrote:
           | true++ and x++ are syntactically different though. The latter
           | is a post-increment of an identifier, and the former is a
           | post-increment of a boolean literal. Different rules may
           | apply to these cases.
        
         | noisem4ker wrote:
         | Nobody uses straight edge razors for juggling, so they're not
         | dangerous when shaving.
        
       | zwarag wrote:
       | Could [,,,] be used to optimize an array allocation? Say I'll
       | need an array of fixed size. Could this method be used to help
       | the interpreter to allocate an array more efficiently?
        
       | usagitoneko97 wrote:
       | I have limited knowledge in web development and its history, but
       | why is javascript a first class language in web dev when all I
       | heard is "javascript bad"? Web assembly seems like a much better
       | choice in hindsight where you can choose different language to
       | compile down to wasm.
        
         | golergka wrote:
         | Modern Javascript, and especially compiled-to-javascript
         | languages, like Typescript, Reason, Elm and others, are quite
         | great. Those quirks are funny and weird, but it's not something
         | you actually run into when you write code that isn't actively
         | trying to show the weirdness of javascript.
        
         | fulafel wrote:
         | Most real world non-JS frontend code compiles to JS, not Wasm.
         | Lots of apps written in ClojureScript, TypeScript, Elm etc.
         | These are mature and Wasm has mostly only disadvantages to
         | offer.
        
         | wruza wrote:
         | In general, a scripting language for a software product (a
         | "browser" being one of them) may be easily substituted in most
         | cases. Because this integration always has a clear API border
         | than can be retargeted to another scripting language in a
         | straightforward way. E.g. vim text editor has vimscript as its
         | main scripting environment, but may be compiled (in addition)
         | with perl, python, lua, tcl, ruby interfaces.
         | 
         | But guys who control web standards resisted for decades to
         | suggestions for other languages, though it was fine to have
         | flash/activex for the same period of time, until Apple killed
         | it for good. Even JS "2.0" (a theoretical better but
         | incompatible version of itself) had no chance, because reasons.
         | 
         | Javascript is okayish generally, but its unusual parts come
         | from the times when it was used as a glue between textual
         | inputs and some~ data structures.
         | 
         | Stroustrups' phrase is just a stockholm syndrome (in his case
         | self-induced).
         | 
         | Edit: webassembly support is not really required to transpile
         | anything to a browser, see asm.js
        
         | lol768 wrote:
         | WASM support hasn't been around for long, comparatively - and
         | I'm not sure if there's been any recent headway with DOM
         | manipulation or GC from WebAssembly.
        
         | Santosh83 wrote:
         | Webassembly is too recent. It needs to catch on. The momentum
         | behind Javascript/Node is _huge_ beyond comprehension. The
         | engineering that has been poured into the JIT is also quite
         | something. Just scrapping all of this and starting again with
         | Wasm is not going to get traction from anyone.
        
           | BenFrantzDale wrote:
           | Can you explain "Javascript/Node"? I thought Node.js was a JS
           | interpreter but not the interpreter used in the major web
           | browsers. Rather, that Node is an interpreter that's used to
           | run Js in (typically) headless (server) environments,
           | allowing both sides to be written in JS. Is that accurate?
        
             | madeofpalk wrote:
             | > Node.js is a JavaScript runtime built on Chrome's V8
             | JavaScript engine.
        
         | jraph wrote:
         | WASM is not a good solution in a lot of situations. In short:
         | 
         | - you have to package your complete runtime in the Wasm binary,
         | this leads to a large binary and memory footprint
         | 
         | - DOM manipulation requires calling Javascript code, and
         | calling JS from WASM is costly
        
           | hazz99 wrote:
           | You only need to package your runtime if you're using a
           | language that requires a runtime :)
           | 
           | Languages that perform their own memory management (C, C++,
           | Rust etc) will be extremely small. Just one big array of
           | bytes/instructions.
        
             | jraph wrote:
             | you still need to provide their standard library, at least
             | the subset used by your program
        
         | Zealotux wrote:
         | "There are only two kinds of languages: the ones people
         | complain about and the ones nobody uses." - Bjarne Stroustrup
         | 
         | JS may be weird, but the kind of weird that works well enough
         | and is rather easy to pickup and maintain with reasonable rules
         | in place. When it comes to JS my empirical experience has often
         | been: most of the time, the issue is situated somewhere between
         | the keyboard and the chair.
        
         | jokoon wrote:
         | GMail managed to be popular thanks to the XMLhttprequest()
         | function being implemented in internet explorer. Microsoft had
         | a monopoly on software, but it was still possible to do things
         | through a web browser, enabling competitors and websites
         | running on linux.
         | 
         | Javascript got popular because it was here first, so developers
         | used it and became able to work with it. When this happens,
         | javascript had inertia which is impossible to stop. Javascript
         | allows one to deploy anything on any platform with a web
         | browser, without copying files.
         | 
         | Webassembly is great, but it's not easy to build WASM files,
         | the toolchain software used (compilers linkers etc) are not
         | mature (only rust can build to WASM natively), and it requires
         | that all language compile to wasm, so compiler developer need
         | to implement a WASM compile "target", which takes time and is
         | not always possible depending on language (python comes to
         | mind, because of its large library, global interpreter lock,
         | etc).
         | 
         | Also, WASM doesn't have access to the DOM or webGL, meaning
         | that you still need to make JS calls to interact with a
         | webpage.
        
           | arkh wrote:
           | > Javascript got popular because it was here first, so
           | developers used it and became able to work with it.
           | 
           | And you could easily copy and learn from scripts before
           | minification became the norm. And you just have to refresh
           | some page after updating your sources to see the result.
        
             | jokoon wrote:
             | Sure, but it's difficult to make newcomers understand why
             | the language still has those nasty behaviors.
             | 
             | In essence, it's very expensive to risk losing backward
             | compatibility or to make large portions of js software
             | obsolete just to remove some bit of language ambiguity.
             | 
             | It's very frustrating but it's true for all languages out
             | there. Same concept when linus torvalds yells "YOU DON'T
             | BREAK USERSPACE". Backward compatibility almost has its own
             | philosophical chapter on software design.
             | 
             | Also remember how painful it was from switching from python
             | 2 to 3. I guess a solution would be heavy usage of linters,
             | typescript or other compile-to-js solution, but in the end,
             | a lot of developers are just wishing very hard for better
             | solutions.
             | 
             | Personally I am really not willing to become a professional
             | JS dev. I'm too perfectionist and nitpicky to have the
             | courage to suffer so much for such thing. Deep down I know
             | it's a bad choice, but I'm too lazy.
        
         | pansa2 wrote:
         | Using WebAssembly currently means programming in C, C++, Rust,
         | or maybe Go. Despite its flaws, many people prefer programming
         | in JavaScript over any of those lower-level languages.
        
           | fulafel wrote:
           | Those are fortunately not the only options, there are many
           | nice HLLs around that compile to JS.
        
         | fmakunbound wrote:
         | If you have limited exposure to JavaScript, that's great. Try
         | to keep it that way. Personally, the article/quiz reminds me
         | what an utter shit field web development really is and that
         | shaving my face with a lawn mower and hot sauce might be the
         | preferable alternative. Also, reading the sibling comments here
         | describing JavaScript as having characteristics like "great
         | defaults" and "reasonable rules in place" make me wonder what
         | fucked up alternate reality they're all living in where those
         | are true.
        
       | superasn wrote:
       | I think a lot of these errors can be fixed with using strict
       | types, aka Typescript.
       | 
       | I've had the same issues with PHP in the past too, which makes me
       | believe that whosoever created these languages had ease of use as
       | a higher priority than strictness, i.e. it's okay to assign bool,
       | int, string to the same variable.. just get the job done.. okay.
       | 
       | On the other end of the spectrum is a programming language like
       | Pascal (or object Pascal which I used for some time) where I had
       | to write so much boiler-plate code that it made a simple job
       | difficult. Maybe good for big projects but checking if email is
       | valid before form submission, it may be too much boiler-plate
       | code for some people with such traditional languages.
        
         | dan-robertson wrote:
         | _strict types_ and _Typescript_ are not synonyms. Perhaps you
         | meant to write "for example" instead of "aka." And furthermore
         | there tends to be some disagreement about the meaning of the
         | words strong /weak, static/dynamic, strict/lax when talking
         | about type systems. Indeed Typescript is quite a weak
         | typesystem in that type checking does not very fully guarantee
         | useful correctness properties about your program because it
         | allows for missing type annotations.
        
           | goodoldneon wrote:
           | I love the HN comment section -- one of the best I've seen on
           | the web. But nitpicking this use of a.k.a. doesn't add
           | anything to the conversation. We all know what they meant,
           | since virtually no one thinks that TypeScript is the only
           | strictly typed language in existence.
        
         | jmkni wrote:
         | I had a similar feeling recently using Swift for a project.
         | 
         | Pure JavaScript is definitely a bit too loose for my liking,
         | but I thought Swift went a bit too far in the other direction.
        
           | Aaargh20318 wrote:
           | I had that experience with Swift for maybe the first 2 days I
           | used it. Nowadays I really appreciate Swift's strictness. It
           | just helps prevent so many stupid mistakes.
           | 
           | I worked on a high-profile project for my company under a
           | strict deadline and Swift was a major part in ensuring we
           | delivered a rock-solid implementation in record time.
        
             | kalleboo wrote:
             | The only part of the type system that I feel gets tedious
             | is dealing with numbers, where you're continually casting
             | back and forth between Int, Float, Double, CGFloat (at
             | least the latter is being addressed). I get why it's strict
             | about it due to loss of precision and the madness of
             | floating-point numbers, but sometimes you just don't care
        
               | Aaargh20318 wrote:
               | The number things isn't that big of an issue once you get
               | used to considering what type your numbers should be in
               | advance, instead of going back and forth between number
               | types, pick one that's appropriate and stick to it.
        
       | jokoon wrote:
       | That was the most horrible quizz I've ever taken in my life.
       | 
       | I recently tried to make a simple flask app to sort pictures on
       | my computer. I used file:/// since there were a lot of them.
       | 
       | I was quite unhappy to discover that CORS is quite restrictive...
        
       | jfoutz wrote:
       | Eh. I'm not a JavaScript developer, just winging it I got 9/25.
       | Seems like there are 3 broad categories of (my) confusion. 1.
       | floating point. Floating point is tricky, and when I use it
       | seriously I have to look up a lot of special cases. I often
       | forget I can get Nan, and it'll infect everything it touches.
       | This is common in just about any language.
       | 
       | 2. One or two of those , questions got me. I don't _hate_ it, but
       | there's a little frustration there. Mostly I just need to know
       | the syntax. If I was writing javascript for money, I imagine it
       | would bite me once or twice, then I'd just memorize the rule.
       | 
       | 3 (the biggie) implicit conversion. Oof. seems like a lot of
       | types can be converted to other types, and it's not obvious to me
       | what the precedence hierarchy is. With C I have to look up the
       | edge cases around signed/unsigned, but usually it's just use the
       | next bigger one int -> long. Java does the .toString for
       | everything which has bitten me once or twice. I really don't have
       | a sense of javascript implicit conversion. Some of those seem
       | really subtle.
        
       | Tade0 wrote:
       | Fortunately nowadays including any of those in your code would
       | award you the review equivalent of bashing your head in.
       | 
       | With the advent of linters most of these patterns started being
       | rightfully considered bad form by default.
       | 
       | Currently even innocent stuff like _+new Date()_ (outputs a
       | timestamp) is already something that I 've rarely seen make it
       | through review.
       | 
       | JS is goofy, but ES2015 managed to avoid making the same
       | mistakes. Shame it took so long to implement it.
       | 
       | At the moment the bigger problem is the painful transition from
       | whatever module system you had to ES Modules.
       | 
       | Especially browser<->Node.js interoperability suffered massively
       | from this.
       | 
       | Hopefully there will be no further standards in this field.
        
         | phist_mcgee wrote:
         | I am eternally surprised at how long it took node to support
         | ESM. CommonJS modules served their purpose, but they are about
         | to go the way of JS module systems. This is where the appeal of
         | deno comes in. It's a runtime that tries very, very hard to
         | give you the same API surface as that of the browser. I just
         | hope deno catches on faster.
        
           | Tade0 wrote:
           | I consider Deno to be DOA - hopefully I'm wrong.
           | 
           | The scope was just too broad.
        
       | SCLeo wrote:
       | Probably unpopular opinion: Most of these are just the weirdness
       | of the language caused by the (not-so-wise) design decision that
       | those simple operators should never throw. In my opinion, these
       | are not footguns and should not be used to attack JavaScript,
       | because regular programmers are very unlikely to run into them
       | (which is why when presented, they seem so obscure).
       | 
       | However, that is not to say JavaScript is without footguns. For
       | example, the classic `[1, 2, 3, 10].sort()`.
        
         | edgeform wrote:
         | > these are not footguns and should not be used to attack
         | JavaScript
         | 
         | No one is calling them that except you. The site says it _right
         | at the front_ :
         | 
         | > most of this syntax is probably, and hopefully, not something
         | you use in your daily life.
         | 
         | Your obsession with having to choose Side A or Side B won't let
         | you see this for what it is...
         | 
         | Just showing weird syntax in JS. That's all. Good lord.
        
           | zild3d wrote:
           | the title is "javascript is weird", not "here's some weird
           | syntax in javascript"
        
         | mherrmann wrote:
         | JavaScript sorting numbers alphabetically is a fact I simply
         | cannot get over. I know I should be pragmatic as an engineer
         | but this goes against the core of my being. Awful.
        
           | jonny_eh wrote:
           | It also alters the original array, just awful usability.
        
           | epmatsw wrote:
           | Since it's (imo) default-wrong in English, I've chosen to
           | think of it as a nice way to point devs to something that's
           | locale-aware like Intl.Collator instead. If it "just worked"
           | in English, most of us would never think to use the correct
           | utility instead.
        
             | mokus wrote:
             | This is a bit of a tangent, but that makes me wonder... are
             | there any languages where this particular collation _would_
             | be correct?
        
         | DarkWiiPlayer wrote:
         | Most of these edge cases should result in clear errors. Chances
         | are, if you're adding two arrays somewhere in your application,
         | something else has gone terribly wrong, and just telling the
         | programmer "this makes no sense" would be a much more sensible
         | solution than returning garbage and letting it cause problems
         | somewhere else, further from the real cause of the problem.
        
       | MaXtreeM wrote:
       | Based on the comments half of the people didn't read the
       | introduction.
        
       | eastbayjake wrote:
       | UX nit: would have preferred question-by-question feedback on
       | right answer and overall score, quite a lot to get through 25
       | questions before you get any reward for your effort :)
        
         | uses wrote:
         | Same - it was clear to me by question 2 that I was going to be
         | guessing on the rest of the quiz. Having to fill out the rest
         | before getting feedback was a formality at that point.
         | 
         | By the time I saw the answers, I couldn't remember why I
         | guessed which way on each question.
        
         | SavantIdiot wrote:
         | I don't think it is a UX nit. You would have started to catch
         | on and learn if you had immediate feedback.
         | 
         | When is the last time you took an in-person test where the
         | proctor told you if you were right/wrong after every question?
         | 
         | You need to grade current knowledge. In fact, I would have
         | removed the multiple choice altogether for this test and had a
         | input(type=text)
         | 
         | EDIT: OK, ok: I get it, it is just a fun website, not the BAR.
        
           | some_random wrote:
           | I'm trying to look at weird javascript, not haze new
           | employees.
        
       | whoomp12342 wrote:
       | TIL I dont know js.
        
       | gherkinnn wrote:
       | These examples are amusing but irrelevant.
       | 
       | What I find sorely lacking is sane syntax for working with
       | arrays. Eyeing Python with envy every time.
       | 
       | And some pattern matching would be nice too.
        
         | DarkWiiPlayer wrote:
         | Special syntax for specific data structures are exactly why I
         | hate so many languages. No. We don't need more of that garbage.
         | Map & co. do everything you need and adding yet another
         | syntactic construct on top of it would just break the language
         | even more.
        
         | Joeri wrote:
         | Both are stage 1 proposals that I hope get in there some day.
         | 
         | https://github.com/tc39/proposal-slice-notation
         | 
         | https://github.com/tc39/proposal-pattern-matching
        
       | jonplackett wrote:
       | I did incredibly badly. JS really is weird.
        
       | asimpletune wrote:
       | I've taught programming to people who struggled because they were
       | misusing JS and the answer they were getting back coincidentally
       | worked for some inputs but not others.
       | 
       | Imagine trying to explain to them that this was their fault? Even
       | trying to find the words to explain what happened made me feel
       | bad that their first experience programming was tarnished by a
       | language that will gladly allow you to do nonsense.
        
         | SavantIdiot wrote:
         | This is why Pascal and COBOL were the CS101 languages at my
         | college. (RPI class of '85)
        
         | ozim wrote:
         | Can it be that JS is not good starting language then?
         | 
         | Maybe strongly typed compiled languages would be a better fit?
         | 
         | One can argue that if you want to program it might be too much
         | information for starters - but IMO basic types are such a
         | fundamental concept that it would be better to teach that
         | concept early on.
         | 
         | It also clears up a lot of newbie confusion as you cannot
         | assign string to an int by mistake with strongly typed
         | language. Such scenarios are then handled by compiler so newly
         | starting dev has quick feedback on fundamental issues with his
         | code without having to ask people around.
        
           | darksaints wrote:
           | The problem with strongly typed languages is that it makes it
           | infuriating whenever you have to work in a language without
           | the same type guarantees. JavaScript made me want to throw my
           | computers off the top of a skyscraper until I discovered
           | typescript, and typescript just barely makes things slightly
           | tolerable.
        
           | asimpletune wrote:
           | Yeah, pretty much everything you mentioned was made clear to
           | me after this.
        
           | denton-scratch wrote:
           | > Can it be that JS is not good starting language then?
           | 
           | @ozim, I don't believe you are trolling!
           | 
           | JS is an absolutely awful language for beginners; it's a
           | 155mm howitzer pointed at your foot. Although you can get the
           | hang of the basics quickly, AND it runs in the browser
           | (super-convenient unless you're headless), those "basics"
           | that you thought you'd got the hang of turn out to have
           | semantics that make sense, but are not what you expected.
           | 
           | I wrote JS (about 0.2 of my time, I guess) for my job, for
           | about 20 years. I got 18 out of 25 on that test. Now, I think
           | it was actually an easy test; I got a third of my answers
           | wrong because I haven't learned about a third of JS
           | semantics. I'm either not very good, or not as smart as I
           | like to think.
           | 
           | A certain recent colleague of mine would probably have got
           | 25/25; he was cleverer than me, and he was REALLY into
           | Javascript.
           | 
           | Try a Pascal-type language, to learn an imperative-type
           | language. Modula2 is better. Learning Prolog is (I think)
           | purely declarative, so it gives you the view from the other
           | side of the curtain - as it were. Forth is a perfectly-
           | feasible beginner's language; it was the second language I
           | learned.
           | 
           | I can't recommend any OO language for beginners. Not because
           | I think all OO languages are way too difficult, only all the
           | ones I've used. I haven't used Smalltalk.
           | 
           | I haven't used any flavour of Lisp. That language is so
           | pliable that I'm sure there's a flavour that would be good
           | for beginners.
           | 
           | [edit] Actually, I wish I had learned a functional language
           | like Lisp as my starting language; I strongly suspect that
           | would have made me a better programmer throughout my career.
        
             | Hermitian909 wrote:
             | Having designed programming curriculum, I have to disagree
             | that the language is a bad language for beginners (though
             | it is _very_ far from ideal).
             | 
             | To be fair the primary reason is not really a virtue of
             | Javascript per se, but the fact that it runs in the browser
             | is a large pedagogical gain that no other language can
             | easily match and is hard to overstate. Learning to program
             | is overwhelming for most students, and setting up your
             | environment is a major component of that. Being able to run
             | your code natively in the browser is a huge boon. Even
             | better, having that code immediately be _useable_ in a very
             | real sense boosts motivation significantly. For most
             | students it really is preferable to let students get very
             | comfortable with basic code constructs before having to
             | interact with the underlying system in any meaningful way.
             | 
             | At the language level, Javascript also has some nice
             | affordances that let you treat constructs as simpler than
             | they are in your curriculum and expand on them later. I
             | think the best example of this is `var`. Viewing variables
             | as uncomplicated "buckets" that happily contain any data
             | you want to shove in them is a good starting place when
             | introducing the very first building blocks of something
             | like if/else control flow.
             | 
             | Most languages are built with semi-experienced programmers
             | in mind and are ill-suited for many beginners and actively
             | bad for children. As an easy example: as a developer I like
             | seeing type specifications for numbers, but pedagogically
             | having to introduce the difference between ints and floats
             | on the first day is just empirically confusing for most
             | students. Much better for them to be "magic" until you can
             | properly motivate them to care (which can be just a few
             | weeks in!)
             | 
             | I could write on this topic far longer than I have, but the
             | short of it is that Javascript has done a truly surprising
             | number of things right for a teaching language. I'd still
             | love to remove some of the zany examples here if I could
             | though.
        
               | jonny_eh wrote:
               | I wonder if Typescript would make a great first language,
               | since a subset of it runs in the browser, but the IDE and
               | compiler can prevent some very bad bugs.
        
               | Hermitian909 wrote:
               | It might be a good extension after they'd spent a good
               | amount of time in plain Javascript, 50-200 hours in
               | depending on age IMO (younger -> more).
               | 
               | Adding types is, again, confusing to most beginning
               | students and adding any sort of build process is asking
               | for tears.
               | 
               | The bugs, while unpleasant, just aren't actually that bad
               | pedagogically. Students readily accept explanations of
               | the form "computers are dumb and do what you tell them,
               | if you tell them to do something that doesn't make sense
               | they will do something that doesn't make sense" which is
               | close enough to correct to not give them a terrible
               | mental that is difficult to unlearn later.
               | 
               | Additionally, at this stage of learning students should
               | be writing many small programs. Such programs are
               | typically easy for teaching aids to debug in seconds (or
               | to suggest a radically simplified re-write).
        
             | ozim wrote:
             | I am not trolling just a honest question based on parent
             | poster experience.
             | 
             | I agree OO is too much for any beginner. Getting started
             | with procedural thinking + basic types is in my opinion a
             | requirement.
             | 
             | I agree nice parts about starting with JS is that basically
             | only things you need is text editor and a browser.
             | 
             | Unfortunately data types will show up one way or the other
             | so there is no need of hiding those. Even in Excel creating
             | formulas one has to understand text vs number and
             | difference between '.' and ',' and how operating system
             | configuration make sometimes '.' to be decimal separator
             | and sometimes ','.
        
       | LW9ucKsYuvuVeBa wrote:
       | > This website is literally about JavaScript. I mean what did you
       | expect, a .NET application? This website is 99.9% poorly
       | optimized and highly questionable JS. And yet, you have JS turned
       | off.
        
       | the_duke wrote:
       | Buggy in Firefox (89): gets stuck on the second question.
       | 
       | Works fine in Chrome.
        
         | jmrm wrote:
         | Works well on Firefox 89.0.2 on Windows 10 :-/
        
         | mikkelam wrote:
         | Same for me in macOS with firefox 89. Disabled all addons and
         | same problem.
        
         | kiwijamo wrote:
         | Works fine in Firefox on Android.
        
         | tgv wrote:
         | Here too (89.0.2, macOS).
        
         | krylon wrote:
         | It worked fine for me (Firefox 89 on openSuse Tumbleweed).
         | Maybe some add-on is interfering?
        
       | nodejs_rulez_1 wrote:
       | _> JavaScript is a great programming language, but ..._
       | 
       | Why are we so afraid to call trash "trash"? It's not attacking
       | the creator, but just how can we make progress if things are not
       | perceived as they are?
       | 
       | https://wtfjs.com
        
         | MaxBarraclough wrote:
         | I wouldn't say it's trash. JavaScript has many ugly quirks, but
         | it has many good facets too, and it can be be used to write
         | effective and fairly elegant code. Considering how quickly it
         | was thrown together, and that's it's been evolving since then,
         | I'd say it's a surprisingly good language.
         | 
         | > how can we make progress if things are not perceived as they
         | are?
         | 
         | People aren't blind to JavaScript's failings. The evolution of
         | JavaScript has been a mix of adding new features and fixing
         | what they got wrong before, e.g. the way it has two different
         | _isNaN_ functions. [0]
         | 
         | [0] https://developer.mozilla.org/en-
         | US/docs/Web/JavaScript/Refe...
        
         | globular-toast wrote:
         | I thought the same thing. I think the author is afraid of
         | offending people. Downvote culture has conditioned a lot of
         | people to walk on eggshells and write this way.
        
           | n4bz0r wrote:
           | Funny how this comment got downvoted into Valhalla in a
           | matter of minutes.
        
         | lkj23ioj233i wrote:
         | because people here wasted years to learn all the quirks in JS
         | and now they should realize all that was a mistake? Much better
         | to downvote negative comments.
        
         | cout wrote:
         | Trash is something you are discarding. If you are keeping it
         | because it still has some utility to you, then it is by
         | definition not trash.
        
           | cies wrote:
           | So I think we should interpret "trash" here as "badly
           | designed".
        
           | anoncake wrote:
           | That's only one of multiple equally valid definitions.
        
         | cies wrote:
         | Loved this video (4mins) of a talk by Gary Bernhardt (CodeMash
         | 2012) on the topic of JS' quirks:
         | 
         | https://www.destroyallsoftware.com/talks/wat
        
           | kuroguro wrote:
           | Yep, the "wat" talk helped, got 17/25 first try since I
           | recalled some of the weirdness.
        
             | cies wrote:
             | > the "wat" talk
             | 
             | so that's what it's called.
        
           | mgerullis wrote:
           | On Twitter he was also talking a lot about his journey into
           | Typescript which I very much enjoyed. Great guy
        
         | lampe3 wrote:
         | the only trash is that comment LooL
        
         | azangru wrote:
         | Is javascript any more "trash" than python or ruby? I don't
         | think so.
        
           | blowski wrote:
           | From what I read on forums, every single piece of technology
           | that's ever been invented is trash according to some self-
           | appointed expert. I doubt I could name a programming language
           | used by more than 100 people about which at least one person
           | hasn't written a crtical comment.
        
             | kingludite wrote:
             | Elixir?
             | 
             | I've never used it but reading about it I kept going ohh,
             | ahhh and wow! In stead of my standard: ** ** * _k * ** *_
             | sh?!?
        
               | blowski wrote:
               | https://news.ycombinator.com/item?id=25787548
               | 
               | I've never used Elixir so can't say whether the
               | criticisms are justified.
        
           | hootbootscoot wrote:
           | Presuming server-side JS, as you won't run Ruby or Python in
           | the browser, typically, you can say that all 3 dynamic
           | languages, as such (garbage collected, heap-based, untyped)
           | will waste computer resources and perform worse than typed
           | compiled languages (even garbage-collected ones) due to
           | memory usage patterns.
           | 
           | Python has an interesting C FFI interface, among other
           | approaches, that can at least allow CPU and memory-bound
           | tasks to be accomplished inside of a native code module. You
           | see a lot of domain specific work in Python due to these
           | approaches, cython, etc..
           | 
           | Crystal lang is what I would urge all Ruby devs to look at.
           | (an LLVM-based compiled language that has HTTP in it's
           | standard library, for one thing...I'd pit it against Go, for
           | example.)
           | 
           | As I see large front-end teams frequently pushing JS from a
           | typescript base lately, I'm not sure that even the JS
           | community supports "everything JS" anymore. At the point one
           | does backend Node.js work with typescript or other more
           | rigidly typed systems, I have to wonder if targeting V8 is
           | really the desired option any more, and if the programmer
           | would not be better off switching to a high-performance and
           | feature-complete typed backend language system. (the single-
           | threaded JS execution model being a needless constraint at
           | this point, for example. It's great as an event loop)
        
             | azangru wrote:
             | > As I see large front-end teams frequently pushing JS from
             | a typescript base lately, I'm not sure that even the JS
             | community supports "everything JS" anymore.
             | 
             | Given how close typescript is to javascript, wouldn't it be
             | more appropriate to treat it as just a dialect of
             | javascript (like coffescript was) rather than a different
             | language like python or go would be?
        
               | hootbootscoot wrote:
               | In the sense that there's extra meta information (type)
               | it can be used as a frontend for other things than JS, so
               | I could easily see
               | 
               | 1) TS to WEBASM (once JS is out of the picture, might be
               | awhile, lol...)
               | 
               | 2) TS as an LLVM IR frontend (compiled TS on the server)
               | 
               | which is basically predicated upon industry familiarity
               | as it's selling point, so yeah, I could see where it's
               | also just a JS industry side-effect. A wart remover, lol
        
         | nicoburns wrote:
         | The vast majority of these are implicit type coercion issues.
         | Which is fairly easily banned with a linter. Once you've done
         | that, I think JavaScript is probably the nicest of the big
         | dynamic scripting languages (Perl, PHP, Python, Ruby) to work
         | with.
         | 
         | There could definitely be improvements, but trash seems to be
         | taking things too far.
        
           | ehnto wrote:
           | The article only really touches on weird language caveats,
           | but where JS really gets weird is it's ecosystem. If you are
           | working with JS in a commercial capacity you will eventually
           | find dependency hell, arbitrary toolchain complexity,
           | asynchronous and callback mind bending, transpiling and
           | compilation, and all just to render some HTML. Quick, get
           | your compsci degree bobby, we need to make this button go to
           | another page!
        
           | pansa2 wrote:
           | > _I think JavaScript is probably the nicest of the big
           | dynamic scripting languages (Perl, PHP, Python, Ruby) to work
           | with._
           | 
           | As an experienced Python programmer learning JavaScript, this
           | isn't true for me yet but I hope it _becomes_ true. I think
           | JS will be much more useful to me than Python.
           | 
           | > _Which is fairly easily banned with a linter._
           | 
           | Any particular recommendations?
        
             | furstenheim wrote:
             | Eslint is the default linter. Standard is a curated list of
             | rules with good quality.
             | 
             | https://github.com/standard/eslint-config-standard
             | 
             | I would start with that and tweak what you don't like
        
             | dfabulich wrote:
             | > Any particular recommendations?
             | 
             | TypeScript.
        
         | LandR wrote:
         | Because some developers will take offense. They will think that
         | if you call the language they use trash then you are calling
         | them a trash developer.
         | 
         | It's odd, there are developers who make the language they work
         | part of their identity and see attacks on that language as
         | attacks on their identity.
         | 
         | I don't get it, but it is what it is. If you call javascript
         | trash, you _will_ offend people.
        
         | ljm wrote:
         | Why is it trash? Or is this just like PHP where people are so
         | accustomed to shitting on something that they're completely
         | oblivious to the progress that's actually been made?
         | 
         | I don't understand what this actually contributes to the
         | discussion beyond it being a tired, beaten-down programming
         | meme.
        
           | hootbootscoot wrote:
           | It is 'trash' for the general purpose 'one-size-fits-all'
           | programming language that it's fans want to impose upon the
           | world. (I shake my head at microcontrollers running dynamic
           | languages. "micro-python" = spare me. line breaks over a TTY?
           | there's the primary question of on-chip resources and a giant
           | shim between the physical realities of a microcontroller and
           | some high-level fantasies about what programming "should be",
           | absent any information on the low level specifics = the issue
           | here.)
           | 
           | It's ES3 API is missing a few things, like Object.keys, etc.
           | I still happily code for browsers in ES5 with a few polyfill
           | functions.
           | 
           | JS works fine for it's core competency: manipulating DOM
           | elements and local data representations.
           | 
           | It's not JS's fault that the browser is the way it is and
           | that HTTP is the way it is and that using a remote directory
           | "browsing" protocol via a specialized file browser that
           | renders hypertext isn't a 2-way bound GUI framework...
        
             | jiofih wrote:
             | That's a load of gibberish. JS as a language has nothing to
             | do with browser APIs, why would you judge it based on that?
             | Also, ES6 was ratified six years ago.
             | 
             | Seems like you had a bad experience with espruino /
             | jerryscript or something and are projecting based on that?
             | 
             | Dynamic languages are easier to program in. That's a fact,
             | and why they are so popular.
        
               | golergka wrote:
               | Although I like Javascript (Typescript) a lot, I have to
               | bite:
               | 
               | > Dynamic languages are easier to program in.
               | 
               | Only if you don't care about writing correct and
               | maintainable programs. The only thing that dynamic
               | languages make easier is writing code. Or, more
               | specifically, the first couple of versions of it. That's
               | not what typical programming as a process mostly consists
               | of.
        
               | jiofih wrote:
               | By the definition of formally correct, yes, you're right.
               | But dynamic programming still allows programs to be
               | functionally correct, and verified by testing, which is
               | more often than not good enough.
        
               | hootbootscoot wrote:
               | gibberish? "JS as a language has nothing to do with
               | browser APIs, why would you judge it based on that?"
               | Excuse me? That is precisely what JS is based upon. Lemme
               | give you a prime example: JS = a single threaded event
               | loop, ON PURPOSE. That directly affected Node.js as an
               | implementation.
               | 
               | Your browser has an embedded scripting engine. Embedded,
               | meaning, the source code for your browser includes the
               | scripting language engine, and JS can run on that and
               | script various permitted things via the browser API.
               | 
               | ES6 may have been _ratified_ six years ago, but it 's not
               | the target code your front-end build chain spits out, is
               | it... browsers don't uniformly support it yet. fun facts.
               | 
               | Look, I've been programming JS since it was invented. I'm
               | not impressed by "classes" that don't exist, arrow
               | functions, async/await, futures, promises, fibers, and
               | assorted hacks that don't mirror the actual CODE (what
               | computers execute) a JS engine actually is based upon. I
               | don't need these tools, why should I use something that I
               | need to transpile when I can code directly for browsers
               | as they are in 2021, including legacy browsers? I don't
               | find ES6 "easier" in any way..
               | 
               | Regarding dynamic languages on microcontrollers: Dynamic
               | languages cannot directly control memory allocation and
               | manipulation, typically are heap based and have no
               | concept of a stack frame, and are basically just a
               | computer program written whose corresponding code
               | instructions (machine code) and execution path is
               | scripted by your high-level language. Read a JS engines
               | source code, study embedded C, and get back to me as to
               | how suitable you find it for timing deterministic
               | embedded programming. LOL
               | 
               | Types are directly related to memory size allocations.
               | 
               | Study the recent crop of LLVM languages, including some
               | very interesting ones like LuaJIT, which should be right
               | up your alley, and note the role Garbage Collection
               | (check the Boehm implementation, for example) plays in
               | many of the object-oriented languages, as well as Go.
               | 
               | Look at the actual assembler instructions you require a
               | computer to perform as a result of your high level
               | specification.
               | 
               | I am NOT speaking gibberish.
               | 
               | I agree that dynamic languages are considered easier to
               | program in.
               | 
               | When speaking of programming languages, they are not all
               | on the same level. One cannot say "oh assembler is fine
               | and all but i prefer lua", as it's like comparing apples
               | and atoms.
               | 
               | there's a reason that you can implement a lisp in c, but
               | that the contrary is not viable nor makes any sense.
               | (although metaprogramming c with lisp makes a lot of
               | sense :D)
        
               | jiofih wrote:
               | > That directly affected Node.js as an implementation.
               | 
               | It didn't "affect" node, it was the whole reason it came
               | to exist: its cooperative multitasking was a good way to
               | tackle concurrency (remember c10k), and V8 was available
               | and easily embeddable. Without the event loop there would
               | have been no reason to choose JS.
        
               | lispm wrote:
               | Though there are C compilers and also C code generators
               | written in Lisp.
        
           | furstenheim wrote:
           | Yes, it's a pity that java applets have disappeared. Great
           | UX, great development cycle, programming purity... </s>
        
         | jraph wrote:
         | We are not saying this because we are afraid to say it, but
         | because it is not true.
         | 
         | JS is a great programming language with a lot of quirks and
         | footguns, most of them easily avoidable by enforcing good
         | coding styles, using easily available and widespread tooling.
         | 
         | And most language have linters or compilers that issue coding-
         | style related warnings, including C, so this is not specific to
         | Javascript.
        
           | tasuki wrote:
           | Why is JS a great programming language?
        
             | jraph wrote:
             | There are a lot of things to hate about JS: its
             | questionable choices around type coercion, its Date object,
             | for..in on arrays (indices are string) (a consequence of
             | every object key is a string), for..in on objects which
             | also iterate on inherited properties, the fact everything
             | is dynamic, its weak standard library, null vs undefined,
             | many original things....
             | 
             | There are also great things about it: the ease at which one
             | can write in a functional style code, anonymous functions
             | (vs Python), closures (vs Java), immutable strings, the
             | fact that there is not a shitload of classes to instantiate
             | to achieve anything (vs Java), block-scoped variable
             | definitions, sane default function parameter handling (vs
             | Python).
             | 
             | Javascript engines are also very fast nowadays because of
             | the ton of engineering going into them.
             | 
             | I'd say, above all arguments, you can rapidly build very
             | fast, lightweight and program programs with it.
             | 
             | Sure, you can pull a shitload of pointless dependencies and
             | write bloatware that re-render the world on each keypress,
             | and that's what many people do. And to make things worse,
             | they wrap their shit with an entire browser that uses a lot
             | of ram and processing power. But you are not forced to do
             | that. You can also write efficient server code that does
             | not show up in top, has few dependencies if at all, consume
             | a negligible amount of memory and run without failure for
             | months. That's possible too. Frontend-wise, you have
             | amazing frameworks like Svelte that do wonders and would
             | allow you to build very lightweight apps rapidly.
             | 
             | That said I would often pick TypeScript so your program is
             | statically type-checked and your code is documented through
             | types, especially for more-than-one-person / non-trivial
             | projects.
             | 
             | I also use and like other languages like Python and D (and
             | a bit of Rust) that have good stuff which JS doesn't have
             | (list comprehension, borrowing, traits, named parameter,
             | sane coercion to False...), or bad stuff which JS has.
             | Javascript is not always the best answer, or even a good
             | answers, but it can be one.
        
         | dfabulich wrote:
         | Calling it "trash" is a very inflammatory way to describe one
         | the most popular programming languages in the world. Language
         | like that is against the HN guidelines, because it distracts
         | from your argument to debate about whether JS is "trash" or
         | not.
         | 
         | JavaScript has a bunch of quirks, but it's still great. In the
         | StackOverflow survey, JS reliably ranks highly in the list of
         | "most loved" languages.
         | https://insights.stackoverflow.com/survey/2020#technology-mo...
         | 
         | Node.js is a thing because people liked JS so much that they
         | wanted to use it on the server side. You may think they're all
         | fools, but it's actually pretty nice. I like the latest version
         | of Node better than working in Python (mostly because
         | node_modules are better than virtualenvs, IMO.)
         | 
         | You can use TypeScript to address many of the quirks described
         | in TFA, but you can also reliably avoid them just by never
         | using == and always preferring ===, using String() before using
         | + to concatenate, and using Number() before subtracting.
         | 
         | I basically never encounter situations like the ones depicted
         | in TFA in real code, because I never try to add two arrays or
         | subtract two strings or what have you.
        
           | wruza wrote:
           | _Trash_
           | 
           | "Admitting like this has a bunch of quirks, but it's still
           | great." (not arguing for it though)
           | 
           | Criticism is a driving force behind change to the better.
           | Calling something "great" without pointing out great sides I
           | find... pointless and harmful.
           | 
           | To name a few great points, distinct from other languages:
           | 
           | JS has a pretty shameless object model, where you (usually)
           | have ordered keys, and every key is a property with an
           | {enumerable, writable, configurable, get, set} descriptor. It
           | is much more usable and practical than in almost all other
           | languages. (They do that for "efficiency", but that's non-
           | sequitur)
           | 
           | JS has very useful destructuring syntax, which many languages
           | lack of and that leads to assignment bloating and boredom.
           | Also, jit optimizes out temporary objects, so foo({x, y}) /
           | function foo({x, y}) works almost at the same speed as foo(x,
           | y).
           | 
           | JS has a nice Function type, which allows easier
           | metaprogramming and substitution of 'this' object. Functions
           | are objects, so you can function foo() {}; foo.x = 1;
           | console.log(foo.name, foo.x).
           | 
           | JS bare objects may have methods and properties: t={_x:1,
           | get_x(){return this._x}, ...}
           | 
           | JS doesn't treat syntactic lists in a last-value-only way, so
           | you can expect foo(...a, ...b, c) to work, and to work as
           | intended. E.g. Lua cannot do that, and python (afair)
           | requires you to collect items into a single array (not sure,
           | correct me if I'm wrong).
           | 
           | But what people usually mean by "great" is "it generally
           | works". I know it is an american thing, but some aspects of
           | js, including those you meet everyday, are really just
           | trashy. It would be nice to not have them at all.
        
         | sesm wrote:
         | If we want to perceive JS as it is we need to follow its
         | history, understand the basic ideas behind different features
         | of the language, understand the trade-offs behind various
         | design decisions, etc.
         | 
         | Basically, it was meant to be a dialect of Scheme, but with map
         | and array data structures at the bottom, as opposed to lists
         | (hello, Clojure!). Suddenly, the last-minute decision was made
         | to add Java-like syntax and OOP to this language and rebrand it
         | as 'JavaScript'. Brendan Eich did the best he could in the
         | limited timeframe to implement this. Then in 2015 'design-by-
         | committee' approach was accepted and horrible feature creep
         | started. We can then investigate every feature and how it
         | pushed individual company's agendas while compromising the
         | integrity and vision of the language, but that's a typical
         | design-by-committee story.
        
         | [deleted]
        
         | [deleted]
        
       | gmac wrote:
       | I'm actually pretty fond of JavaScript, but here's a question
       | that has caught me out in real code:                   const
       | x = [1, 10, 2],           y = x.sort();
       | 
       | Now: what is the value of x? (Edit: and y?)
        
         | tinco wrote:
         | I've been using JavaScript for around 15 years, and I've never
         | used a comma to separate expressions. And I'd still go to MDN
         | to look up if sort() is in place or not :p
        
           | gmac wrote:
           | The comma is not material here: the answer is the same if we
           | write `const x = ...; const y = ...`.
           | 
           | And that's the first gotcha: sort() _is_ in place.
        
             | dahart wrote:
             | Pretty sure I've actually tripped on sort() myself before
             | by assuming it was a new array. It does make sense for
             | performance though, creating a new array would be a bad
             | default choice for performance, for the same reasons that
             | forEach is generally faster than map all else being equal.
        
               | gmac wrote:
               | True. I like Ruby's solution with exclamation marks, such
               | as `sort!`, to make this kind of behaviour obvious.
        
         | zodiakzz wrote:
         | In JavaScript every possible value has a .toString()
         | representation* so it makes the most sense that the
         | untyped/mixed array .sort() does lexicographic sorting. If you
         | need numeric sort, use a TypedArray or provide an explicit
         | arrow function.
         | 
         | * Except Object.create(null), which throws.
        
           | gmac wrote:
           | Yes, .sort((a, b) => b - a) is what I meant in this case.
           | 
           | I think perhaps this "makes the most sense" from a language
           | designer/implementor's perspective, but it also gives ample
           | opportunity for WTF moments in actual use.
        
         | colmvp wrote:
         | Is the y relevant? Sort is in place and without a comparator
         | function, it's going to convert the numbers to strings, so the
         | array will remain the same.
         | 
         | If the question is about const, const with Arrays/Objects are
         | by reference rather than value, nothing is stopping them from
         | being modified later in the code.
        
       | have_faith wrote:
       | You're weird if you write code like this.
        
         | qayxc wrote:
         | The sad part is that you don't have to and still encounter one
         | of these cases.
         | 
         | The reason is that JS is dynamically typed and thus functions
         | are free to return multiple result types. So you might run into
         | one of these and get unexpected results because at some point
         | in your code one of the functions returned an empty array
         | instead of a number or a boolean, or divided by zero, or...
         | 
         | It's good to at least be aware of these edge cases so you can
         | avoid them.
        
       | krylon wrote:
       | The questions covering floating point are not really weird, or
       | rather their weirdness is not specific to Javascript.
       | 
       | It's a fun quiz nevertheless, at least for someone like me who is
       | not very proficient in Javascript.
        
       | ksec wrote:
       | People may want to watch "Wat" [1] from 2012 ( for a laugh )
       | before doing this quiz.
       | 
       | [1] https://www.destroyallsoftware.com/talks/wat
        
         | nxpnsv wrote:
         | Good talk!
        
           | kreetx wrote:
           | Wasn't that where the "wat" got started?
        
             | lgas wrote:
             | Yes, it was the proto-wat.
        
       | ZoomZoomZoom wrote:
       | Especially weird was that the quiz stuck at question 2 and kept
       | resizing and shifting the position of the question text on
       | selecting any answer until the quiz ended.
       | 
       | CSS in the console is a nice touch though.
        
         | dgb23 wrote:
         | > CSS in the console is a nice touch though.
         | 
         | Ty for bringing it to attention. Indeed a cool feature to
         | create emphasis and structure. Haven't bothered with it yet but
         | will consider it. Another cool one is using
         | console.groupCollapsed (as long as you are staying in a
         | callback context).
        
         | imalerba wrote:
         | It doesnt work for me in Firefox at all.
        
         | southerntofu wrote:
         | I got stuck at question one like this. Running Tor Browser
         | latest version, tried in all security modes.
         | 
         | First time i ever see a form behave like that oO
        
       | masklinn wrote:
       | The awful letterspacing makes it very hard to know whether
       | strings are empty or single spaces.
       | 
       | (They're all empty strings).
        
         | jeltz wrote:
         | Yeah, got a couple of questions wrong due to that.
        
       | golergka wrote:
       | I guess there's a lot of people who don't work with JS and learn
       | about it from memes like this, so I feel like I have to clarify:
       | I've been writing Javascript (well, actually Typescript, as any
       | other sane person) professionally for quite a few years now, and
       | I can count the amount of times I've actually been bit by these
       | quirks on one hand. And if they added Array.sort() and
       | MAX_SAFE_INTEGER (NEVER serialise and deserialise Facebook's and
       | other long digit IDs as numbers), it's still better than most of
       | the alternatives, in my opinion.
        
       ___________________________________________________________________
       (page generated 2021-06-28 23:01 UTC)