Hacker News new | comments | show | ask | jobs | submit login
We haven't forgotten how to code – JS just needs to become a better language (christoffer.me)
95 points by rplst8 399 days ago | hide | past | web | 86 comments | favorite

I think you're missing two major points (which the original 'left pad' post partially noted):

1. There should be one or several libraries (like lodash), where the maintainer provides a high level of quality across many core utilities that are needed, rather than all these functions singly collected across many different users which can lead to variable quality - and a maintenance nightmare over time (plus the potential security risks)

2. You should minimize dependencies when it doesn't provide great value (the bar's especially high if many others could/will depend on your library); there are functions like 'is-positive-integer' that should have been written without external dependencies (but had 3 dependencies); realize that dependencies inject cost into your system (and benefits as well), and weigh one vs the other for your use case, rather than blindly defaulting to a mindset that micro libraries are always the best approach

Regarding #1, I strongly think that the JS community should come together and build out a library that fills the same role as Boost does for the C++ community. Sort of a collection of things that are missing from the standard library.

I suppose lodash and others aim for a similar purpose, but clearly left-pad-gate has shown us that they're not quite complete enough.

This ignores the fact that js libraries need to be downloaded on every run. Even if there were a great general-purpose string module that included the functionality, a micro-package like left-pad would be less to download if you didn't need the other stuff so I imagine some developers would still use it.

It's almost ironic really, that js has the worst standard library situation of any popular language yet it would benefit the most from having a good one since it would save everyone bandwidth and page load time.

Maybe someone can write an amazing replacement stdlib and we can all agree to include it from the same CDN so it'll be cached on every browser in the world...

EDIT: I see from other comments that lodash functions can be required individually which I hadn't thought about. But the point still stands, every function that you use in a big project that could have been in the standard library is more to download.

You seem to be optimizing size of download as the critical issue, when I think there are a few other optimization points that this controversy highlighted (e.g., quality of external codebase, security risk, maintainer risk, dependency management challenges).

A main issue with the current system is that you're pulling in micro dependencies from a variety of different sources, instead of a few potentially highly reputable sources (fairly or not, I'd feel more comfortable with dependencies from the lodash maintainer, than from 50 different people). One solution obviously is a better standard library, but often to get there, the process is for devs to create common libraries - which over time are (partially) absorbed in language standards.

ES6 modules, combined with a tree shaking build tool solve this issue. You can install a hige library and the output source will only include the parts you use.

Unfortunately, libs that provide function chaining via dynamically extwnding a prototype can't be optimized by tree shaking.

The future :: function bind operator should provide a tree shaker friendly alternative.

Sounds like all you need there is a compiler (people already use minifiers, right?) that would include or inline the used functions as appropriate and the cost would mainly go away? Or add in the "fetch this version from CDN" library loader code if it's a stdlib we expect to be cached and used by many js scripts.

Lodash has a left pad function that can be installed individually. People just don't know/wasn't available before.

I vote for lodash to become the new STL. It's even faster than native JS.

It already exists in the form of underscore/lodash. If the authors who used left-pad had looked at say underscore.string (https://www.npmjs.com/package/underscore.string), they'd have not only a pad function that works for left and right padding, but a whole slew of other useful (indispensable IMO) general functions and string functions. Next time they need a right-pad, they won't have to go looking for another extension or god-forbid actually copy and paste a 5 line function into their code. These libraries have been around for years and there is no excuse for not using them. Finally, there is no excuse for left-pad, even if no other alternatives were available, unless Copy/Paste functionality completely disappears off the face of the earth.

Agreed, I think one issue is that great libraries for all use cases weren't available in the past so older libs built up these chain of dependencies, and this might be the wake up call that gets people to to a) create a few more unified libs (might be as simple as cherry picking top NPM micro libs + refactoring) and b) gets libraries to switch over to the new unified micro libs.

You'll need both to happen - and that's the benefit of this controversy.

Even so, I think the micro-library dogma might have gone too extreme, without many programmers realizing the cost it injected - and this controversy will likely also help with changing some developers dependency philosophy.

More speculatively, I'll be interested to see if any of this leads to changes in the ECMAScript standard discussions in future years.

There is an equivalent lodash function. Lodash is also nice because you can just include the function you need, a custom build, or the whole library. I use node but I've never felt the need to install a 1 line module.

Or apache commons lang for java.

1a. What problem is that trying to solve? The left pad issue was caused by unpublishing an open source package, it won't fix that. Writing quality libraries is a lot of work, especially for a single maintainer. From experience, maintenance nightmare is Python 2 to 3, or upgrading any "framework" library. Replacing a simple immutable function is easy, I would take 50 of them over one complex monolithic library.

2b. Though this wouldn't fix the left pad issue, mitigating security risks in OS is actually a very interesting topic. Something I haven't seen, but would love to is an ecosystem that allows packages to be code reviewed for security flaws. So users can see that a package (and dependencies) have been reviewed by X people, and Y in their network.

2. This won't solve the left pad issue, at best mitigate it. The main reason this is done in JS libs is to reduce file size of web apps, maintainers brag about it in their READMEs. Babel on the other hand is part of the compilation step, so no need to have that constraint, which it is.

Not mentioned, but this is one way to mitigate security issues, by reinventing the code. Other option is to audit the dependencies.

#2 is an excellent point. If there's one thing my years as a Java developer (and Maven user) taught me, dependency hell is a real and ever present threat. :)

Maven doesn't help in that case either, given that it contains it's own self-contained dependency hell.

I want to say "look at the Java ecosystem", but that's not hipster enough.

Duplicate the Python standard library, call it "batteries" as in batteries included, ???, profit

The problem is A, but everyone is attacking B.

The issue: developer pulled their package off NPM, which many packages depended on.

The solution: keep all packages in NPM. If the software is open sourced, we can legally continue to redistribute the software even though author may not want us to.

Ecosystems with this issue: Python, Ruby, Go (google it)

Ecosystems without this issue: Maven, Haskell

I respect someone wanting to pull embarrassing or private data, or even just out of spite. In that case the package can be made undiscoverable, but still accessible from direct download.

Non relevant issues: laziness; micro vs standard vs kitchen sink libraries; package security; package quality; package maintainer coordination; ... but the color of the bike shed is just so interesting.

Golang, Python and Ruby all have solutions for this: vendoring. I know first hand that Python and Golang have OPTIONS for how you vendor code... My current Python project and ONE of my Golang projects are "non standard".

The last time I used NPM, vendoring the code wasn't really a viable option, and it seems that things haven't improved. When googling NPM and vendoring, I learned that this isn't the FIRST time that this sort of issue has bitten the NPM user base. This article from 2 years ago http://www.letscodejavascript.com/v3/blog/2014/03/the_npm_de... makes it clear that the community as a whole hasn't learned. Vendoring still seems much harder than it needs to be and based on my search results is activly discouraged.

"If the software is open sourced, we can legally continue to redistribute the software even though author may not want us to."

Right, you can legally redistribute the software, but can you ethically do so? Some people have complained about the bad precedent set for allowing left-pad to be reuploaded again after it was deleted, and the reason they complained is because the developer has lost control over the fate of his own package.

These people can't complain too loudly, as the author in question did indicate that he was willing to give ownership of his npm packages over to someone else. But you could easily see a situation where a developer would want his stuff deleted and not be accessed, period. Why should this request be refused?

The idea that the developer has lost all moral rights whatsoever to his/her work just because they attached a LICENSE text document feels wrong to me. Just because a license says you can 'do whatever you want' doesn't mean you should do whatever you want.

The author explicitly chooses an open source license and publishes to a public repository for other people to depend on. That action releases the package into the public sphere.

If the author then wants to undo this action, that simply will be difficult—more so the more people depend on the package.

If several people depend on the package, then they will try to put it back again, unless they sympathize strongly with the author's intention to unpublish.

That's just open source working as intended. There's no ethical framework that compels people to have that sympathy, in general.

> Right, you can legally redistribute the software, but can you ethically do so?

Yes, you can. If you're sharing your code with the world, that entails certain responsibilities. You're telling people that they can depend on your code, and you should not be allowed to violate that. Open Source isn't just about getting attaboys for being such a cool dude—it's about working together to build a library of code. If you don't want to be part of that, if you don't want to take under consideration any of the people who will be using the code you're sharing—then don't do it. Just don't release your code. Find something else to do with your time.

See my second to last paragraph for my response.

And I think that's a pretty good compromise that I'll accept. I could also suggest a manual deletion process as well in case you accidentally released security credentials or something very private that really shouldn't be open source. (Manual in the sense that you have to send an email to tech support and wait for them to respond...)

iirc packagist.org (for php libs) allows deletions for packages that have been downloaded < 100 times, which covers the situations where something was published accidentally and needed to be reverted.

The issue: you have a fever.

The solution: take a cold bath to bring the temperature down.

Addressing the disease, not the symptom, is not bike shedding.

Thanks, that's another way of looking at it. Not sure if you agree or disagree, the metaphor helps explain the point.

By having a larger std lib, or less dependencies, it only treats the symptom of the disease, which is dependencies disappearing. To treat the disease we need to make sure open source packages are always accessible. This issue runs through a lot of other areas as well, not just package managers, which is why projects like IPFS are exciting!

Congratulations, you've just met someone who legitimately likes JavaScript as a language, as well as its libraries.

That's just never, ever a credible assertion, "I've never met anyone who likes X"....then you must not talk to many people. There's a lot of people in the world and a lot of JS developers and PLENTY of them like it.

Seconded. I really enjoy coding in JS, and don't mind the various hacks that have to happen for browser incompatability.

I do, however, object to the massive amounts of dependency in the Nodejs ecosystem. It's as if no-one learned the lessons of DLL Hell. We already know that dependencies are bad, people!

If dependencies are bad, then it seems to follow that every project should reinvent all the wheels.

No. Reinventing wheels is also bad. Which one is worse depends on context.

nice ad absurdum ;)

I don't have any objection to dependencies where they're necessary. But the node culture isn't "where necessary", it's "wherever some code might be vaguely useful". Left-pad is a classic example: this is a one-liner[1] so why the hell are we including it as a dependency?

[1]: ((str,len)=>("0000000000"+str).slice(len*-1))("test",10)

I like ES6 myself! Though ES5 rates as only tolerable to me; I hope the standards committee manages to phase out more of the cruft over time via some kind of 'use strict'.

As a former C# coder i really like JS. ES6 is great.

3rded, as a C++ programmer of many years it took a while but I now enjoy JavaScript quite a bit

So what exactly is the connection with JavaScript's deficiencies as a language and the existence and prevalence of micro-libraries like left-pad? There is the whole issue of cross-browser compatibility, but how does something like left-pad even relate to that? I doubt there are many languages with core library support or language level support for that type of string padding functionality. I feel like the problem in this case has more to do with the way package publishing currently works than any features/warts in the language.

It's because there are so many of these warts and gaps that a Javascript dev has two options: write their own left-pad (and array.includes, and range iterator like I did yesterday, and so on...) every 5 minutes, or use the one you can reasonably assume already works without bugs.

You should check out lodash/underscore [1]. Not only is the codebase well reviewed, but there is a _.pad function in there (left and right!), and the maintainers are open to additions if core functionality is truly missing. You'll also get functional primitives that will actually make JS fun.

[1] https://lodash.com/docs

Edit: FWIW, lodash also has _.isInteger(), _.range(), and _.inRange().

Yup I looked there first, but there was no iterator-based range function. lodash/underscore were built for a pre-ES6 world, so they don't cover all the nice iterator/generator stuff that I like from python (yet? hopefully!)

I suggest you look at using a python like language that transpiles into javascript. For example, https://github.com/kovidgoyal/rapydscript-ng which supports iterators/generators on both ES 5 and ES 6 runtimes.

Using a python like language greatly eases my pain as a primarily python developer that has to code significant amounts of javascript.

I don't think that explains it at all.

If Javascript string manipulation sucks, there should be a single string manipulation library that fills in the gaps, not 50 different libraries to work around 50 different gaps. Ditto every other class of deficiency.

There's really only lodash now that individual functions can be imported without bringing the rest in.

you could also have 1 library that depends on 50 different libraries, where you trust somebody to lock and update them responsibly

And what's wrong with Lodash, which contains pad and all the above, and loads more besides?


This is making a lot of excuses. Bad design and poor coordination between package owners and consumers is the problem (in this case).

I am a JavaScript developer and I see this as an opportunity for the community to learn and grow.

How much of this is the fault of Node culture? Javascript on clients may be a necessary evil, but relatively good languages actually exist for servers. Writing a server these days in Java makes little sense; writing one in Javascript is sheer lunacy.

Agreed, node exists becuase it can, not because it should.

Because it's great, simple, and has a huge community? A few lines of code and having an HTTP server (or other protocol) is quite nice.

Agreed. One can get a server up and running in seconds with Apache, NGINX, Django, Rails, or any number of other tools, many of which have rather large communities. Node has no monopoly on any of this.

How is it lunatic to use the same language for client and server?

The problem isn't using the same language for client and server it's the monopoly on code executed on the client.

Because there are far better languages to use on the server side. There isn't much choice on the client.

Not at all a bad idea. But it's not a good enough idea to warrant sinking to the lowest common denominator.

This is ridiculous. You don't need a module for a function that returns false (https://github.com/mde/false), and you sure as hell don't need a dependency for a function that prepends N spaces to a string. It takes more keystrokes to add the dependency than it does to write the damn function. Not to mention it spares the NPM server additional requests, etc, etc.

If you can't trust yourself to write such a simple function, how confident are you about writing something a little more complicated? Or very complicated? Doesn't it bother you that you feel more confident in 10 simple lines of code written by a complete stranger than you are in yourself?

I'm pretty sure that false module is a joke (along with the true module)

Although I agree with you about the left pad function. It wouldn't even cross my mind to search for a library instead of just typing out the code.

It does make sense as a function in a larger utilities library though, such as lodash. If you already have that as part of your code base then might as well take advantage, similar to apache commons/lang in the java world.

I spend 90% of my time on the back end, coding in SQL or Python, setting up servers,cleaning data in SQL. JavaScript has enough quirks that I likely still don't know about, I feel it would be a far more sensible choice to import something like this rather than write my own. (Chances are that I wouldn't have known about this until now, so I would have written my own anyway.)

Hell! just copy-paste it raher than adding a dependency.

I spent many years programming Perl, which had no trim / strip funtcion to get rid of whitespace. The Perl cookbook has a recipe for one using a regxeg, and I have cut and pasted that into many other places. It always felt wrong cutting and pasting the same thing over and over, but it was never large enough for me to consider putting it in a package either.

> but it was never large enough for me to consider putting it in a package either.

That's OK, someone did it for you:


CPAN to the rescue!

Bad idea: left-pad. Good idea: polyfill library for ECMAScript 6. Specifically: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

> since our single written source code is often executed on different environments and browsers

That's still a lot easier than writing portable C has to support variations in environment, compiler (w/ varying interpretations of the C standard over several decades), linker, make/build tools, CPU architecture and byte-sex (big-endian vs little-endian vs middle-endian), pointer sizes and alignment rules, integer sizes and alignment rules, incomplete and occasionally broken "standard" headers, and many more inconsistencies.

And that's just for a simple system daemon or command-line tool. If you want a GUI, that's another giant mess for potability.

> it's silly that we web developers should spend time to recreating basic wheels

Of course. There are many solutions to that problem that don't require builds that depend on network resources controlled by 3rd parties.

> JavaScript language itself is fundamentally flawed and the core APIs is a mess

While that's debatable (worse platforms exist), it also misses the entire point. Nobody is saying that sharing the code for left-pad is a bad idea. Wrap it up properly into an extended-standard-library and distribute it with node/etc.

What is conspicuously missing is any discussion at all about the costs of depending on 3rd party libraries. Adding a network, 3rd-party dependency to your build or deploy process is a huge risk that at the very least needs to be justified.

Note that I'm not saying that using 3rd party libraries is bad; I'm saying it has a cost paid in additional risk. You can decide if that cost is a fair exchange for the benefits you gain from the library. Just remember that humans are terrible at evaluating risk, so it might be a good idea to limit how much risk you take on.

Look, I don't disagree that Javascript itself creates some of the problems in its ecosystem, but complaining about 8 whole extra keystrokes to support IE9 doesn't really help.

To fully get the point, extrapolate that example out over every single task you might want to accomplish. As someone who used to do a lot of Javascript for side projects but works daily in Python, returning to Javascript for a new side project this week has been very annoying and frustrating.

> extrapolate

So what - every language has places with extra verbosity, unfortunate function names, or other minor annoyances. The correct solution to this type of problem is either 1) just type it the compatible way and move on to a real problem, or 2) use an editor macro such as TextMate's snippet[1] feature or the emacs variant yasnippet[2]. Code templates have been a solved problem for a long time.

[1] http://manual.macromates.com/en/snippets

[2] https://www.emacswiki.org/emacs/Yasnippet

Strawman much? His example was obviously not about the number of keystrokes, it's about the standard lib functions that JS includes. indexOf !== -1 vs includes()

Irrelevant much? He can just use indexOf != -1 and it will work both in old and new browsers.

And whatever JS includes or doesn't include, he should use ONE bloody library, like Lodash to fill in the gaps, instead of some micro-monstrosity like "left-pad".

Sorry no - you're missing the point of the grievances that were aired.

The problem is Javascript culture itself. It's culture has directly influenced the way NPM packages are made.

If "JavaScript just needs to become a better language" is it wise at this point to really be trying to use it for every possible thing? JavaScript has its place and building a web app without it today is very rare but I don't understand why so many are trying to depend on it for so many things that it's not intended for or at least ready for.

"I see us JavaScript developers as hurdle-runners where every 30 seconds we need to jump over a new obstacle."

That's not a good thing imo.

When you want to build web apps, you have to stich together HTML and CSS. That's intrinsically text processing.

To not have a check if one string includes another and/or to not have functions for padding is strange in 2016. Fine, let's not have it inside the language. But the dev community should at least agree to use one good package like lodash instead of playing "mine is better than yours" like in the damned highschool. This is a job where people make money and business decisions are made. The tech bros need to learn some professionalism.

ES6 has a bunch of "modern" features 1/3 of which I won't ever use but hell, the committee be damned if they allow string padding functions! :D Or God forbid they make a good use of "use strict" to make the language more predictable and eliminate most of its quirks in it.

The more I work with JS the more sad I am Dart isn't taken seriously.

It's all because of the don't-override-native objects religion. If only mootools had won instead if jQuery. It would have shown a goal API that browsers would have slowly implemented. Those libs need update at each major browser version, anyway.

I don't doubt that JS development is helped via such packages, but pulling in an external dependency to solely to pad a string seems like a bad idea. Introducing cascading chains of dependencies that you have no control of (left-pad was republished by someone who was not the original publisher, and AFAICT the original could have been replaced by the original author at any time with a malicious version) strikes me as a great way to create brittle code, both from a security and a stability perspective.

NPM restricts the developer from being able to push to the same version of a package twice.

If you explicitly requesting a particular version, that mitigates the security concerns to some degree (though as this incident proves, you are still reliant on that version being published for proper functionality).

That said, the fact that npm's blog [0] indicates that a republished package (with a new version number) mitigated the issue to some degree, and this comment [1] suggesting that the default behaviour is to get the latest minor release, makes me wonder how widespread of a practice that is in reality.

[0] http://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm [1] http://www.haneycodes.net/npm-left-pad-have-we-forgotten-how...

Unless you unpublish then republish over it.

This was possible before but no longer true. A version X will either return the original version X or a does not exist (if you unpublish)

I ask this with genuine curiosity. I'm an outsider when it comes to js development really. A while ago a lot of discussion was made regarding libraries like jquery and frameworks made to solve common problems. Much of the argument went along as "why are you using such a big library when you are using just a tiny part of it?? Don't be lazy!"

Now in the wake of leftpad issues, the most common argument I've personally observed, has been "why are you using a library that solves just this one problem? Use a library that provides the full utility around this problem area (strings)".

It feels strangely contradictory but I'm most likely missing some context here. Just wondering what it is :)

In general you're just seeing different people make different arguments, and the proposals which solve the most recent problem are the ones being suggested loudest right now.

Perhaps. In my view, inferior programmers will always blame the language. Every language has its shortcomings, and server side languages have, in my view, far more shortcomings than client-side javascript. I program in angular, so the experience is pretty good. As long as I can debug and have a comprehensive framework I'm fine.

ES6 should get us there, and I for one really like coding in javascript.

I really like JavaScript as a language - Better than any other language. I agree though, we needs more utility functions as part of the core lib.

I like JavaScript a lot too, but "better than any other language" ?

JS is just a scapegoat here.

Giving away a perfect valid package to a company without a legal order was lame. Unpublishing many packages without taking into consideration all dependents was lame. I can't help but think the people involved wouldn't repeat the very same decisions.

Despite any amount of blame tossed around, this is a micro hickup in the thriving ecosystem around npm / Node / Javascript. This statement is backed by data http://npm-stat.com/charts.html?package=clone&author=&from=2...

Thanks to node, npm and amazing OSS devs, we can count on modular packages to get the job done faster on the client and server, and that's really valuable.

Next time, please use a smaller font and leave out all the silly images. It took a long time to get to the bottom of the article, only to find out there was no real content.

Existence of micro-packages and the recent development saying that twitter as a host for micro-packages seems weird to me.

Twitter as a host was a joke. The zealousness for these micro packages, though, is all too real.

man i didn't even know about "includes" -- i always use indexOf

Are you really truly placing jquery in the same category as left-pad?

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact