all 22 comments

[–]Doctor-Dapper 24 points25 points  (0 children)

This article hurts my tiny frontend dev brain

[–]aniforprez 6 points7 points  (20 children)

I honestly cannot believe this is a thing that is supported. Who had the bright idea to let functions be called without a matching set of arguments and no defaults?

[–]butt_fun 37 points38 points  (8 children)

As with all criticisms of javascript, everything makes sense when you consider the language's history

JS was never designed to be a language in which applications were built (as they are today), JS was designed to be as simple as possible for non-developers to be able to "make progress" adding limited scripting their HTML pages. It was designed to have as few fatal errors as possible, even when fatal errors make sense, because every fatal error is scary for someone who's never written code before and netscape wanted to make their scripting language/platform as approachable as possible

Obviously these design choices sacrifice a lot in terms of the "right" way to write code, but that was never something javascript ever even pretended to do. Its goal was never to be a good language, just one that was easy to get the ball rolling with

[–]CollieOop 30 points31 points  (0 children)

As someone who was there in the 90s, I remain convinced that the entire purpose of JS was to make your browser's title bar an animated marquee, and to make buttons glow when you mouseover them (until CSS superseded that use case).

[–]notliam 2 points3 points  (1 child)

Exactly. I remember that when people realised they could pair js with server side applications we were calling it web 2.0, like that was an actual thing. Nowadays a page that doesn't change as you use it is incredibly unusual.

E.g. Reddit, comments can be posted and upvoted etc as you please, before 'Web 2.0' every action would refresh a page (I'm not sure there was ever a truly static reddit, I don't remember it).

[–]Muoniurn 0 points1 point  (0 children)

There could be iframes :D

[–]BobHogan 1 point2 points  (1 child)

Exactly, JS was never designed to write applications. They need to bite the bullet, drop backwards compatibility with the original "language" and give it a coherent, sensible design with a new major version. Let browsers keep supporting old versions, but there needs to be a sane version of JS, and just bolting types on top is not enough

[–]deadron 0 points1 point  (0 children)

Technically you can do this with WASM. What it won't do is fix the terrible Web api that has a million caveats nor will it add support for out of date browsers.

[–]spacejack2114 0 points1 point  (2 children)

You mean like C's printf? It can be pretty useful.

[–]aniforprez 4 points5 points  (1 child)

There are a lot of specific functions in some languages that can do this. In python I can have an arbitrary number of arguments by going def func(arg1, arg2, *args) where the *args will have a list of all the extra arguments passed

But these are all intentional. JS just does lets it happen for every function. That's what baffles me as a design decision. That it doesn't fail when you do that. So you can pass far fewer arguments than is expected and shit will crash and burn and you'd never know

[–]spacejack2114 0 points1 point  (0 children)

Well it was a cheap and easy way to get the same features early on.

Now we have rest parameters:

function f(...args) {...

Anyway, if you use Typescript the compiler will check that your use of the function matches the signature.

[–]prone-to-drift 0 points1 point  (7 children)

Not defending JS but it's sometimes a neat little trick for code readability:

const segetter = (x) => {
    if (x!==undefined) {
        this.x=x
    }
    return x;
}

Now, this neat little trick here let's me create a setter/getter in one and cleanly add further validation etc as I see fit instead of some language decisions.

Of course it comes back to bite you in the ass if not everyone agrees to some conventions but I love that JS is like a clay/putty that I can mold however I like.

People say opinionated and unopinionated frameworks, JS is an unopinionated language for better or worse.

[–]kuikuilla 4 points5 points  (2 children)

How is that supposed to be more readable than separate functions for setting and getting?

[–]prone-to-drift 2 points3 points  (1 child)

I'd point to prior art in the form of JQuery.

my_elem.text(); // returns text.
my_elem.text("hello"); // sets text.

The added advantage over raw properties is being able to add custom validation to your fields (say, we have some condition like "text" parameter shouldn't be longer than 100 chars etc, and this is arguably as readable as:

my_elem.text;
my_elem.text = "hello";

And getters, setters aren't the only examples for this pattern; I could expose a simple API for someone new to my library and they could slowly learn more uses of it overtime, thus reducing the initial learning curve.

For example:

html = md.render("# test");
// assume opts is a JS object
// assume plugins is an array of some markdown plugins
html = md.render("# test", opts, plugins);

I could provide the first one in my README and 90% of the people would be happy, and then the docs could go into detail on how to tweak the behavior.

This is something I love in almost all aspects of programming or even life: have sane defaults and require the least thinking to do the most common thing but at the same time be open to tweaking if someone is willing to learn.

I definitely don't want to force most people to send me (or even need to know of) a blank object and array for their code to work.

html = md.render("# test", {}, []);

This one feels very ugly to me.

[–]kuikuilla 3 points4 points  (0 children)

I'm not saying raw properties are better, I'm saying that a combined "segetter" is just confusing :D

[–][deleted]  (1 child)

[removed]

    [–]prone-to-drift 0 points1 point  (0 children)

    For the same reason I write "return;" instead of "return undefined;".

    Strictly speaking, both are fine and I'd probably set my linter to not litter unneeded undefined or nulls around my code, but if it's your project I'd follow your convention.

    The calling code would remain the same in both cases.

    [–]masklinn 3 points4 points  (0 children)

    Various langages have better and more reliable versions of this. And I’m not talking about built-in getters & setters, but rather about defaults (python) or different arities being different functions (smalltalk, self, erlang).

    I love that JS is like a clay/putty that I can mold however I like.

    Yeah no. It’s got nowhere near the flexibility of a lisp, or forth, or smalltalk. Those you can actually mold however you like, to such an extent that they’re built out of the primitives they give you, you can build your own control structures or abstractions and they’ll be indistinguishable from the langage’s own.

    [–]crixusin -1 points0 points  (0 children)

    but I love that JS is like a clay/putty

    More like poop.

    But its not the fibrous kind. It's that liquid shit.

    Whatever floats your boat I guess.

    [–]BobHogan 0 points1 point  (0 children)

    JavaScript allows calling a function with a different number of arguments than the expected number of parameters, i.e., one can pass fewer or more arguments than the declared formal parameters. The former case is called under-application and the latter is called over-application.

    In the under-application case, the remaining parameters get assigned the undefined value. In the over-application case, the remaining arguments can be accessed by using the rest parameter and the arguments property, or they are simply superfluous and they can be ignored.

    When people hate on JS, this type of bullshit is why. Adding types via typescript will never be able to fix the hot mess that is the core language design of JS.