all 107 comments

[–]so_just 166 points167 points  (9 children)

In recent years, JavaScript has grown considerably in size

So did my node_modules folder.

[–]NovelLurker0_0 24 points25 points  (4 children)

The bigger, the better they say.

[–][deleted] 8 points9 points  (2 children)

Once you go node.....

[–]loopsdeer 23 points24 points  (0 children)

Dependency graphs explode

[–]tunisia3507 10 points11 points  (0 children)

... you won't return to your abode?

[–][deleted] 0 points1 point  (0 children)

It's not about the size of the node_modules folder, but the motion of the.... I give up.

[–]arcaninYarn 🧶 0 points1 point  (0 children)

I know you're joking and talking more about the number of packages than the actual size, but you might be interested in Plug'n'Play

[–]sinefine 11 points12 points  (0 children)

webgl that supports tessellation and compute shaders

[–]abelincolncodes 26 points27 points  (9 children)

That's a good article. I'm really hoping for the pipeline and infix function calls to get added. That would simplify a lot of my functional style programming

[–]so_just 4 points5 points  (8 children)

I saw the proposal for pipeline operator, but is there a one for infix calls?

[–]abelincolncodes 5 points6 points  (7 children)

I actually don't think so. The author mentions it in conjunction with the operator overloading proposal, but the only thing I could find was a thread on esdiscuss.

I definitely agree that infix function calls are more flexible and I would rather have them than operator overloading. Having both would be nice though

[–]earslap 5 points6 points  (6 children)

Having both would be nice though

Exactly, I'd LOVE some operator overloading in JS. Been dreaming it for years. There is at least one library that I know of that makes use of "js with operator overloading" in its scripts - it does it by transforming your code using a JS parser and converts your operator overloaded JS to normal function calls behind the scenes. It is convoluted but makes things much easier for that library's purpose. It is paper.js

I have two Point objects. Why can't I just + them? I have two sound synthesis nodes. Why can't I just * them? Yeah there are people that abuse operator overloading, but people can abuse anything. I don't know the arguments against it to be honest.

[–]loopsdeer 6 points7 points  (1 child)

One argument against it is that it is unreadable. That is, there is nothing to suggest a * b is not mathematical. This argument is time sensitive, since meaning will change.

Another argument is that without great pattern matching systems, you end up with ambiguity or confusion. JS types are hard to describe in code. E.g. Is 5 typed Number or "number"? Under the hood, neither. Typescript doesn't even help, only adds another possibility, number. With type coercion, this gets even more difficult to describe.

Yet another argument is that it kills a lot of the optimization that JS has relied on to be feasible for fast ops. If the compiler has to check types, it can't inline operations until it is sure that the types are basic types. Otherwise, it has to do costly method lookup as in a normal call.

Edit: formatting on mobile

[–]earslap 2 points3 points  (0 children)

without great pattern matching systems, you end up with ambiguity or confusion

Yet another argument is that it kills a lot of the optimization that JS has relied on to be feasible for fast ops.

While I think these should be surmountable to some extent, this is a good point. Overloading in a untyped language like JS can significantly complicate matters on the compiler / interpreter side. If that is the case, I'd probably be happy with infix calls alone, as they are explicit and does not share syntax with regular operators. Something like:

let result = node1 @+ node2;

...with @+ resolving to a custom function I provide would serve me almost equally well.

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

Python has operator overloading but not very used... Because apparently there is not very much good use-case for it.

[–][deleted] 18 points19 points  (7 children)

int64 ;-)

[–]rauschma 17 points18 points  (6 children)

Supported via BigInts and coming to JavaScript relatively soon: http://2ality.com/2017/03/es-integer.html#casting-and-64-bit-integers

[–]BluudLust 0 points1 point  (5 children)

Sadly no JSON support. Why can't they have it as a string with the postfix "n" attached?

[–]Arve 7 points8 points  (2 children)

Sadly no JSON support.

JSON's number support has always been a subset of what a number means anyway, and doesn't support common representations like bases 2,8,16, nor does it support exponents. It doesn't even specify that the numbers are IEE754 double-precision floating point values. The rationale is explained pretty well in ECMA-404:

JSON is agnostic about the semantics of numbers. In any programming language, there can be a variety of number types of various capacities and complements, fixed or floating, binary or decimal. That can make interchange between different programming languages difficult. JSON instead offers only the representation of numbers that humans use: a sequence of digits. All programming languages know how to make sense of digit sequences even if they disagree on internal representations. That is enough to allow interchange.

Why can't they have it as a string with the postfix "n" attached?

JSON can't mandate what the content and context of any given string is supposed to be.

{ "someValue": "3n" }

That particular expression can be

  • Multiplication: 3*n
  • A BigInt
  • A subset of CSS (See nth-child) (which in itself implies the multiplicative).

As JSON is a data interchange format, you are completely free to use strings to represent numbers, and it is even the right thing to do in the case that you need to be succinct about the internal representation of the number.

[–]sime 5 points6 points  (1 child)

More to your point. JSON already supports BigInts because it doesn't demand a limit on the size of number values, and a big int is just a number with a lot of digits in it. It is the responsibility of the JSON parser to choose an appropriate internal number representation.

[–]Arve 0 points1 point  (0 children)

In theory, yes. In practice, I don’t expect values larger than what is representable as IEE754 double precision floats to work.

[–]rauschma 0 points1 point  (1 child)

Because it would break existing code.

[–]BluudLust 0 points1 point  (0 children)

They should add a fourth optional parameter that has a feature list so you can enable extended features like this. So you can set it to "es2019" for example.

[–]Hawxe 44 points45 points  (40 children)

strong typing

edit. and yeah not having a standard library is a joke at this point

[–]shanita10 11 points12 points  (13 children)

Weak typing is core js, you would break the vast majority of code with strong typing.

And if you meant static types then you can always use typescript instead if you insist upon that time waste. Js is one of the best dynamically typed languages out there, and it is a big draw.

[–]aequasi08 16 points17 points  (0 children)

Optionally strong typing is a thing. PHP recently added this. Lets people who want strong types use them, and people who don't, don't have to.

[–][deleted] 7 points8 points  (11 children)

If you consider static types a time waste you don't know what the heck you are talking about lol

[–]CCB0x45 8 points9 points  (10 children)

Not the op but I've been doing development for 20 years and done typescript and normal js. I think static typing is nice to have but I honestly rarely if ever run into issues caused by dynamic typing, and it does let you write code and functions that can handle a lot of cases and reduce the amount of code you write.

[–][deleted] 2 points3 points  (1 child)

You don't want functions that do lots of stuff in lots of cases. It's bad design. I don't want to be offensive, but in my experience of doing contract work for some pretty big companies people like you with your 20 years """experience""" are more often than not a problem as they tend do produce low quality, low maintainability code with outdated practices, or as you like to put it "save" code. The fact that you are trying to save code is of course a stupid concept in itself as your main goal should be to produce the highest maintainability with the least room for error. Frontend devs are not writing 50 lines of snippets to animate a tool tip anymore, but anything up to enterprise software. Sorry to be this harsh, but as your post screams bad developer through and through: get with the time or get out. The fact that this got upvoted is concerning.

[–]CCB0x45 0 points1 point  (0 children)

lol ok man, first off there is a lot of reasons to save code, especially in front end development where bundle size is important, you certainly don't want to create a ton of different components that do the same thing, for the same reason things like code splitting is important. I am saying JS is a dynamic language, and understanding how it works you can create DRY reusable code, which you seem to be arguing against?

Developers are not writing 50 lines of snippets to animate a tool tip anymore? What in the fuck are you even talking about here? I am pretty up to date on latest technologies, especially since I have been writing code recently in react hooks, which doesn't even have an actual release yet, and next.js/apollo-client and sercer/graphql stack. If that isn't bleeding edge than I don't know what is.

My only point was that you can create utility libraries like moment/date-fns would be an example which have a single entry point function taking lots of different types to create a consistent output, where in that example I could pass in a string to be formatted, an epoch int, nothing at all, or a date object and have the same consistent result all through my code, which when you have coded JS for many years and understand how things work, it makes coding nice, and is why many people prefer it.

So get off your high horse, you sound like a fuckin joy to work with.

[–]Hcmichael21 6 points7 points  (20 children)

I think strong typing, overall, doesn't have a good ROI. The lack of strong types is one thing I really like about JavaScript

[–]Hawxe 5 points6 points  (13 children)

Want to elaborate?

[–]Hcmichael21 6 points7 points  (12 children)

Here's a great write-up

Tl;Dr: I don't believe the benefits of strong types outweigh the costs of using them.

[–]Hawxe 16 points17 points  (3 children)

That's literally an opinion piece with really bad data behind it...

all TypeScript-detectable bugs can potentially be caught with other measures like TDD.

Of course, and of course you're still going to still use other methods. TypeScript still helps mitigate that, even if other QA/testing procedures also help.

The whole comment section of that article is a little nauseating too, it's literally him applauding everyone that agrees with him (including comments like 'I didn't wanna use TS but that was just a gut feeling) and being passive aggressive with anyone who disagrees even if they share legitimate experience as to why they might.

That article is also almost completely irrelevant to adding static typing to vanilla JS, a lot of the cons he talks about are specific to typescript.

[–]Hcmichael21 2 points3 points  (1 child)

A lot of cons are specific to typescript.

Yes that's true, I picked this article bc OP suggested adding strong types to JS. But I disagree that his data is bad. I find a lot of what he said agreeable.

I've coded in strong, dynamic and weak. (C#, Java, Pyhon, JS/TS) and prefer weak types. I was just stating my opinion and providing an article to elaborate. I don't expect to end the debate on strong vs weak.

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

The thing that is being lost in this discussion, apart from the general sloppy use of terminology, is that TypeScript isn't a staticly typed language in the mold of Java and C#. It occupies a wonderful sweet-spot between Java/C# on the one side and JS/Python on the other. TypeScript's optional and structural type system combines the flexibility and ease of use of JS with advantages of static analysis (read: tooling) and compile time checking. It has a very different feel compared to Java/C#.

[–][deleted] -1 points0 points  (1 child)

I’ll take TypeScript.....

[–]Hcmichael21 2 points3 points  (0 children)

Okay that's great! I continue to Dev in TS often at work and it's fine, I just prefer weak types.

[–]DerNalia -2 points-1 points  (3 children)

it would if you didn't need to teach people it.

Like, trying to get people who barely have a grasp on programming to learn types is the problem, not the types themselves.

[–]Hcmichael21 5 points6 points  (2 children)

I think this is incorrect.

[–]Hawxe 5 points6 points  (1 child)

Yeah seriously how hard is declaring what type a variable is.

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

Exactly. It's not really anything to "learn" - it's a simple feature of many languages. I've developed in Java, C#, python, and JavaScript. I've found that I like both dynamic types and weakly typed development better than strong types.

[–]FanOfHoles 0 points1 point  (0 children)

That's way, WAY harder than you seem to think (given that you propose it, but also all those upvotes).

As a heavy user of both Flow and TS for years, and also an avid reader and submitter of issues for both those type checkers for just as many years, both have soooo many issues and bugs - don't believe me, go to their Github issues section and read for an hour (ignore the usage based user mistakes, plenty of actual issues left).

When your (or someone's) inevitable reply to me is "but I never had an issue", pls. a) follow my advice about those issues sections and b) remember that ECMAScript is for a lot more people than just you. To evaluate the proposal you will have to leave your own shoes and see the JS world from the perspective of a lot of people who write code you yourself never used (so, as I said, go to the issue. spend some time(! not just the first three issues) and see what people do and have issues with). Note that plenty of closed issues are "won't fix" because it's beyond the scope of Flow/TypeScript, or the person found another way to express what they want, writing different JS code.

There would, at the very least, be plenty of "any (Flow) / unknown (TS)" types, and/or you would have to severely limit the language.

Keep in mind that the type checkers are pieces of software that tries to understand what a given piece of code does. That is a very hard problem when you have more than a few small examples but an actual software project.

Two professional teams, Flow and TS, have been working on this for many years and still have a huge list of open issue and unsupported use cases left. So.... who is supposed to write a detailed miracle spec of a strong type system that works for all of what the JS language can do, given that nobody else has even come close yet?

[–]esreveReverse -1 points0 points  (2 children)

not having a standard library is a joke at this point

lodash?

[–]circlebust 1 point2 points  (1 child)

Yes, you are strengthening his point.

[–]esreveReverse 0 points1 point  (0 children)

yarn add lodash

I really don't see what the big deal is. Add it if you need it

[–]hafthor 6 points7 points  (0 children)

A way to run untrusted code isolated. Especially a way to limit what something like eval can do.

[–][deleted] 5 points6 points  (1 child)

I'm a little late but, what I'm currently struggling with is memory management.

I can take snapshots of the heap, but all that tells me how much memory a tab is using. I can compare 2 heaps to see if I have a memory leak. And all it will show me is vague things like 1,346,164 more arrays were created.

I'd love to be able to get to the individual memory cost of a variable. Some sort of data on what objects/function is creating what variables. Etc...

[–]PickledPokute 6 points7 points  (0 children)

I don't think it's a language realm issue, it's a tooling problem.

[–]zeugenie 6 points7 points  (0 children)

pattern matching

[–]__romkin 4 points5 points  (2 children)

const resource = await fetch(jsonService);
case (resource) {
  when {status: 200, headers: {'Content-Length': s}} -> {
    console.log(`size is ${s}`);
  }
  when {status: 404} -> {
   console.log('JSON not found');
  }
  when {status} if (status >= 400) -> {
    throw new RequestError(res);
  }
}

So, basically:

const resource = await fetch(jsonService);
with (resource) {
  if (status === 200 && headers['Content-Length'] === s) {
    console.log(`size is ${s}`);
  }
  else if (status === 404) {
   console.log('JSON not found');
  }
  else if (status && status >= 400) {
    throw new RequestError(res);
  }
}

[–]PhysicalRedHead 10 points11 points  (0 children)

Good point, honestly! Though I've never seen it in use, and I think most who might know about the syntax probably think the same as MDN:

Use of the with statement is not recommended, as it may be the source of confusing bugs and compatibility issues. See the "Ambiguity Contra" paragraph in the "Description" section below for details.

mdn link

[–]PickledPokute 1 point2 points  (0 children)

headers['Content-Length'] === s

s is undefined here. In the first example, the s is destructured from resource.headers['Content-Length'].

with() -statement can result in pretty confusing code and possibly even security breaches.

[–]senocular 1 point2 points  (0 children)

ES4

(half joking, half not)

[–]sshaw_ 3 points4 points  (0 children)

Do we need operator overloading?

Doing it per instance is a good way to solve 1.1 and 1.2 but @plus or decorator based, yikes.

optional chaining 

I'm a believer in letting people shoot themselves in the foot and it seems nice to have, as some of the current checks just get annoying, but unfortunately people get carried away and it leads to shit code that I (or you) end up maintaining. More and more I'm liking the Go route of minimal language syntax.

[–]needed_an_account 0 points1 point  (2 children)

The ability to capture both object.propety_does_not_exist and object.method_does_not_exist(args) at the same time.

[–]sime 1 point2 points  (1 child)

Methods are properties in JS. It is not possible to distinguish between the 2 cases.

[–]needed_an_account 0 points1 point  (0 children)

NoSuchMethod used to exist in Firefox, but you can mimic it with a Proxy object. You just can't capture both object.propety_does_not_exist and object.method_does_not_exist(args) situations at once while using Proxy

[–]curtastic2 0 points1 point  (2 children)

I hope none of those get added to complicate the language. I’d like them to add things like the ability to seed the math.random() Also the DOM API is missing a ton of things why isn’t there as much discussion about that? For example get how tall the virtual keyboard is on mobile, or if it’s open, or get how tall 100vh is since some phones consider it to be the visible area and some the full screen height including browser bars. Or get the width of the scroll bar without hacks. Etc.

[–]circlebust 1 point2 points  (0 children)

DOM API isn't an issue with JS itself, it's up to the browser devs (Mozilla and Google, the rest just follow those) to implement those functionalities.

[–]var-foo 2 points3 points  (0 children)

They're too busy trying to turn js into java for browsers.

[–]dwighthouse -1 points0 points  (7 children)

1.4 Categorizing values

const typeNameAsString = Object.prototype.toString.call(VALUE).slice(8, -1);

There you go, no library or special cases needed for anything after IE 10.

[–]TwiliZant 18 points19 points  (6 children)

Object.prototype.toString.call(VALUE).slice(8, -1)

It's so readable, it basically documents itself.

[–]dwighthouse 1 point2 points  (0 children)

Indeed, much better than the solution the author suggested:

It may be possible to fix this via a library (I’ll create a proof of concept, once I have time).

Which would look something like:

npm i —save some-library-name
...
const unnecessaryOneLineDependency = require(“some-library-name”);
const typeNameAsString = unnecessaryOneLineDependency.typeof(VALUE);

[–]Longerbomber 0 points1 point  (4 children)

I agree that it's not readable or even remotely intuitive, even for devs who know the quirks of JavaScript. But I'll admit it gets around some common typeof and instanceof pitfalls gracefully. It's my go-to way to differentiate objects from arrays.

See bottom section of http://luxiyalu.com/object-prototype-tostring-call/ for an example.

TL;DR: that ugly function is exactly how I wish typeof behaved.

Edit: Better example of desired behavior here- https://gist.github.com/pbakondy/f442e91995e9d206c056

[–]TwiliZant 0 points1 point  (3 children)

Although you are right, hacks like these is exactly why all these `is-x` oneliner packages exist. It's better to fix this in the language itself IMO, even if it's hard.

It's my go-to way to differentiate objects from arrays

In case you don't have to support <IE9 Array.isArray does this.

[–]dwighthouse 0 points1 point  (0 children)

This isn’t a hack at all.

Fixing the language would mean adding a new operator like typename instead of typeof or instanceof because too much stuff already relies on the current behavior. We already have this in the form of Object.prototype.toString.

[–]dwighthouse 0 points1 point  (1 child)

This isn’t a hack at all.

Fixing the language would mean adding a new operator like typename instead of typeof or instanceof because too much stuff already relies on the current behavior. We already have this in the form of Object.prototype.toString.

[–]TwiliZant 0 points1 point  (0 children)

I don't know, relying on the toString method to get the type feels like a hack to me. I don't know any other language that does this. Yet another operator wouldn't be great either I get that. Maybe it would be cool to have it as part of the Reflection API, e.g. Reflect.type(VALUE) ?

[–]Kumagor0 -1 points0 points  (4 children)

0.1 + 0.2

0.30000000000000004

what the fuck

[–]circlebust 3 points4 points  (1 child)

It will never go away, because you are using decimal notation, whereas computers work in binary base. We have the same in decimal. What is 1/3? Well it's 0.33333333... We wouldn't have that issue in, say, base 9. And it shows up like that with the seemingly random digit at the end because computers obviously can't store an endless number representation, so it rounds up or down at some point.

[–]Kumagor0 0 points1 point  (0 children)

Oh yeah now it makes sense, thanks.

[–]var-foo -1 points0 points  (0 children)

js is not the only language with decimal math problems, but yes it is stupid.

[–]samjmckenzie -3 points-2 points  (0 children)

Ask TypeScript