21 ms·
NPM and Left-Pad: Have We Forgotten How to Program?
- buckbova 10y agoNearly everyone has had it drilled into them the "Don't reinvent the wheel." nonsense for better or worse. I use lodash in almost every javascript project I start, big or small because it makes my life easier. I'd rather use the lodash isArray than roll my own. https://lodash.com/docs#isArray https://lodash.com/docs#isArray
- n4sa 10y agoYeah but you're loading an entire library to use one function?
- xentronium 10y agoTree shaking.
- jessaustin 10y agoDo you support IE 8? If not, why not use the one provided by the language, Array.isArray()?
- cpeterso 10y agoThe latest version of lodash (4.0.0) doesn't support IE 8, so you would need to polyfill isArray() yourself or use a pre-modern lodash version.
- jessaustin 10y agoYeah I agree that polyfilling makes more sense than depending on lodash just to get isArray(). I wonder if we'll start seeing the sorts of "you don't need..." rants about lodash that we've seen about jquery for some time now?
- Nr47 10y agowhen you go out for food or order in, do you ask yourself "have I forgotten how to cook?" Sure in some ways NPM has packages that don't deserve the title of a package, but isn't the convenience of not having to reinvent every code worth it?
- jgrahamc 10y agoWhat concerns me here is that so many packages took on a dependency for a simple left padding string function, rather than taking 2 minutes to write such a basic function themselves. It takes more than two minutes. That little module has a test suite, if you're including it then you have some assurance it does what it says it does. If you write it you've got to worry about whether it works or not.
- deleted 10y ago[deleted]
- Alex3917 10y agoSo any developer could make this in five minutes, but for some reason they can't verify whether or not it works? That doesn't make sense. In reality it could take an hour to get this working properly, but it does take only a couple minutes to verify that the solution here is correct. There are certainly good reasons for not adding extra dependencies to your project, but trading a known amount of time to check that an existing project does what you want for an unknown amount of time to redo it yourself is probably not a great bet.
- mastazi 10y agoUsually, dependency hell doesn't bite you, until it does. Try to rebuild that thousand-dependencies app in three years from now and you'll see ;-) I recently had to rebuild a large RoR app from circa 2011 and it took me longer to solve dependencies issues than to familiarise myself with the code base. Excessive dependencies are a huge anti-pattern and, in our respective developers communities, we should try to circulate the idea that, while it's silly to reinvent the wheel, it's even worse to add unnecessary dependencies.
- emidln 10y ago> Try to rebuild that thousand-dependencies app in three years from now and you'll see ;-) This is your fault for expecting free resources to remain free forever. If you care about build reproduction, dedicate resources to maintain a mirror for your dependencies. These are trivial to setup for any module system worth mentioning (and trivial to write if your module system is so new or esoteric that one wasn't already written for you). If you don't want to do this, you have no place to complain when your free resource disappears in the future.
- xeromal 10y agoMost of the time this is something you inherit. Not something you wrote.
- emidln 10y agoA maintenance programmer should be raising to management the risk if they do not have reproducible builds. The issue isn't that the company's software has a dependency. The issue is that the company is taking for granted the generosity of others. If they did not get a reproducible build before, they should attempt to get one as soon as they are aware of the problem. If the package is no longer available, they must now accept the punishment in terms of lost staff time or dollars to work around the lack of the dependency.
- mastazi 10y ago
- tschellenbach 10y agoIn a way this shows what a great job NPM did at making it easy to publish packages. It's so easy that people decide to package up extremely easy functions. As a python developer I would never publish a small package, simply due to the overhead of setting up a PIP package.
- jessaustin 10y agoOh God yes. After being spoiled in npm-land for a couple of years, I went back and tried to re-release a very small python module I had written before. I simply couldn't do it. Oh well!
- scrollaway 10y agoVery true. Although pypi is in a better position than npmjs.org on a few fronts (including security), it's also such a pain in the arse to deal with. Packaging is by very far my least favourite part of python.
- adambard 10y agoI think it speaks to just how lacking the baseline Javascript standard library is. The libraries that come with node help, but all of this stuff seems like it should be built-in, or at least available in some sort of prelude-like standard addon library. The lack of either leads to all these (apparently ephemeral) dependencies for really simple functions like these. That said, I work with Java, Clojure and Python mostly so I may be more used to having a huge standard library to lean on than is typical.
- zbuttram 10y agoSo many people use lodash as a drop-in standard addon library that I'm surprised people aren't just using the padding functions that are right in there... Some of the packages that broke yesterday even have lodash included as dependencies already!
- bencoder 10y agoProbably they do use that if they need left padding but also have a dependency on another package that thinks 'lodash is too big when all I need is left padding' so we get to this situation
- hepta 10y agoWhat if lodash itself was unpublished? I'm having a hard time drawing a line here, obviously a 10 line function is too far on the bad side of lazy, but I can't tell what is an acceptable dependency.
- NathanKP 10y agoI don't see anything wrong with using a pre-made left pad function. Why waste time and lines of code implementing something so trivial when there is already a solution available? However, I agree it is ridiculous to have a dedicated module for that one function. For most nontrivial projects I just include lodash, which contains tons and tons of handy utility functions that save time and provide efficient, fast implementations of solutions for common tasks. Lodash includes `padStart` by the way (https://lodash.com/docs#padStart https://lodash.com/docs#padStart).
- chipotle_coyote 10y agoI think the article's thesis is essentially that every dependency your project pulls in -- which includes all the dependencies your dependencies pull in -- is a point of potential failure. I understand the "don't re-invent the wheel" defense, but the Node/JavaScript ecosystem tacitly encourages its users to build vehicles by chaining together dozens of pre-made wheels, all of which depend on more wheels, and each and every one of those wheels has a small but non-zero chance of exploding the next time you type "npm update." (And, y'know, maybe it's because I'm not a JS programmer, but the notion of looking for a module to implement a string padding function would never have even occurred to me.)
- joantune 10y agoThe problem is not that, the problem is depending on unreleased versions, instead of simply depending on the version that was written when u wrote your code. a Git submodule like approach would be much better
- nv-vn 10y agoWorse yet, a backdoor or legitimate bug in any of these module could leave huge exploits in the entire Node.js ecosystem.
- smokeyj 10y agoWorse yet, the OS is compromised. This is why I hand roll all my encryption libraries. /s
- runin2k1 10y agoHoly moly-- is-positive-integer/index.js: var passAll = require('101/pass-all') var isPositive = require('is-positive') var isInteger = require('is-integer') module.exports = passAll(isPositive, isInteger) I retract my previous statements that Javascript programmers are going down the same enterprise-y mess that Java programmers went down a decade ago. They've already taken it to an entirely different level of insanity.
- raverbashing 10y agoYeah, I thought the dependency thing was a joke (I mean, to have a package for is positive integer is already a joke, but come on) Really
- onli 10y agoI think it actually is not. That's from some years ago and my memory of it is fuzzy, but at that time it was surprisingly hard to check whether a variable is a positive integer – maybe it was a negative one though and that was harder? You'd think it is just checking whether it is an integer and bigger than 0, or just checking whether it is bigger than 0. And it is. But to get that code to work reliably, regardless of whether it gets a string or float or an undefined, with the JS type system of that time and in multiple browsers, even the crappy ones, that took some time. There was one specific edge case involved. Not that it was impossible, but I still remember having to search for it and being astonished that that was necessary. Sure, should not apply anymore like that.
- msbarnett 10y agoBe that as it may, is-positive doesn't handle any edge cases https://github.com/kevva/is-positive/blob/master/index.js https://github.com/kevva/is-positive/blob/master/index.js That's half the problem with these stupid micromodules; they're not abstracting complexity, they're obfuscating simplicity.
- onli 10y ago
- ocdtrekkie 10y agoMy current programming project, my goal has been to do as much in-app as possible. Does that mean I'm more likely to have bugs in my own code? Yes. But I've learned a ton doing it, and I know that my code doesn't have a giant monster of bloat hidden behind some random dependency somewhere. And yeah, that means when I wanted to handle email, I learned a heck of a lot about how programs handle email. Did it take more time? Yup. Education is time well spent. I've got two dependencies besides the basic framework my project is built on: A scheduling engine, and a database interface. I eventually hope to factor out both.
- bronson 10y agoSpoken like someone who doesn't have a tight deadline.
- ocdtrekkie 10y agoThat's true, I don't. But if your deadline is too tight to do it right, maybe you need to reevaluate your project plan. I mean, I can certainly see using more dependencies than I'm using. Mail is a great example of something that probably should be handled by dedicated, well-tested code. But to carelessly dump piles of third-party dependencies in your project to save a few minutes, as talked about in this article... just crazy.
- engi_nerd 10y ago"If you don't have time to do it right, you will be forced to make time to do it again."
- bronson 10y agoSpoken like someone who isn't on a tight deadline.
- atjoslin 10y agoCounter-argument: A good micro-module removes complexity. It has one simple purpose, is tested, and you can read the code yourself in less than 30 seconds to know what's happening. Take left-pad, for example. Super simple function, 1 minute to write, right? Yes. But check out this PR that fixes an edge case: https://github.com/azer/left-pad/pull/1 https://github.com/azer/left-pad/pull/1 The fact of the matter is: every line of code I write myself is a commitment: more to keep in mind, more to test, more to worry about. If I can read left-pad's code in 30 seconds, know it's more likely to handle edge cases, and not have to write it myself, I'm happy. The fault in this left-pad drama is not "people using micro-modules". The fault is in npm itself: all of this drama happened only because npm is mutable. We should focus on fixing that.
- oblio 10y agoI don't agree with the explosion of micro-modules. There's a reason the vast majority of languages doesn't have them, at least not at function level. IMO in the Javascript world they're only there in order to minimize script size for front end work. See lodash & lodash-something1 / lodash-something2 / ..., where there's an option of using the whole module or just including 1-function long scripts, precisely to avoid the script size issue. Is there a solution for this? I know that the Google Closure compiler can remove dead code, ergo making inclusion of large modules less costly in terms of code size. Am I missing some ES6 feature that also helps with this?
- raverbashing 10y agoNo, no, no Left padding is (almost in all languages) built-in, even C can do it with printf (edited) The problem is not having a library that offers that, but having this micro-module thing as a whole NPM module. No other language does that. If it was inside a string helpers, that's great. But don't make me one single module for just left-padding (or is-integer-number)
- baudehlo 10y agoJavaScript much to my dismay has no sprintf. It's one of the most annoying omissions ever for server side work.
- anonymousguy 10y agoThis is acceptable because web developers expect a certain level of coddling. Many developers are quick to defend this insanity because they simply cannot see their own level of entitlement.
- spo81rty 10y agoAs a dot net developer I avoid adding packages and references at all costs due to all of these same reasons. Usually for something simple like this left pad example, I just copy the code and put it in to my project in some sort of class of helper functions or extension methods. Seems like a lot of these basic Javascript functions need to be built in to javascript/node itself or consolidated down to a single package of common core functions that extend Javascript. Like padding, is array, etc. As others mentioned, these are fundamental things in other languages.
- mooreds 10y agoRelevant: '"The Excel development team will never accept it," he said. "You know their motto? 'Find the dependencies -- and eliminate them.' They'll never go for something with so many dependencies." In-ter-est-ing. I hadn't known that. I guess that explained why Excel had its own C compiler.' http://www.joelonsoftware.com/articles/fog0000000007.html http://www.joelonsoftware.com/articles/fog0000000007.html
- jussij 10y agoConsidering the fact that Excel had to run on multiple versions of Windows and also run on the Apple Mac I can understand why they would hate hidden dependencies. I've experienced the joy of trying to make sure Win32 code runs on Windows 3.11 (with Win32s), Windows 95, Windows 98, Windows Me, NT, 2000 and XP. Generally it all works, but sure enough there are times when a small code change breaks one or more of those platforms. Luckily these days things are much better as Win32 is a lot more consistent.
- xigency 10y agoThanks for a great post.
- tiglionabbit 10y agoThis is just more evidence that the unit of code is a function, not a module. Eventually, given a pure enough language, every "package" could contain only a single function, and every function in a project could be published as an independently reusable unit.
- danharaj 10y agoOnly if your modules are little more than textual inclusion and perhaps a mechanism to deal with name clashes. ML style modules are way more substantial than that, they can be used as units of abstraction.
- CodeOtter 10y agonpm install goldmansachs
- Animats 10y agoIt beats the alternative - pulling in some huge package with lots of little functions, all of which end up in the output. At least you're not loading huge amounts of unreachable code into the running system. In languages with linkers, the better linkers would discard all unreachable functions. Then came DLLs. Use one function in a DLL/.so, and the whole thing has to be loaded. Go and Rust are usually statically linked, reflecting the fact that pulling in big DLLs was usually a lose. You rarely have two different programs on the same machine using the same DLLs, except for some standard low-level ones such as the C library.
- darawk 10y agoEverything in this article is categorically wrong and antithetical to every principle of good programming ever articulated. The only problem here, as others have already noted, is that NPM allows people to delete published packages. Small modules are not evidence of a problem, and they certainly aren't evidence of an inability to implement these things on the part of the people depending on them. Why would I implement left-pad myself when there is already a well-tested implementation that I can install? Building up an ecosystem of tiny abstractions, bit by bit, iteratively and evolutionarily, is how we get robust, well-designed complex systems. We don't get there by everyone reinventing the left-pad function to sate some misplaced appetite for self-reliance. The author seems to make some arbitrary distinction between things that are 'large enough' to be packaged and 'pure functions' which are 'too small' to be their own modules, and I just couldn't disagree more. Tiny, pure functions are ideal modules. They facilitate the greatest degree of re-use, most clearly articulate what they ought to be used for, and stateless things are, in general, more composable than stateful things. There is no better unit of re-use than a tiny, pure function.
- smrtinsert 10y agoI wish I could say you were joking. At best it comes off as ivory tower idealism, at worst the complete naivete of someone who doesnt code.
- darawk 10y agoI'm not sure if you're saying this of my comment or the OP, but I code professionally every day in this style and it's working out just fine. And the smaller my modules get the better it seems to work.
- rantanplan 10y agoIt's not working out fine. You just haven't been around long enough to understand it. JS code is the most disposable piece of any infrastructure. In all companies(mine included) that I know of, npm and the JS jenga tower of hell is the most brittle element that breaks every fucking day. It's the constant pain you can count on being around. The stack and the dependencies are a moving target. Like.. every minute. If you had coded in any other language other then JS you would know that. Come to me after 5 years and tell me if your "professional" JS code you're writing today is used by anyone and then we'll talk. I'll be waiting.
- danielrhodes 10y agoIt does seem pretty insane, but how many of these are polyfills?
- sebringj 10y agoThis is a non-issue and taking focus away from the real issue. The issue is the security hole that NPM opens up when a namespace can be grabbed up by anyone if the original developer pulls out.
- edejong 10y agoPersonally, it's not about the 'original' developer pulling out, but about the simple question: who or what do you trust? 1. The developer, 2. The content distributor, 3. The code (by git SHA ref perhaps), 4. The contract of the code (using formal verification), 5. The legal contract with the code supplier. And if you trust 1, do you expect of him to sign the stable releases using GPG tags? All the focus on OSS nowadays seems to be on 1, but as professional engineers, shouldn't we focus more on 4 and 5?
- jlg23 10y agoThe OP is deliberately talking about a completely different issue that just happened to be spawned from the recent drama. He is talking about learning to code vs asking google for implementations of even the most trivial things and about what a useful library is.
- sebringj 10y agoI know I wasn't interested in doing any JavaScript until they started modularizing it and npm was that on crack. Possibly once the kids had their shiny new npm, some went mad with power and took it too far. Take the good with the bad though as the JavaScript language is known for.
- c3t0 10y agoFunctions Are Not Packages Cracked me up :D
- xdissent 10y agoIn the case of left-pad, 2538464 of its 2550569 downloads last month are attributed to dependents of the line-numbers package (https://www.npmjs.com/package/line-numbers https://www.npmjs.com/package/line-numbers). So it would appear that relatively few people directly rely on left-pad, which highlights the importance of vetting the dependencies of dependencies.
- habosa 10y agoThis is in the description of line-numbers: DEPRECATED. This is a rather silly package that I do not recommend using. It's easier to copy the ~20 lines of code of this package and customize that code, rather than downloading and learning how to use this package.
- Macha 10y agoCommitted five hours ago: https://github.com/lydell/line-numbers/commit/711f6ad0eb1771341aecb59d83f139a24d862dba https://github.com/lydell/line-numbers/commit/711f6ad0eb1771... This mess appears to have convinced the author of that.
- nostrademons 10y agoAbout 2/3 of those (1.7M) were from babel-code-frame, which is a core dependency of babel: https://www.npmjs.com/package/babel-code-frame https://www.npmjs.com/package/babel-code-frame And the fix was just to drop the functionality and inline the function as a no-op: https://github.com/babel/babel/commit/09287643c712bcd203bbd6f2f9fa7a9ae54026b8 https://github.com/babel/babel/commit/09287643c712bcd203bbd6...
- andrewingram 10y agoThis is from a client-side web dev perspective: I'm hoping that proper support for ES6 modules to enable tree-shaking bundle builds (in the short term), and HTTP2 with client support for modules (in the long term), will allow us to head towards a world where we converge around a handful of large utility libraries. In theory, tiny dependencies was supposed to allow us to only include code we actually needed in our bundled code. Bu the reality is that everyone uses different tiny dependencies for solving the same problem. So you end up with enormous bundles made up of different solutions to the same tiny problems.
- gardano 10y agoWhen I was prevented from upgrading Xcode/Swift for a project last year because of podfile dependencies, that cemented in my mind that every time I include a dependency, I'm putting myself at risk. If I can spend half a day writing the code myself, I will -- because I know it will prevent headaches down the road. Yes, yes, I know any code I write adds the probability of bugs down the road. But at least the roadblock would be of my own doing, and not dependent on if/when the package maintainer upgrades their stuff.
- mtalantikite 10y agoOne of the things I've enjoyed the most while programming in Go for the past couple years is the standard library and how much the Go community emphasizes keeping external dependencies to a minimum. For most projects I find myself using few if any external packages. Now of course there are times you'll want to reach for a library, say for something like an http router, and up until recently the dependency management side of Go has been lacking. But when a pattern or library arises that many find useful the core team is open to pulling that in to the standard library if a strong enough case is made, for example in the context package (https://github.com/golang/go/issues/14660 https://github.com/golang/go/issues/14660).
- 88e282102ae2e5b 10y agoTo me, this looks like a symptom not of bad programmers but of a terrible standard library.
- nobody_nowhere 10y agoWell put. When a hammer requires endless accessories to drive a nail, is it the right tool for the job?
- asragab 10y agoThis was probably grotesquely naive of me, but I literally had no idea how jenga-tower like the javascript ecosystem was. Eye opener!
- ycmbntrthrwaway 10y agoWhat would happen to all those NPM projects if GitHub is destroyed? I don't think it will close anytime soon, but lets say, a meteor shower hits GitHub data center or something along the lines of this.
- BinaryIdiot 10y agoWell npm doesn't use GitHub for hosting of modules so honestly npm would be fine. Bower on the other hand would be completely screwed.
- jessaustin 10y agoIt is the nature of git that most repos on GitHub also exist in many other places.
- __jal 10y agoI still find it hilarious that, upon the bulk of SCM use shifting to a DVCS, the first[1] thing people did is run out to build a central hub. [1] For the pedantic, it probably was not literally the first thing; I'm sure some folks went to the rest room, others ate something, still others took a nap.
- mbrock 10y agoThat's because central hubs are very useful...
- smsm42 10y agoThe thing with DCVS is not that central hub does not exist. It is that you do not need specific central hub. That means if github dies, I can take any of my git repos I checked from github and continue working with them, and create a local git server that would allow others to work with it. Of course, there is a convenience value in having central hub. The point is not denying that, the point is turning it from necessity to option.
- vdnkh 10y agoI don't have an issue with modules or the Unix philosophy, I have an issue with using NPM for all these tiny modules. Hint: you can make your own modules, store them within the project, and add them to your package.json to be required anywhere.
- sauere 10y ago> There’s a package called isArray that has 880,000 downloads a day, and 18 million downloads in February of 2016. It has 72 dependent NPM packages. Here’s it’s entire 1 line of code: return toString.call(arr) == '[object Array]'; How anyone can deal with JavaScript for more than 5 minutes is absolutely beyond me
- pfooti 10y agoSensationalist stuff. isArray doesn't depend on anything, but lots of other packages depend on it. Why? Because it's actually kind of hard to tell the difference between an array of things and an object with integer keys. The Array.isArray function wasn't added to the language until ES5, so you need a way to shim older tests. If you're writing only for modern browsers, you don't need it (if you actually visit the code in question you'll see it defaults to Array.isArray - in that sense, it's a polyfill or whatever). But if your code might run on old browsers, it can't hurt to have it, and it cleanly encapsulates a trick that you no longer have to remember the syntax for.
- joantune 10y agoOne can argue that modules are good, but them depending blindly on newer versions like that was bad dependency management. I say this because I strongly believe that reinventing the wheel is unnecessary and can bring more problems than not. There are many examples, and I could come up with a made up one, but here's a very real bug that I debugged from another programmer not so long ago: So, he came up with a JNI for SPSS's C library, applied it correctly, and got haunted for lots of months with an unsolvable bug. The problem? he miswrote the final copy of the file, and sometimes, some bytes where copied twice. He tried to solve this problem for a long time (and eventually lived with it because SPSS was still resilient to this) Is this concrete example of a 'module' ridiculously short? yes, but my logic still holds IMO.
- supermatt 10y agoThere are lots of useful titbits often left out of a languages corelib. Back in the day we would have built up various pieces of library code, which we would have utilised rather than continually guessing best practices. For example, the isArray method cited may be trivial but is also non obvious. We'd probably have something like that in our library of useful snippets. Sometimes we may have shared the code on forums and the like and people would copy and paste the code, sometimes into their own libraries. We would locate them by browsing known locations or inefficiently querying search engines Now we utilise a central resource and simple tools to have a global library of code. Instead of searching far and wide we query a handful of tools that effectively does the copying and pasting for us. How that can be considered a bad thing is beyond me. It's not a question of knowing how to code, it's a question of using your time effectively. Granted, there is the problem of so-called modules being removed and dependencies breaking. This can be alleviated by vendoring your modules, a simple task with most dependency management tools. Personally I think that published modules should persistent indefinitely based on the license the code utilises, although I'm not clear on the actual legalities of the recent npm issue (although if it's due to a trademark complaint, I don't see how it would ever be enforceable for completely unrelated code in any slightly sane country).
- nikolay 10y agoWe have. I spent some time optimizing [0] a String.repeat function over at Stackoverflow and I was surprised that many developers today don't know what they are doing, including core team members [1]. Specifically, function repeatString(str, len) { return Array.apply(null, { length: len + 1 }).join(str).slice(0, len) } [0]: http://stackoverflow.com/questions/202605/repeat-string-javascript/36173160#36173160 http://stackoverflow.com/questions/202605/repeat-string-java... [1]: http://stackoverflow.com/questions/202605/repeat-string-javascript/35319469#35319469 http://stackoverflow.com/questions/202605/repeat-string-java...
- Macha 10y agoSo I don't think this is an example of core team members who don't know what you're doing. This function repeats a string up to a certain length. e.g. repeatString(foo, 10) = foofoofoof This could entirely be what the developers needed in their code base. The fact that it doesn't repeat a string N times, is at best, an example of bad naming. The issue here is that someone unrelated to the core team grepped the node codebase for the term they wanted and threw a function up as a SO answer without understanding what it did.
- nikolay 10y agoAllocate and join an array of blanks just to repeat a string is acceptable?!
- Macha 10y agoI guess I'm also as guilty of looking at input/output rather than implementation here.
- nikolay 10y agoHere's a benchmark [0]! [0]: https://jsfiddle.net/nikolay/Lgshxrk8/ https://jsfiddle.net/nikolay/Lgshxrk8/
- jestar_jokin 10y ago
- IvanK_net 10y agoWhen am I developing some large project for a long time, sometimes I find, that I have reimplemented the same function at several places (few years between implementations).
- UK-AL 10y agoI find NPM packaging ridiculous. Awhile I go I used NPM on windows, where the folder hierarchy became so deep it broke windows file handling. I could not delete the modules folder. I had install a npm package which allowed me to delete it. I think this is fixed in new versions by flattening the hierarchy, but still.
- xirdstl 10y agoI've been there. If I recall correctly, I found that a "rmdir /s" from a command prompt does the trick.
- larkinrichards 10y agoI wanted to write this post after the left-pad debacle but I've been beaten to it. I think we got to this state because everyone was optimizing js code for load time-- include only what you need, use closure compiler when it matters, etc. For front end development, this makes perfect sense. Somewhere along the line, front end developers forgot about closure compiler, decided lodash was too big, and decided to do manual tree shaking by breaking code into modules. The close-contact between nodejs and front end javascript resulted in this silly idea transiting out of front-end land and into back-end land. Long time developers easily recognize the stupidity of this, but since they don't typically work in nodejs projects they weren't around to prevent it from happening. New developers: listen to your elders. Don't get all defensive about how this promised land of function-as-a-module is hyper-efficient and the be-all end-all of programming efficiency. It's not. Often times, you already know you're handing a string, you don't need to vary the character that you're using for padding and you know how many characters to pad. Write a for loop; it's easy. Note that this is exactly the sort of question I ask in coding interviews: I expect a candidate to demonstrate their ability to solve a simple problems in a simple manner; I'm not going to ask for a binary search. Separately, I'll ask a candidate to break down a bigger problem into smaller problems. In my experience, a good programmer is someone who finds simple solutions to complex problems. Note: rails is similarly pushing back against developers that have too many dependencies: https://www.mikeperham.com/2016/02/09/kill-your-dependencies/ https://www.mikeperham.com/2016/02/09/kill-your-dependencies...
- panic 10y agoFunctions are too small to make into a package and dependency. Pure functions don’t have cohesion; they are random snippets of code and nothing more. Who really wants a “cosine” dependency? We’d all really like a “trigonometry” dependency instead which encompasses many “tricky” functions that we don’t want to have to write ourselves. This is a pretty weak argument. What is "cohesion" and why do we care that modules have it? Joe Armstrong, one of the creators of Erlang, has argued the opposite (http://erlang.org/pipermail/erlang-questions/2011-May/058768 http://erlang.org/pipermail/erlang-questions/2011-May/058768): that lots of small, individual-function modules are better than a "misc" module that grows endlessly and may overlap with other people's "misc" modules. Calling a function instead of writing the code yourself doesn't mean you've forgotten how to program! The real problem here is the cost and risks associated with dependencies in general (both of which are actually lower for single-function modules), and the broken package removal policies of npm.
- GFK_of_xmaspast 10y agoThere's a big difference between a "misc" module and a "trigonometry" module.
- gosub 10y agoI would retort with: Packages are too big to make into a functional dependency. In the end, in this functions-as-dependencies world, a trig package would be something like: (name) => switch (name) { case 'sin': (x) => sin(x); break; case 'cos': (x) => cos(x); break; }
- lmm 10y agoPackages are only too big if your infrastructure makes them too big. A trig package like yours could be implemented on top of sin and cos packages if it's something you find useful.
- rimunroe 10y agoI'm not really sure whether or not I should to add my voice to the din, but I feel like this whole thing is more a problem with npm and what it allows vs. what it encourages (and the rather paltry standard libraries in Node & browsers), rather than a problem with developers feeling entitled to not have to write their sorters and padding functions. npm actively encourages structuring projects as many tiny individual modules and dealing with the resultant dependency trees and deduplication. Both of these things (along with the ease of publication) combine to encourage people to share their packages. They make it incredibly easy to consume code from other people, but but at the same time provide a similarly low-barrier mechanism to retroactively change published code. That combination seems like a way more deserving topic of criticism than the unending refrain of "developers these days are so lazy".
- newobj 10y agoHave we forgotten how to program? Maybe we've forgotten how to /just/ program. Everyone bangs the drum so hard of "let github be your resume." Incentivizing putting every brain fart you ever had out into the universe instead of just keeping it to yourself. Just a thought.
- yoodenvranx 10y agoThe problem is not that we forgot how to program, the problem is that we never actually learned how to create a good programming language which avoids these problems. Just look at the whole build system and module hell of C and C++... I totally like the language C++ but I hate the tooling around it with a passion. As long as you only need stuff from stdlib then you are fine, but as soon as you want to create some custom library for use in your other projects? Which should compile on Linux and Windows? Either you use make and Visual Studio solutions or you have to fight with cmake... Just thinking about it makes me angry. For this reason I just don't use C++ very often. It is way easier to just use Python because most stuff is just an 'import library' away and you can concentrate on your actual program instead of fighting against the build system. But god forbid you actually try to ship your Python program to your customers... Why do I as a programmer have to deal with all this crap? I want to focus on programming and not on library management amd writing make files. My CPU is idle 95% of the time so there is enough processing power which could solve these problems. I have high hopes for Rust and it's integrated build/module system!
- adrusi 10y agoIt sounds like your problem with C/C++ tooling is that it's hard to support Windows. The reason for that is simply that microsoft bundles its own proprietary C++ toolchain with the platform-specific tools that Windows developers need. Windows developers don't want to install a second posix-like toolchain, and os x/bsd/linux developers don't want to install a Windows-like toolchain because in both cases the new toolchain wouldn't integrate as well with the rest of the system, and it would add unnecessary complexity to the operating system. The problem with proper unix tools, the ones that do one thing well and integrate with other programs as a part of their design, is that they make doing cross platform work a problem, because those other programs might not exist on other platforms. GNU Make works just fine on Windows, but you're not using just make when you write a makefile. Makefiles typically depend on GNU Make, pkg-config, gcc/clang (or another compiler with the same CLI), coreutils, bourne shell, and an assortment of a few other utilities. That means that Makefiles by design will only work on a single platform. The other operating systems have essentially made themselves into the same platform for these purposes through the use of system package managers. I've heard Windows is kind of getting one? More like homebrew than what we have in linux/bsd-land but that might still help. But maybe Windows developers will still be reluctant to install software with MinGW dependencies. That would be unfortunate, but fair; I wouldn't install a package that had Wine/Mono dependencies just because some asshole wanted to use their Windows build system on Linux! Hell, I avoid installing smaller things with a Qt or GTK3 dependency simply because none of the software I use needs those and I don't want to clutter my installed-packages list for something that isn't important. I'm not a huge fan of Rust's Cargo. The list of requirements that the Rust team had for their package manager and build system made sense, and if I had to design a tool that met those requirements, it probably would have looked quite a bit like Cargo, but it makes me sad that the most reasonable design is that which abandons the unix-like simplicity of the python and C (and perl?) toolchains.
- bliti 10y agoIt suddenly feels like the 90s all over again.
- po1nter 10y agoEveryone keeps mentioning the lack of a standard library for JavaScript as an excuse for this shit show. IMO this is just a futile attempt to mask incompetence.
- plugnburn 10y agoThis. Any modern standrards-compliant implementation of JS (following ES5 and especially ES6/ES2015 standard) already has everything that a sane programmer would ever need.
- tonetheman 10y agoAll the comments here have answered the question quite well. Yes we have forgotten how to program and we want to argue about it.
- lmm 10y agoIf your package manager is so cumbersome that it makes a 14-line package not worth it, get a better package manager. We haven't forgotten how to program. We've got better at it.
- Gnolfo 10y agoI totally agree. The npm ecosystem and the generally accepted practices in js these days come close to the bash style of composing & chaining a bunch of solid, specific little programs together to solve problems trivially that would have been a bear to do in many other platforms like java, C++, etc. I cringe at the idea that you should find yourself implementing l-pad in 2016, at least for the vast majority of projects that a typical engineer will encounter in their career. A similar case can be made for something as small as "is positive integer". While I agree, there are two counter arguments: 1) As noted in other comments, this is a reflection of the core libs of javascript not covering enough of the basics. This is a subjective thing when it comes to where to draw the line, but wherever the border lies between "core" and "community" libs, on the other side you start running into things like "L-pad" and "Lib-L-Pad" and "L-pad2". If there's a great enough fundamental need, you experience a lot of crowding where lots of people offer up their solution to this, and reconciling that across larger dep. chains that disagree on which one to use can become a real burden. 2) Have you ever had the conversation with an auditor (PCI, HIPAA, etc) that your application is actually built on top of a huge substrate of software written by unaffiliated 3rd parties? And that between your own iterations you could easily have different versions for any/all of them? It's a difficult conversation. Much less the explanations to QA about why a build failed because lib X was updated to a new hotfix version in the 14 hours since yesterday's build, after a couple hours of wasted time of initially suspecting your own diffs, and trying to navigate through all the indirection between the actual stack trace and what actually caused the blow-up...
- kf5jak 10y agoI wouldn't even think of looking for a package that does something as simple as the ones mentioned. If I need to pad a string, my first thought would be to create a new function, not look for a package...
- nly 10y agoNobody has forgotten. These people never knew to begin with. NPM/JS has subsumed the class of programmer who would have previously felt at home inside PHPs battery-included ecosystem. Before that, a similar set of devs would have felt at home with Visual Basic. Seriously, go visit the comments section on archived copies of the PHP documentation. You'll find code of a similar nature. If PHP had had a module system 10+ years ago you would have seen this phenomenon then. Instead it was copy and paste. This isn't elitism, it's just the way it is. The cost of a low barrier to entry in to a software ecosystem is taking in those who don't yet have software engineering experience. Nobody should be surprised that NPM, which I believe has more packages than any other platform, is 90% garbage. There are only so many problems to solve and so few who can solve them well, in any language. Put 100 programmers in a room, each with 10 years experience, and you'll be lucky to find 1 who has written a good library. Writing libraries is really hard.
- _wmd 10y agoPHP has had an extension module repository since 1999
- xrstf 10y agoComparing NPM to PECL/PEAR doesn't make much sense when talking about PHP developers. With PECL, the overhead of building a module in C is waay too high to make it viable for micro packages. And PEAR didn't just accept any random stuff, they were shooting for the one-solution-fits-all libraries and not tons of user-defined micro libraries like ecosystems like NPM encourage. Compare NPM to Composer/Packagist and you get a better comparision. I've personally seen only very few micro packages on Packagist, thankfully this never seemed to gain traction in the PHP world.
- ep103 10y agoThis is the answer, 100%. All it takes to publish an npm package, is the command npm publish, and you're done. So of course it is no surprise that there are tons upon tons of seemingly useless or tiny projects (gotta pad out that github profile for those recruiters!), or that there are then plenty of packages that use them. Add into that the fact that: 1) Javascript has a huge number of developers, and is often an entry-level language 2) The developers on this thread (I like to think of HN as at least slightly above average) are divided whether having small packages / large dependencies trees is a good or bad thing 3) Dependency management is something that matters mostly to long term (professional / enterprise / etc) applications, which is a subset of programming, and I wonder if not a minority subset of node.js projects in general. 4) If I'm writing a throwaway app or proof of concept, and therefore don't care about dependency maintenance, using as many dependencies as possible is a major time savor, and of course you get this situation, and it seems to make perfect sense. Personally, I wish there was an NPM Stable, where packages underwent much more scrutiny and security in order to get it, but nonetheless, nothing I've read so far about npm really scares me given the the above context. If you are a dev creating an unmanageable dependency tree for your enterprise app, you're a shitty dev. That doesn't necessarily mean that NPM is wrong for being so open in allowing others to publish their packages, or that smaller / more worthless packages shouldn't be allowed to publish. That said, I would really like to hear a response to this post, as I have limited experience with different package management systems.
- facepalm 10y agoWhat I don't get about Left-Pad, shouldn't they have used Arrays.join for better perormance?
- richmarr 10y agoArray performance isn't always better than string concatenation. In this test case it comes out slower: https://jsperf.com/left-pad-arrays/3 https://jsperf.com/left-pad-arrays/3 But ultimately it doesn't matter in the least for 99.9% of use cases: https://blog.codinghorror.com/the-sad-tragedy-of-micro-optimization-theater/ https://blog.codinghorror.com/the-sad-tragedy-of-micro-optim...
- facepalm 10y agoInteresting - well I thought if it is being used by thousands of libraries it might be worth optimizing. I just tried in NodeJS, you could also just instantiate an Array of a given length and join it with spaces, like this. var x = new Array(5);x[4] = "abc";x.join(" "); No idea if it could be faster - but the test you linked to pushes spaces into the Array.
- adamwong246 10y ago"There are no small parts, only small actors". - Constantin Stanislavski If there's a flaw to this debacle, it's that packages can be un-published. That is some grade A+ BS. But no, there is no such thing as a package too small. Coding is hard. Collaboration should be default-on, not default-off.
- morgante 10y agoThis shows the beauty and success of npm in making it very easy and cheap to publish small modules. It's not that we can't write a left pad function ourselves. It's that we might easily miss an edge case or make a mistake in doing so. The author seems to be hung up on a preconceived idea of what a package "should" be without actually offering a compelling argument for why a single short function can't be a module. Yes, every dependency you introduce is a liability. But so is every line of code you write. I'd much rather take the risk on a shared library which can be audited and battle tested by the entire community. If a function is so easy to write, it's trivial to check out the module's code, review it does the right thing, and then lock the dependency.
- jsprogrammer 10y agoThis post is too dismissive and confuses some topics. "Packages", "modules", "functions", and other words can mean different things within different contexts. Well-known and tested functions are useful. Putting them in a "package" is just a consequence of how node/npm work. There should certainly be a much, much better implementation of code sharing, but sharing and using well-known, singular functions should be exactly what we are going for.
- deleted 10y ago[deleted]
- peferron 10y agoThe funniest thing about this entire debacle is the thousand of self-assured programmers coming out to show the JS/NPM world how it's done, only to have their short, simple, no-nonsense functions fail miserably on some edge cases they didn't think about. This discussion about the "isarray" package is probably my favorite: https://www.reddit.com/r/programming/comments/4bjss2/an_11_line_npm_package_called_leftpad_with_only/d1ae85b https://www.reddit.com/r/programming/comments/4bjss2/an_11_l...
- nostrademons 10y agoSomehow, someone always forgets that engineering is about trade-offs, and so every few years we can an indignant series of articles about how stupid and ignorant today's programmers are and how we should all go back to the same processes that they called stupid and ignorant 4-5 years ago. Relying on reimplementation, copy-paste, npm shrinkwrap, or various other ways of importing third-party code into your repository results in the following advantages: 1. You know exactly what goes into your product, and can audit everything for security, performance, or coding standards. 2. You often end up importing less, as third-party modules may have functionality that you don't need but other clients do. 3. You can modify the resulting code to add showstopper functionality, even if upstream doesn't want to. 4. You aren't subject to the whims of someone removing your dependency from the Internet or replacing it with a version that does something you don't want. Relying on lots of little libraries installed via package manager gives you the following advantages: 1. You can easily install & try out modules that other people have written, letting you test out new features on users more quickly. 2. You can share code with other modules that have the same dependencies, often reducing the overall size of your system. This is important when there's a cost (eg. download size) to your total bundle. 3. You have less code for your engineers to read & maintain. 4. You can easily track licensing & contact information for your dependencies. 5. You automatically get any new features released by your upstream dependencies. 6. You automatically get security updates and performance enhancements released by your upstream dependencies. The last is nothing to scoff at: imagine if the headline, instead of 'left-pad breaks the Internet!', had been a security vulnerability in left-pad which literally broke the Internet. Imagine how hard that would be to fix if everyone had copy/pasted the code or re-implemented it. This is not an academic scenario either: remember "Nearly all binary searches and mergesorts are broken", published by the guy who wrote the broken binary search implementation in the Java standard libraries? http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html http://googleresearch.blogspot.com/2006/06/extra-extra-read-... Always copying your dependencies into your source tree is not the answer to this, no more than always relying on npm modules was the answer to updating your dependencies. They both have pluses and minuses, and if you really want to be a good programmer, you need to weigh both of them. For my projects, I tend to use whatever libraries I need when building them out (via npm, if possible), and then periodically audit the dependencies to make sure I'm still using them and they wouldn't be better off incorporated directly into the project. I wish more products did this, but I don't control what other programmers do.
- tn13 10y agoI don't think it is bad at all. For a lot of project where saving even a minute matters.
- blainesch 10y agoI think we missed the point here. The fact that it's 11 lines is meaningless, this could have been babel itself.
- return0 10y agoPackaging is the new programming.
- pfooti 10y agoSo, I suppose you could do something like this instead. function leftPad(str, width, pad = ' ') { const actualWidth = Math.max(str.length, width); return `${pad[0].repeat(actualWidth - str.length)}${str}`; } And that would do a leftPad pretty well, and be reasonably robust to stuff like the required width being less than the string width, the padding character being multiple characters long, and so forth. It doesn't do any type-checking of course. It also doesn't work on older browsers - both string.repeat and template strings are new. You could fake it with string addition, but addition behaves oddly in the case your arguments are numerical, whereas template strings handle that. There's also a trick where you can say (new Array(desiredLength + 1)).join(' ') to make a string that is the appropriate length, but you've got OBOEs to worry about if you're not paying attention (Array.join puts the character between the elements, so you need an n+1 array for an n-length string). Also, at least on some browsers, Array.join is pretty cruddy, and you really ought to construct the string with an old-fashioned for loop. Javascript has all kinds of weird corner cases and lots of browser compatibility problems. The fact that someone's written a decent implementation of something that should have been standard in the String object means I don't have to worry about it. Of course, I do have to worry about stuff like losing access to left-pad when someone throws an npm tantrum, or dealing with future build issues if npm becomes untrustworthy. A cryptographically sound package manager seems like a reasonable want, especially after this week's issues. But if your take-away from this whole problem is "meh, javascript devs are lazy", you're missing the point.
- nv-vn 10y agoHere's a proposal (that I'm sure others have come up with in the past) -- why not create one big, community backed "batteries included"-type module that would implement all the small, commonly used functions. This could combine all these ridiculously small libraries and greatly reduce the number of necessary dependencies for a package. Extending the standard library should be just that: standardized. If the entire community focused on one project like that they could just as easily write the same code (but with smaller package.jsons, less require()s, and less time spent learning new libraries/searching for the right libraries. In fact, it would be great if something like that could be packaged as a standard node module so you'd get the same sort of quality assurance as you get with official projects.
- chillaxtian 10y agobecause everyone would stop using it in a week when the next one arrived
- fredbot 10y agoI call this kind of attitude the "Tea Party" of JavaScript development. The reason why we currently have JavaScript tooling fatigue is exactly because Tea Party developers insist on writing everything themselves instead of trying to build a better abstraction. The lesson here isn't not fewer dependencies: it's managing dependencies. NPM should not allow someone to arbitrarily remove modules that other's may be depending on. It's like building a bridge and them deciding to remove it after a whole city now depends on it.
- xamuel 10y agoIt's more like planting a bush in your front yard, and for some reason the metropolitan train system decides to use your bush's shadow to tell the time of day, and builds that into every aspect of the entire city's transportation network. Then you cut the bush down and everyone starves.
- innocentoldguy 10y agoThis problem speaks volumes about the myriad shortcomings of the JavaScript standard library, in my opinion.
- spullara 10y agoIt seems to me that the JavaScript VMs should get together and start including standard library. That would also give the benefit that those would be highly optimized. They can keep it small at first and focus on number and string manipulation.
- imh 10y agoUnzipped, the source code for GNU coreutils is 30MB (zipped 4MB). This is a great example of a collection of single purpose functions you should never rewrite yourself. There's only one dependency if you want to use them because they're packaged together. With normal desktop code, 30MB doesn't really matter and you can link only what you need. Can you do that with the usual Javascript package managers/bundlers, or would you need to send the whole 30MB package to the client to use one function from it?
- smokeyj 10y agoWhat's with these kids and their "calculators". Back in my day we used a slide rule and we liked it! But seriously this is stupid. Programming shouldn't be the goal. Just because you can write a function doesn't mean you should. Every line of code you write is overhead that must be tested and maintained. I guarantee that if the author chose to hand roll code instead of using packages he'd have a lot more bugs. But he wouldn't know that until he hit some mundane edge case scenario in production.
- kbart 10y ago"Every line of code you write is overhead that must be tested and maintained." The problem is, that modules doesn't solve problems magically. Every dependency should be tested, maintained and kept online as well, by somebody else, whom you have no control of. In turn, you have a bunch of black boxes that can blow up your application anytime. Of course, another extreme of write everything yourself is also bad, so it's a trade-off that must be considered carefully. I've build many systems during my career and one of the biggest nightmare I encounter is managing dependencies.
- Wintamute 10y agoGoing down the "lots of tiny modules" route is about these three things: a) No standard lib in JS b) JS is delivered over the internet to web pages in a time sensitive manner ... so we don't want to bundle huge "do everything" libs. Sometimes its convenient to just grab a tiny module that does one thing well. There isn't the same restriction on any other platform c) Npm makes it really easy to publish/consume modules d) And because of c) the community is going "all in" with the approach. It's a sort of experiment. I think that's cool ... if the benefits can be reaped, while the pitfalls understood and avoided then JS development will be in an interesting and unique place. Problems like today can help because they highlight the issues, and the community can optimise to avoid them. Everyone likes to bash the JS community around, we know that. And this sort of snafu gives a good opportunity. But there many JS developers working happily every day with their lots of tiny modules and being hugely productive. These are diverse people from varied technical backgrounds getting stuff done. We're investigating an approach and seeing how far we can take it. We don't use tiny modules because we're lazy or can't program, we use them because we're interested in a grand experiment of distributing coding effort across the community. I can't necessarily defend some of the micro modules being cited as ridiculous in this thread, but you can't judge an entire approach by the most extreme examples.
- mdavidn 10y agoI think b) is true only because JavaScript tooling cannot perform dead code elimination. Other languages have big grab-bag utility libraries like lodash that don't hinder performance because a linker or runtime can avoid loading unused portions.
- digitalpacman 10y ago.... isn't this a problem with node, and not developers? Wouldn't you say this is a symptom of a systemic problem of the framework that it is lacking common features that everyone needs?
- haberman 10y ago> In my opinion, if you cannot write a left-pad, is-positive-integer, or isArray function in 5 minutes flat (including the time you spend Googling), then you don’t actually know how to code. Spoken like someone who writes functions in 5 minutes that I find bugs in later. Just because a problem is simple to describe informally doesn't mean it is simple to implement without bugs.
- kungtotte 10y agoIt would be trivial if the language lent itself to trivial solutions and there wasn't a culture of trying to anticipate and catch really messed up error cases that results largely from user errors. In Python I would write ´if num > 0´, if it matters that it is an integer I would cast it to int, and that handles everything you should be handling at that level. If your user passes in a list instead of a number type, the code should crash because then there's probably an input error somewhere. If a user has monkeypatched a base class to make a number into something else the code should also fail and you deserve whatever happens to you. Catching every possible error is a mistake.
- nick32m 10y agoWhat's the problem of writing a function with a few lines of code and exports as a module? I think it's totally fine. Like other people said, it's the mindset we borrow from Unix, do one thing and do one thing well. The function would be well tested, and could be reusable. I don't understand why so many people just require lodash into their project (when they start project) while they only use one or only minimum set of the functions. I mean lodash is a very great library with clean and well tested code, but it's also quite bulky like a big utility lib, and for me most of the time I only need one or two of the functions I would just go to npm and find a module just do that thing.
- meric 10y agoAlso, Node.JS modules can be used browser side. On the browser you only want to include code you're using so you're not making the client downloading excessive code. A large 500kb module with one useful function is worse than a one 10kb module with the one function you need.
- tomohawk 10y agoRob Pike: "A little copying is better than a little dependency"
- artursapek 10y agoAfter working with JS/Coffeescript/Python/Ruby for years, Go has been an enormous breath of fresh air for me. Of course it's all a matter of preference.
- pjlegato 10y agoYes, or more accurately a large new generation of coders is entering the workforce who know how to code only in a superficial sense and think this is a good thing. Programming, and especially startup programming, is being taken over by people who are primarily technicians rather than engineers. They want to assemble prefab components in standardized ways rather than invent new things. They are plumbers who know how to install from a menu of standard components, rather than civil engineers desigining purpose built one-off aqueducts. It is the inverse of the "not invented here syndrome." The technician-programmer is trained to minimize time spent thinking about or working on a problem, and to minimize the amount of in-house code that exists. The goal is to seek quick fix solutions in the form of copy/paste from StackOverflow, libraries, and external dependencies to the greatest extent possible. In house coding should, they believe, ideally be limited to duct-taping together prebuilt 3rd party libraries and services. Those who want to reinvent the wheel are pompous showboating wankers (they believe); creating your own code when you don't absolutely have to is a self-indulgent waste of time for impractical people who just like to show off their hotshot skills and don't care about getting things done. Move fast and break things and all that. This began with stuff like PHP but really got going with Rails, which preached convention over configuration as a religion, and supplied a standardized framework into which you could easily fit any generic CRUD app that shuttles data between HTML forms and a database (but is painful if you want to deviate from that template in any way.) Note that Rails doesn't use foreign keys and treats the relational database as little more than a glorified persistent hash table. This set the stage for Node.js (why bother learning more than 1 programming language?) and NoSQL (why bother learning how database schemas work?)
- quietplatypus 10y agoBravo. Saving this comment. For substance: Consider how this is all part of the effort by management to make programmers feel as interchangeable and insignificant as possible. And it's not even in the name of quality. Plenty of software out there breaks because of its multiple single points of failure in the form of dependencies.
- pjlegato 10y agoYes, totally. I can understand why management does this. Coders have a very high turnover rate as a profession. When your genius Clojure or Rust programmer leaves, it's much harder and more expensive to find a replacement than when your PHP or Rails programmer quits. This then incentivizes new coders to take up one of the popular languages, because that's what most of the advertised jobs are for, creating a self-reinforcing positive feedback loop.
- pkrumins 10y agoYes, we have. The entire Javascript ecosystem is a huge catastrophe. It will collapse any time soon. It's complex, fragmented and no one really likes it. There are a dozen different tools to get started. No one even understands how to get started easily. There are no fundamental tools. Everything is changing every week. You can't just build a product and then rebuild it even a month later. Nothing works anymore a month later - your dependencies have changed their APIs, your tools have different flags that do different things, there are new data models that you never needed and shouldn't even care about. The developers are in high stress. Devops engineers are in even higher stress because they get to see what developers don't. It's a huge mess and my advice to "prefer core-language solutions to small abstractions to small helper libraries to general libraries to frameworks" (http://bit.ly/1UlQzcH http://bit.ly/1UlQzcH) hasn't been more relevant than today. Software should be developed using least amount of complexity, dependencies, effort and using fundamental tools that have been and will be here for the next 20 years. Cut those dependencies, you don't need them. They're here today and won't be here tomorrow.
- lucb1e 10y agoYeah look at all these modern languages that do so much for you, like .empty() on an array -- have we forgotten how to do simple comparisons?! You could just take a second to consider the properties of an empty array, namely it contains no items (.count() == 0). My point being, if something is a completely reusable and basic feature, a dependency is totally just. I remember a few years ago when I and all devs I knew (which weren't many, I was maybe 17) had our own libraries to include in all personal projects we made. It contained features we had to look up once and from then on just automated and imported, stuff like password hashing or input checking. This went out of style as single-programmer programs are going out of style, but the little useful features are still there.
- BackPropagate 10y agoProgrammers haven't forgotten how to program. JavaScript script-kiddies never knew how to program in the first place.
- j-diaz 10y agoMaybe some people just want to claim they have a published module. Making them feel some sort of achievement or glory.
- maze-le 10y agoNot just making them feel... I think this may be targeted towards recreuiters, who may be impressed by the sheer amount of npm modules someone has published.
- deleted 10y ago[deleted]
- j-diaz 10y agoAnother explanation for the flourishing of these one function modules may be the fact that some people feel a kind of high/achievement from being able to say they have a published module out there. A sort of bragging rights if you will.
- usrusr 10y ago"I may not be Mick Jagger, but I am playing in a band and we did have some gigs (before we had that 50% decline in audience when my mother got bored and stopped showing up)" - just about every twentysomething before coding became a desirable career
- irascible 10y agoAhhh job security :D
- deleted 10y ago[deleted]
- irascible 10y agoAhh job security :D
- meric 10y agoNPM modules can be used on browsers. On browsers, space is a premium. Why would you want to install a 500kb dependency that has only one function you need, when you can install a 10kb dependency that has it? Would you want each of your five 20kb dependencies to re-implement the same 5kb function, increasing the code you must send to the client by 20%, or would it be more optimal for each of those dependency to use the same 5kb function? The author rants about practices of developers from different programming environment, without experience, without figuring how things came to be. If he did give an effort to think from the perspective from Node.JS developers he’d have addressed the previous two points. This is like going to a friend’s house and complaining everything is put in the wrong place. It would have been wise to immerse in Node.JS conventions and observe for a while before making comment. EDIT: Reply to scrollaway: I've also understated the problem. Let's look at the problem in the current Node.js environment, it's not uncommon for a web app to have 20 dependencies, each of those have 10, and each of those 10 have 5. That's a total of 20 times 10 times 5 = 1000 dependencies in total. Let's say you were to remove a 10 line library function that's "standard library-like", used by 15% of those dependencies, and have each of the existing dependencies re-implement that in each of those dependencies that uses it. 15% times 1000 times 10 lines is 1500 lines of code. So if you're going to troll a solid argument by nitpicking, do it properly and get the details right.
- scrollaway 10y agoIt's quite ironic how you're lecturing people about dependencies and bandwidth when you yourself don't seem to have a good grasp in your mind of how immense even 5 kilobytes is (you talk about 5kb functions). 5 kilobytes (well, KiB) is 5120 bytes. That's about 200-300 lines of code. If you're talking about minimized code, maybe up to 500 lines.
- eterm 10y agoWhile a 5kb function is immense, I work on a legacy code base and I have seen functions up to 2000 lines long. You possibly overestimate the quality of code that people in business actually write. I've worked in a few places and all have parts of the code which I would thought were made up if submitted to the dailywtf. Also, have you ever seen a commercial library require >2MB of minified JS? Here's an example: http://cdn.wijmo.com/jquery.wijmo-pro.all.3.20153.84.min.js http://cdn.wijmo.com/jquery.wijmo-pro.all.3.20153.84.min.js That file is almost 2MB minified (5.6MB unminified). And that is is only 1 of the few different files required for our dependency on it, there is a bunch more javascript/css also required. Would I use that library on a new product? I'd probably advise against it due to the size, but a legacy product has dependencies and you don't have the freedom to rewrite everything all the time.
- fiatjaf 10y agoNo saner alternative presented.
- lintiwen 10y agoI see two kinds of programmers here. Good programmers understand the risks of making your system depend on something you don't have control really well; They know how keeping system complexity low is like an good investment which makes your life later easier (low maintaining costs). Bad programmers stacks up technical debts such as including unnecessary dependencies until the system no longer works.
- smitherfield 10y agoWithout addressing the wisdom or lack thereof of including dependencies for small functions, perhaps the problem of disappearing/changing small dependencies could be solved with an option along the lines of npm install <small-dependency> <destination> --save-inline Which would just copy the dependency verbatim to <destination>. Maybe have a "<dependency> is 100kb. Are you sure you wish to copy the entire source to <destination> instead of using a 'require' reference? y/n" prompt for the inevitable silly types who'd do it with Angular.
- democracy 10y agoRe-usability is a good concept but can be overused easily.
- haddr 10y agoWhile in general I agree with the article I must admit that I also strongly DISAGREE with the overall message. Especially with this: "Finally, stringing APIs together and calling it programming doesn’t make it programming." Stringing APIs together is what actually programming is. This is building software and for instance when i use .toString() method I can easily forget how it is done, focus on other high level things and don't care about dependencies, as long as everything works fine. Let's admit that the main problem here is with broken npm, rather than packages themselves. If someone has written the "leftpad" function, it is so I don't have to write it again, and I can save probably 15-40 min programming and checking some corner cases. Also please note that javascript can be really tricky down in the details. So if there's anything that can help, it's better that it exists, rather than not.
- visarga 10y ago> Let's admit that the main problem here is with broken npm It is absurd to have packages suddenly retracted and important parts of the ecosystem stop functioning. This never happened with other languages I have used. Maybe we need a way to make sure the packages are always going to exist. Checksumming and adding the checksum to the version number would be useful too.
- haddr 10y agoThat's why there are proposals for immutable and distributed packages managers. Look at gx for instance. This is probably the future for package managers maintained by community.
- city41 10y agoI'd just like to point out that React does not have a dependency on left-pad. React has no dependencies at all[0]. devDependencies have no impact on third party consumers. [0] https://github.com/facebook/react/blob/master/package.json https://github.com/facebook/react/blob/master/package.json
- memracom 10y agoAgreed. Most development groups should be building a local collection of utilities that contains all of these snippets, and most importantly, some documentation of what they do and some unit tests to demonstrate that they are correct. No need to have global dependencies on small snippets that really should be in a core library anyway. C has libc, Java and C# have the creator's (Oracle or Microsoft) standard set of libraries, Python has the "batteries included" stuff in all the different distros. And so on. All of these snippets rightly belong elsewhere, not in packages. And even if you did get them added to the right libraries, I guarantee you that you will not get rid of the need for a collection of small, and somewhat random, in-house functions, classes and libraries.
- memracom 10y agoSeems that we need a tool to crawl all the repos that a developer owns and report lines of code in each package that they wrote. If there are lots of small packages, then this is not the kind of person you want to hire, except maybe to do PR. Real developers do not do stuff like this.
- xupybd 10y agoHave we forgotten how to program? No, we have changed the way we program. We leverage the work of others to solve ever more complex problems. When we do this we get more than just the simple functionality we require. We get all the testing that comes from a package being used by thousands of projects. We get updates when people find a better faster way. We get to lower the number of lines of code we have to maintain. Yes, these are simple tasks but do we gain anything doing these simple tasks ourselves? I find there is a finite amount of focus I have when programming, and I'd rather spend that solving the bigger problem. This reminds me of a discussion I overheard between two professors when I was an undergrad. Prof 1 "This new language makes it so much easier to x, y and z" Prof 2 "Yes but what's the point, I can do all these things in Java" Prof 1 "I could do all these things in NAND gates, but I'll get more work done if I have this tool."
- gsmethells 10y agoThe fact that anyone has to even think about code size is the real problem. Yes, downloading a giant JS lib for one function is insane, hence the ton of tiny dependencies. However, it is equally insane that basic SDK expectations found in every other language has yet to come to be pre-implemented by the JS engine in the web browser itself. Some basic code ought to already be on the localhost the moment your app arrives.
- qewrffewqwfqew 10y agoThe elephant in the room here is Javascript. No other scripting language has been so bloody awful in the past that a five-line module that saves you typing `array.prototype.forEach.call` or something that papers over the language's awful idea of equality comparison with three functions has been "useful" or "more than five minutes coding without references". Granted, these modules don't do such useful things, but that's the environment their creators were immersed in.
- colinmegill 10y ago^^ Nice, sane point.
- benedictchen 10y agoI find it interesting that blaming code reuse is a valid thing, but blaming a lack of test coverage and CI build testing is not. The problem is the lack of a test culture.
- lifeisstillgood 10y agoSurely there is a need to standardise on a set of well-maintained "batteries included" packages.
- pmlnr 10y agoThat is what PHP has, and it received countless attacks on that approach during the years; although most of those attacks were due to the inconsistent function naming.
- markbnj 10y agoThis is literally one of the funniest things I've heard about in months. Look for my new python library isDict, coming soon.
- qaq 10y agoIt's up to you how to go about it on server side you for example can go with express or hapi (minimal external dependencies).
- overgard 10y agoHere's the funny thing that gets forgotten: in a lot of commercial software, 3rd party dependencies need to go through legal to get properly vetted and attributed and so on. This also usually requires an engineer (to be able to answer things like if it's dynamically linked or not, etc.). As staid and corporate as it might sound initially, it's a very smart thing to do. One screw-up with licenses could be catastrophic. Are you all really checking that carefully? I can't even imagine how any sort of proper legal checks could be done with a trillion micro libraries.
- iamleppert 10y agoI couldn't agree more. I've been using the new ES6 style module syntax for a few days now because a co-worker forced me to, so he would use my library. I'm not convinced its worth it compared to the simplicity of commonjs and module.exports. You have to pull in babel, which has over 40k files to do all this. Why are people destroying the beautiful simplicity that is javascript? Can those people please go back to java?
- deleted 10y ago[deleted]
- omaranto 10y agoThis culture of tiny one-function modules sounds like Joe Armtrong's proposal about the "Key-Value database of all functions". http://erlang.org/pipermail/erlang-questions/2011-May/058768.html http://erlang.org/pipermail/erlang-questions/2011-May/058768...
- smegel 10y ago> What concerns me here is that so many packages took on a dependency for a simple left padding string function, rather than taking 2 minutes to write such a basic function themselves. Wait -- code reuse is bad now??
- apalmer 10y agoYES... it is... its a trade off... code reuse has a upside and a downside...
- partycoder 10y agonode is can be a good idea. But people don't take JavaScript programming seriously. Most libraries objectively suck. Google, authors of V8 and #1 subject matter experts on V8, have published coding standard. Does someone use it in the node community? No. Everyone loves "standard", a lousy standard that allows everyone put a badge on their github page while still having a code base full of vomit. JSDoc. A great solution for documentation. You would expect major libraries to adopt it, or a similar thing. But again, no. Major libraries such as busboy do not use them. The documentation resembles a napkin. Then everything else: input validation, error handling, consistency... etc. Take "request" for instance, one of the most widely used libraries. The state machine it implements is inconsistent. You abort a request and get a timeout, you can abort a request without starting it and get an exception. Issues that will drive you insane while debugging. Express, one of the most widely used web frameworks on node.js. Do this on a route: setTimeout(function(){ throw new Error(); });. Great, now you have broken out of the error handling context. Great job. Node libraries suck all across the board. It's the PHP of the 21st century. There are exceptions, like: lodash, bluebird, and others.
- namuol 10y agoFormula for a top HN article: 1. Make an observation about a popular thing. 2. Blindly extrapolate. 3. Make one or more broad, controversial statements. 4. (Optional) Nuance.
- dustingetz 10y agoIf the code is open source, what difference does it make if the code is in my module or someone else's?
- thrillgore 10y agoI started out really thinking Kik was wrong to sue this guy but like with all things, the longer this goes on the less sympathetic I grow. Write your own goddamn utility classes, people. Or learn how to suspend package releases, include them in your projects, and smoke test your releases.
- EdiX 10y agoThese issues are ortogonal.
- joeandaverde 10y agoI completely agree with the author. The loudest people in the Node community have been evangelizing this practice for as long as I can remember. This shouldn't come as a surprise. The argument, "If I didn't write it I don't have to think about it" is ludicrous. I just have to point at the left-pad incident disprove the premise of this argument. The analogy of building things with a bunch of npm lego blocks is laughable. Those responsible for advocating the use of trivial functions by acquiring module dependencies are leading the masses astray. "But, If I find that there's a bug in a module I can AUTOMATICALLY fix it everywhere!" No. You still need to assess how the change to that module impacts any code that depends on it. Just by updating a module and posting a "minor" bug fix can lead to other bugs that RELIED on the behavior as it was originally written. It's simple, write your own trivial functions. Test them. Maintain them. P.S. Another module that can easily be in-lined to every code base you own. (3 million downloads this week). https://www.npmjs.com/package/escape-string-regexp https://www.npmjs.com/package/escape-string-regexp
- iopq 10y agoJust because it's a one-liner doesn't mean that this code is not complicated. If you forgot something in this one-liner, you could have something that's not working in every case.
- mr_justin 10y agoIt's not that anyone has forgotten, it's that a lot of people never learned how to in the first place. Every programmer community is riddled with these problems but the NPM world seems to be the worst. The ruby gem "american_date" annoys me to no end. It's just a highly-specific implementation of Time#strptime. Gah
- erikpukinskis 10y agoI think this is the fundamental thing people don't understand about NPM and JavaScript, and the web in general: Nothing is included. And that's a feature. The web is not trying to be the kitchen sink. That's iOS. They provide high level APIs for everything. And as a result, the platform is architecturally only as vibrant as Apple can make it. Now maybe you're happy with Apple, maybe you love the iOS APIs. But if you don't, you're stuck. There's not a rich bed of alternative view layers that you can draw from to build your own vision of how software should work. Node and the web browser strive to be lowest common denominators. They provide just the very basics: a document format, a very simple programming language, and an http server. The rest is up to you. That's pretty scary, and so the JavaScript world has dabbled in frameworks. In the end all-inclusive frameworks are antithetical to the spirit I'm talking about, so things trend towards small modules that do one thing pretty well. People go overboard sometimes. I would argue left-pad should just be a copy-pasted snippet rather than module. But that's not a sickness in the community, it's just developers feeling out how far to go. If you like every application to look the same, and you don't mind being chained to enormous and restrictive standard libraries and frameworks, then you will hate JavaScript. If you like writing software from scratch, forming opinions about all of the different parts of the system, and allowing each application to be built out of different parts, out of the right parts, then you should give JavaScript a closer look.
- MichaelGG 10y agoThis is flawed. Basic things like checking if something is an array or a integer should be part of a stdlib. No one is saying whole frameworks need to be included, just basic functions, partially because JS isn't sane in the first place. Nothing in C's stdlib forces apps to look the same.
- kbart 10y agoYou are talking about extremes here, but there are nice place somewhere in the middle, where open source libraries/modules exist to help you solving complex problems and you are free to write whatever you want.
- sorpaas 10y agoIMHO, this is all due to lack of a standard library in the Javascript world.
- tobltobs 10y agoNeed more of this WTF stuff? Have a look at the docker registry/repository/hub and those pearls of wisdom of the new DevOps guilde.
- noiv 10y agoThe Python community has a proper response: https://pypi.python.org/pypi/left-pad/ https://pypi.python.org/pypi/left-pad/ /s
- sametmax 10y agoThen you can do variants. A Java left pad implementing a Padder class instanciated by a PadderFactory that you can get by a PadderInjector from a PadderRegistry all that accepting an AbstractPaddingString. Then one in Ruby where you monkey patch the string to that it pads, then add an AUTO_PAD settings set to True by default and a fluent API to chain padding. Then one version PHP version containing pad_string, then real_pad_string that deals with unicode, then real_pad_string_i_swear_this_time that that call str() on parameters automatically. Then a Haskell one with a monad and a trampolin and some |=> giberrish to mix it all. Then a Go one that creates a string padding microservice. With a docker file, just in case. And the last trend in Python, an aio_string_pad which gives you an asyncronous padding coroutine, but under the wood calling run_in_executor, and optionally auto start an event loop. This is 99 bottles of beer all over again.
- frozenport 10y agoI don't see nobody criticizing 'std::min()'. Perhaps what we really need is a 'std' for js?
- lorenzhs 10y ago`std::min` isn't a library of its own, it's a function in the `<algorithms>` header of the Standard Template Library. The STL also encompasses a wide range of other things. There are some efforts to provide "the missing standard library" for JS, e.g. lodash.
- frozenport 10y agoThen the problem isn't that people don't know how to program, rather that js is missing standard functions. In the C++ world there is a large push to avoid rolling your own things, indeed even simple constructs like `for` loops are starting to be frowned upon.
- gdulli 10y agoThere's so much wrong here, it can't even all be seen at once. The part we can perceive is only a projection from a higher dimension into our three-dimensional space.
- kevin_thibedeau 10y agoThe insanity is that JavaScript doesn't have a standard string library. More a case of forgetting how to design a programming language than how to program.
- nas 10y agoContrast with the Scheme Request for Implementation (SRFI) process, see <http://srfi.schemers.org/> http://srfi.schemers.org/>.
- alistproducer2 10y agoOn the one hand, I ,love how the JS community is constantly coming up with new [versions of old] things. Even though most of it is creative waste, it's still creative and out of that churn we get some pretty awesome apps and tools. On the other hand, there's a lot of bad practices disguised as "simple" and "efficient." Using NPM for one line functions is a great example of this.
- dschiptsov 10y agoI remember how I have been downvoted to oblivion for comparing JavaScript madness with Java EE "packer's" paradise years ago. The Programmer's Stone first essay is actual as it never been before. Actually, it is a common pattern. When some activity becomes popular due to very low barrier to enter it will end up in a such kind of mess. It seems like nowadays everyone is either a programmer or a scientist and researcher. This is the quality of their software and research. There has been a reason why good schools taught principles (algorithms and data structures) not particulars (objects and classes). But since MIT and Berkeley dropped Scheme-based courses in favor of "pragmatic" Python (thank god not JavaScript) based courses we are heading to a disaster. Java madness taught us nothing. History is full of examples where assault by mediocrity ruined the whole branches of philosophy, arts and crafts. Instead we have fastfood, mass media, social media and now this mass coding, which combines worst from mass and social. Just try to compare things like Smalltalk or Plan9 or R4RS Scheme or Zeta LISP of Symbolics or with this stuff.
- zalzal 10y agoSeparate from the discussion of whether super small modules and hundreds or thousands of deps are a good idea, is the point of operational stability. Putting on your devops hat, whatever your dependencies, from a reliability and reproducibility point of view, you should control your reliance on unexpected decisions of npm or third-party developers. A lot of the panic with npm issues comes from people blindly using the npm registry and then seeing breakages, with no safety net. I hate to say "I told you so" but this is an issue we worried about a lot when considering Node productionization last year: https://medium.com/@ojoshe/fast-reproducible-node-builds-c02bca056739 https://medium.com/@ojoshe/fast-reproducible-node-builds-c02...
- Artoemius 10y agoIt's not that we have forgotten how to program. It's that everybody and their dog is now a programmer. Professional racers don't need an automatic transmission, but it's quite helpful for an unprofessional driver.
- spotman 10y agoEvery single dependency you import should make you nervous. You would look at it like hiring someone. You are letting go of some responsibility. You are letting go of some control. The end result might be better than you could do in-house, but it might not. But you are already hoping that it's better, and giving up control. Save these for the things you can not do in house, like NaCL. Don't write that yourself. But string padding, sorry. Any developer worth their salt would laugh at adding a dependency for this. It's irresponsible, and comes across as amateur hour. This is a simple case of optimizing for responsibility. The inexperienced programmer does not know how to do this, because they have not spent enough time being responsible, and having to deal with the fallout of managing responsibility poorly. An experienced programmer carefully manages responsibility. A simple function, that is easy to understand, easy to test, and easy to reason about, is something that makes more sense to either pull all the way into your codebase, or write yourself. Years of doing this means that managing dependencies should never be just slap it into your packaging system and start using the function. If you are on the line for making the wheels turn for a large scale platform that is directly connected to a monetary transaction of some nature, you will quickly find yourself preferring to remain responsible for everything that you possibly can control. There is certainly enough that you can't control to keep you on your toes.
- robodale 10y agoI'm content and happy not knowing what the fuck this is all about. Pad left? Are you kidding me? If your tower og babel fell because of your reliance on some script kiddie's toy project, I am happy and content knowing you get what you deserve. Law of leaky abstractions, motherfucker.
- robodale 10y agoI'm content and happy not knowing what the fuck this is all about. Pad left? Are you kidding me? If your tower og babel fell because of your reliance on some script kiddie's toy project, I am happy and content knowing you get what you deserve. Law of leaky abstractions, motherfucker. Spolsky...do you read it?
- rycfan 10y agoIf I engage in as much hyperbole as the author, where does "write it yourself" stop? If I'm working on a team of two, should we each write our own left-pad? How about a team of three? Four? Five? Fifty? At a certain point, it makes sense for that to be written once for the project. We spent 30 years in software engineering trying to figure out how to get code re-use, and now that's it common and widespread, we want to go back to NIH?
- marssaxman 10y agoI think about this every time I write a UTF-8 decoder. It's a task which is simple enough that I can bang it out from scratch about as fast as I can find a library that does it, so I can't really stomach adding a full-blown dependency to deal with it - but it's also just complex enough that I have to think about it, write some tests to make sure I didn't forget something, and wonder whether this implementation is any different from the last one I wrote.
- kbart 10y agoI have 'tools' repository on my local gitolite server just for that. Saved a lot of time already.
- sealjam 10y agoI pretty much came to the comments to post something similar. I'm sure there was a long comment thread here on HN discussing the perils of NIH this week. This seems like the end point of the alternative.
- ankurdhama 10y agoWhat's next? A hello-world package and Node tutorial about hello world program being include this package as dependency and call the exported function.
- dc2 10y agoFor a less sensational review of this situation, NPM published a post-mortem: http://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm http://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm
- jeffdavis 10y agoJoe Armstrong had an interesting related comment here: http://erlang.org/pipermail/erlang-questions/2011-May/058768.html http://erlang.org/pipermail/erlang-questions/2011-May/058768... Maybe the unit of modularity should be a single function and we can do away with modules?
- stevewilhelm 10y ago> What concerns me here is that so many packages took on a dependency for a simple left padding string function Clearly to mitigate such a tightly coupled dependency, Left-Pad should be a micro-service. :-\
- deleted 10y ago[deleted]
- dschiptsov 10y agoThis is, finally, the "Fractal Of Bad Design" moment for JavaScript.
- unicodeveloper 10y agoLOOL..I agree with this one.
- fieryeagle 10y ago<rant> The problem here is JS developers have baked in the notion of having NPM as the alternative to Google + StackOverflow + own thoughts. It's really a no-brainer (literally) to just slap another package than to bother thinking about what a piece of code does, the edge cases and pitfalls. Move fast and break things, right? Sure there was some argument about Unix philosophy, small module doing one thing and does it very well. Did anyone bother considering the quality of most NPM packages? Quality is not reflected with passed Travis CI or extensive community testing and feedbacks. Not at all. Look at the those packages on apt-get. They are modular and robust. They do what they were supposed to do. Now take a long hard look at the state of NPM. What do we have? People clamoring for reusability and whatnots. Most of them don't even know what they're talking about, just reciting the latest hip statement from the Internet. Being mature about development means accountability for what you do, not pushing shit around that you don't even have knowledge off. As a self-proclaimed polyglot, I love JavaScript as a language but not the ecosystem. It's like watching a dog chasing its tails: - Endless loops of discussion that help stroke the egos but not improve anything else. - Craps for resume/repository padding, not for actual developers to use. - Bandwagon mentality that just pushes the latest fad along, and the herd towards the cliff. The notion that JS developers are kids playing grown-up, has been reinforced with this NPM incident. If we want to discard that notion slowly, we need to be more mature developers. It's that simple. Here's what I think we could do: - Have a clear idea on what dependency you need. Browser, IDE, terminal etc are dependencies. Basic type checking is not. - Be better craftsmen. Roll and maintain your own toolboxes. Only share a working hammer, not a broken nail or a wood chip. - Note that for each package you publish, thousands more hours would be spent on learning, adapting, using and reporting mistakes. Collectively, the current community wastes so much time with finding the right things to use. Often times, we learn much more by playing with code, even posting on StackOverflow. That's hands-on, `npm i` is not. - Own the code better. The idea that teams like Babel and React devs with all the brilliant developers choose to put their eggs in a private corp's whims is just scary. You can't hope to build robust software while playing Jenga tower.
- vu3rdd 10y agoI am posting the article "No silver bullets" again, in the wake of the npm fiasco. I think it is an essential reading for every programmer, every year! https://news.ycombinator.com/item?id=11350728 https://news.ycombinator.com/item?id=11350728
- salehd 10y agoWell it has always been like this. In early 2000s most developers I knew would simply copy-paste code from all over the Internet. Nowadays you use NPM search instead of Google search The fact is that lazy programmers are lazy. The methods change but the principle remains the same. In 90s people typed in code from magazines and books.
- grumblestumble 10y agoCouple of things: * If you're in favor of the micro-module approach, you shouldn't be relying directly on NPM, and should have something like Sinopia in place. After all, external code isn't the only thing you're vendoring, right? * Micro modules are fine - but your application code should depend on a privately published utils module whose entry point is a prebuilt distribution of all your external micro-modules exposed through a facade. Your utils module deps are all installed as dev dependencies to avoid the Fractal Nightmare. * Yay, now you have your own 'standard library' which still manages to leverage the NPM philosophy of distributed code. And if some twit decides to throw a tantrum, it will only impact future builds of your custom std lib - and you'll know about it at build time.
- losvedir 10y agoThere's nuance to the discussion that both sides are missing. People argue forcefully whether these small modules are good or bad, but I'm not seeing much evidence that they understand the other side. First: why small modules are bad. Lots of dependencies complicate your build, and you end up with the dreaded diamond dependency issue. Failures in a dependency become more likely to affect you. It gets you in the habit of using prebuilt modules even if maybe it's not quite what you need and it would have been better to write yourself. With `npm` specifically, we've seen how its mutability can break the build, though that's about `npm` and not the idea necessarily. I think most software developers' gut responses are that something is wrong and crazy in the npm ecosystem. That said, there are benefits that this blog post and others aren't mentioning, related to the javascript situation specifically. The first one is that javascript is a surprisingly difficult language to get right. Sure, the final solution is only a few lines, but which lines are hard. You have to navigate the mindfield that are is V8 in nodejs, v8 in chrome, spidermonkey, chakra, etc. I've had code work in Chrome before but blow up in IE, and it's really hard to track down and test. The comments in the blog post are illustrative: One line of code package: return toString.call(arr) == '[object Array]'; Crazy right? And my first stab probably wouldn't have been to implement it that way. Why not: (testvar.constructor === Array) that a commenter suggested, which should be faster? Well another commenter said: The constructor comparison will fail if the array comes from a different context (window). I've run into issues before with cross-browser compatibility stuff, and it's frustrating and hard to test. If there's some de facto standard package that implements it for you, hopefully the community can iron out edge cases. The other thing that people don't bring up, is that there's not much JS standard library, and in the browser context you have to send all your code to the front end. So maybe you write these 11 lines yourself, and then another package writes these 11 lines, and another... it adds up. But if everyone uses the same package, the code only gets sent once and they all share it. Lastly, people talk about how `sin` should be a part of a "trigonometry" package and not by itself. Well, again you're faced with sending a bunch of unnecessary code to the frontend. With webpack2 and tree shaking, or e.g. Google's Closure compiler, it can strip out dead code and so this issue will go away in the future, but we're not quite there yet. So package authors still bundle all these things separately. So pros and cons.
- zongitsrinzler 10y agoIt's not about programming, it's about fast progression.
- terryf 10y agoSo, apparently some guys managed to build a system where it is very easy to re-use small parts of other people's code and now the author is complaining that "too much code re-use is happening" ? I'm fairly old, so I remember the complaints a decade or two ago that people had where "We can compose hardware from IC's and you don't have to know what's going on inside and it's all standard and just works! Why can we not do that with software?!?! (of course that ended up with things like CORBA and DCOM, which was all wrong)" aaaand here we are in a situation where code re-use is actually happening on a wide scale and now you're complainig about that? 28k lines in an empty project? ha, how many lines of code does the preprocessor generate for #include <stdio.h> I haven't actually measured, but I bet it isn't that far off from 28k lines.
- omgtehlion 10y agominor nitpick: it's not 28k lines, it is 28k FILES
- kungtotte 10y agoWhich, given what I understand about most packages on npm, corresponds closely to 28k lines :P
- MattHeard 10y ago> Even if correct, is it the most optimal solution possible? "most optimal"?
- spajus 10y agoThat's what you get when you let JavaScript into the server side.
- nnq 10y ago...maybe it's time a committee of really smart people sit and sip through all the most used modules below N lines of code or smth, and just write an opensource JS-stdlib, hopefully merging in top 30% most used methods of Lodash too? Node/NPM is a great example of why too much democracy and decentralization is bad. Just gather some experts and have them centrally plan a "standard library" then impose it as "industry standard" have a recommended "no fragmentation policy" like "no forking" and "use it all or not at all", the hell with your web app's need for "performance"... even a few hundred Ks of code will not hurt anyone nowadays ff sake... I even consider PHP a "more sane" language because you at least have most of the useful utility functions in a global namespace and everyone uses them. Of course, the real ideal on this is Python's solution: a nice set of standard libraries that you know are baked in, but most of them you still import explicitly - hence it's pretty easy to write even large Python applications that have a small and comprehensible number of dependencies! (And more generally: our strike for "more efficiency" in programming is stupid imho! I'd always take a less efficient solution, even "less safe/tested", if it's more "understandable" and "explainable" and sometimes, paradoxically, making things a bit more monolithic and centrally planned makes then orders of magnitude easier to reason about for our tiny ape brains...)
- deleted 10y ago[deleted]
- Ciantic 10y agoThere is also a big programmer efficiency to be gained by having batteries included library: The new person coming to a project has learned the same batteries already, and it need not to re-learn new set of minipackages the last person working on a project has used. In fact this should be the key selling point for stdlib to JavaScript. It actually saves money from their employers if trivial functions are mostly in the same place. However pushing a stdlib is difficult there is a lot of hate for Python's "kitchen sink" library in JavaScript world which is totally misplaced. It maybe founded on fact that you should then minify the whole package to use one function in it, but this could be solved with dead code elimination (with proper type checking) in the minifier.
- 10y ago
- doctorstupid 10y agoSmart people created software that lowered the barriers of entry to making software. It was inevitable that not-so-smart people would eventually be writing software that others would build upon.
- ordbajsare 10y agoIt's js .. they never learned to program.
- StreamBright 10y agoSo funny, just few weeks back I had an argument with somebody about writing a simple functions vs. importing libs when you need less then 5% of the functionality. I am more convinced than ever that it is better off to have the least amount of external dependencies. Of course I would not want to rewrite a 2M+ LOC library with very complex code, but left pad is not one of those use cases.
- venomsnake 10y agomodule.exports = leftpad; function leftpad (str, len, ch) { str = String(str); var i = -1; if (!ch && ch !== 0) ch = ' '; len = len - str.length; while (++i < len) { str = ch + str; } return str; } Isn't that the least efficient way to do that function? Prepending a string has always been very expensive operation. Calculating needed length. Using repeat and just concatenating 2 strings would be faster.
- titzer 10y agoV8 internally uses cons-style strings for these operations, and only flattens the string when necessary for other operations.
- z3t4 10y agoThis is why one guy can now compete with say Google or Microsoft, because that guy uses code written and managed by more engineers then both Google and Microsoft have combined. Instead of paying hundreds of dollars to said companies, you can just NPM install "what you need".
- kbart 10y agoLibraries/modules should help to solve complex problems where writing your own version is not optimal. Single line functions as modules, on the other hand, won't help you compete with Google or Microsoft and result in more problems than they solve. If a simple padding or "is this int positive?" is a complex problem, well, there are different professions than programmer's..
- z3t4 10y agoThe less code you write, the less code you have to maintain. Even if it's just one less thing, it's a win. The comonJS module pattern also helps tremendously, as your requires are block/function scoped. It makes it trivial to refactor (remove/rewrite) code.
- kbart 10y agoIn a perfect world yes, but in the real world, with unreliable dependencies and their imperfect management, it doesn't come for free.
- z3t4 10y agofunction foo(arr) { var str = ""; var leftpad = require("leftpad"); for(var i=0; i<arr.length; i++) str += leftpad(arr[i]); return str; }
- sebak 10y agoThe main reason there is a fetish for these micropackages is a fetish for github stars. The formula seems to be: Overly generic + Simple + Javascript = Lots of stars. That being said, there is something to be said for using these micropackages. Left padding a string is easy, but you might just have forgotten about that one edge case where in browser X and language Y you have to do things different. It's not really the case here, but things that seem simple at first often turn out to be hard because of some edge cases. One might hope these edge cases are solved if they use a library.
- justin_vanw 10y agoForgotten? Most people who develop on Node.js never knew...
- sordina 10y agoCheck out the work on Morte for a more reasoned approach for how to take micro-modularization to it's natural (or insane) conclusion.
- serge2k 10y ago> if you cannot write a left-pad, is-positive-integer, or isArray function in 5 minutes flat (including the time you spend Googling), then you don’t actually know how to code. I'd probably get 2 of those wrong in some weird way, but I blame javascript. I mean without Google of course.
- forgotmypassw 10y agoJavaScript was a mistake.
- gladimdim 10y agoOn DigitalOcean instance I cannot even use browserify+minify+babel6 cause npm process is killed by host (it consumes > 512Mb of RAM). So I have to manually run browserify + babel then minify. Still it produces 500kb of bundle.js :D
- grillorafael 10y agoI agree that some packages might be too much but I don't think `left-pad` is one of them. I wrote my own left-pad for a project I'm working now and I had to revisit a few times for tiny problems and lack of time to write tests. I would definitely use `left-pad` module if I knew the existence at that time.
- svs 10y agoThe problem is not of small modules. The problem is lack of dependability. If the language patrons stand behind a set of modules and guarantee continuity and availability, it really doesn't matter what is in them and the world can continue regardless of how insane the module or the whims of any one author. This is not about the technical merits of having or not having a stdlib. The module in question could have been anything. Making this about is-positive-integer misses the point that this is a social/political problem not a technical one. A language ecosystem must address concerns of business continuity as first class concerns.
- ajuc 10y agoWhat's wrong with reusing small fragments of code? The usual complains about many dependencies are mostly void (it's not bloat if you only depend on single functions you actually use).
- romualdr 10y agoThe author missed the point about modularity in Javascript. Small packages done right, well tested = maintenable, reusable, stable code. The problem does NOT comes from packages. The problem comes from un-publishing public packages and centralized repository server. I have a java project with a lot of dependencies. Does it mean it's bad ? No, but if maven repos are closing tomorrow, my project will not build as well.
- HarrietJones 10y agoThis isn't forgetting to program, it's a deliberate choice as to how library code needs to be organised. We can disagree about choices made, but let's not assume other people aren't able to code as well as we think we can code. That being said, I think this is a perfect example of where a good concept (small, tightly scoped modules) is applied dogmatically at the cost of the codebase. It's the node.js equivalent of AbstractRequestFactoryFactoryFactory stuff you see in Java, and the Mock Messes you see in Ruby.
- dreta 10y agoAfter reading this, i don’t think i’m capable of ever complain about OOP again. Whenever you think you’ve seen it all, web developers always manage to come up with something worse. The only thing more depressing than this is the comment section below the article.
- spion 10y agoIts interesting how everyone used this as a chance to attack the small modules approach. This approach definitely has downsides, but the problem caused by leftPad being unpublished wasn't one of them. If jdalton declared a jihad on arrays tomorrow and decided to pull all array related functions from lodash, we would have the exact same problem. If kriskowal decided that Q must mirror built in Promise and published a version that does this tomorrow, we would again have the exact same problem. There is only one connection between this problem and the small module approach. As the size of a module decreases, the number of dependencies increases and so does the number of authors that produced your dependencies. With the number of authors increasing, the chances that some author decides to go rouge or protest for some reason also significantly increases. Therefore, its irresponsible to use this approach with a package manager that allows an old, established module with many dependents to be unpublished so easily by the original author.
- usrusr 10y agoWould people automatically update to the new versions of the libraries you mentioned? The problem with unpublishing is that it changes an existing version. If instead of depublishing a correctly versioned empty module named leftpad was pushed to npm (increment major, because a non-implementation is incompatible with an implementation), there would not be half as much pain. As long as unpublishing exists, micromodules increase the "attack surface" to this specific method of changing the contents of a specific published version.
- plugnburn 10y agoSo sad yet so true. We haven't. React developers probably have.
- jammycakes 10y agoHere's a quick rule of thumb. If it's the kind of function you would ask a candidate to write at the start of a job interview, you shouldn't be importing a separate module to do it.
- insin 10y agoShould you rewrite it for every project you need it in, or copy and paste from the last one? Should tests also be rewritten or copied each time you do this? What do you do when you've used it in multiple projects and you find a bug or performance issue?
- chukye 10y agoMan, I have to quote: `In my opinion, if you cannot write a left-pad, is-positive-integer, or isArray function in 5 minutes flat (including the time you spend Googling), then you don’t actually know how to code.` You would be surprised of how many developer these days have 'afraid' to write such functions, or how lazy they are, they found this thing and just add to a project, then push to some google list and the project got a lot of followers, and in the next day the project has changed about 90%. I saw this happen over and over again in this ecosystem, this is insane dude. A lesson I learn is: you _need_ to read every module source code before add to any project, the NPM ecosystem has so many "shits" out there. You cannot trust in any npm module, recently I tried to trust in a module that has more than 5k stars, but I found a such ugly bug on that, that I feel my soul die, and I swear I hear the angels cry, thats not how open source supposed to be. These days, seems that people dont care about the 'bug free' as long as it work a half way.
- deleted 10y ago[deleted]
- cel1ne 10y agoI know the discussion revolves around the amount of dependencies, but I want to add a comment about semver, which has a part in this mess: In my opinion it will not be done right in 80% of cases. Every breaking change requires updating the major versions, but developer are hesitating to go from 1.0.0 to 6.0.0 in a month. The way out is staying in the 0.x range therefore abandoning semver alltogether. A nice write up about how packages are not following semver in java-land: http://avandeursen.com/2014/10/09/semantic-versioning-in-maven-central-breaking-changes/ http://avandeursen.com/2014/10/09/semantic-versioning-in-mav...
- blablabla123 10y agoI guess this is the way one is supposed to use node, preventing one to write non-DRY code. (Golang takes the exact opposite approach, having it's own drawbacks of course.) However, when using React, I kind of trust that the maintainers don't include packages than require 12 star projects, and if, that they fork this stuff themselves. BTW, isn't that a Facebook project, so aren't they supposed to use a CI? ;P
- TickleSteve 10y ago"Small modules are easy to reason about" No... "appropriately sized modules are easy to reason about" In this case... "Appropriate" has gone out of the window!
- Shivetya 10y agoHell, the java programmers I work with seem to never use each others simple functions and instead recreate the will every single time. As for the issue with such a short piece of code being reused by many, why score on number of lines? If it works and is a useful function is more important to me. I am not familiar with bundling within the usage the article covers but we tend to bundle like functions together and the compiler drops unused ones
- duncanawoods 10y agoThe problem with shared hyper-modularisation is that it assumes the name of a function is unambiguous with only one valid implementation. If that were true, it should be encouraged but given it isn't, the practice will crushed by ambiguity and unintended consequences. My app might well have an is-positive-integer function but it will include a range of context dependent choices about e.g. floating point, infinities, zero, null, "9", "9 ", "09", boxed numbers, string representations exceeding js max int, etc. etc.
- joshstrange 10y agoI can't take this author seriously at all, one of his most egregious cases is the is-positive-integer library which until today had around 30 downloads in the last month.... No one was really using this and furthermore of course you can find bad/iffy code on NPM for the same reason you can find bad/iffy code on github. ANYONE can publish code. I could write a similar module for any other library, publish it to their repo, then scream LOOK! python is stupid and python devs are stupid. I firmly believe that building on what has already been done allows for much safer code written at a quicker pace. Why should we constantly repeat ourselves? Also by using npm modules we can abstract logic and prevent someone on the team from going in and modifying it for their own use. It is a documented/constant function that we can use knowing exactly what it does. Is it a better world where everyone just copies code out other's repos and then has to include the licence/docs/tests along with it? It's much easier to just pull in the repo which contains everything and make it trivial to see where a function came from. People are blowing this whole thing way out of proportion just because it makes a good headline "11 lines of code broke node"... You can all try to shame people who build on what's come before and chant "Not invented here" but I'll opt to build on what is proven to work instead of rewriting everything. At the end of the day that's what ships products.
- rsp1984 10y agoDependencies are one side of the problem. Unavailability of binaries and dogmatic use of dynamic linkage are the other side. When I installed a simple lines-of-code counting tool through Macports the other day I accidentally opened the door to dependency hell as gigabytes of not even remotely related stuff started to build [1]. Without a doubt something is going very wrong with Free Software and package managers. On the other hand, never look a gift horse in the mouth so I may not even be the right guy to complain here. [1] http://pastebin.com/cAZgbaFN http://pastebin.com/cAZgbaFN
- esailija 10y agoNo it's because they don't do the same thing at all. This comparison shows you clearly don't understand the first thing about promises.
- nailer 10y agoIf you're new to technical discussions, people normally provide supporting arguments. Both of those handle sequences of tasks that need to complete in order. "No you don't understand" without any further info is not a response.
- esailija 10y agoI think if you don't even know the basics of something, you should go learn them before discussing it.
- dang 10y agoThis comment as well as https://news.ycombinator.com/item?id=11354704 https://news.ycombinator.com/item?id=11354704 break the HN guidelines. Please don't post uncivil comments regardless of how wrong or ignorant someone seems. We detached this subthread from https://news.ycombinator.com/item?id=11351657 https://news.ycombinator.com/item?id=11351657 and marked it off-topic.
- grav 10y agoIsn't the problem that there is a lack of a good standard library in Javascript?
- kerkeslager 10y agoA lot of the discussion here really isn't talking about the problem at hand. From the perspective of Babelify users, a major bug was introduced into software they depended on. I don't know how much money in developer time was lost due to this but it would almost certainly be in the thousands of dollars. And it could have been a lot worse. It could have been something more complicated than left-pad. The author could have introduced a vulnerability or outright malicious code, or been hacked and done the same, and millions of people would have downloaded it and run it. Arguably, small modules are good if you control them. Maybe they are more composable, maybe they enable better testing, maybe they encourage code reuse. I am not going to argue for our against small modules. But none of the positives of small modules matter if an unknown developer who you have no reason to trust can change or unpublish the module out from under you. It's irresponsible as developers to risk our employers' and clients' businesses in this way for a function we could write in five minutes.
- progrocks9 10y agoI just removed the tilde and caret of all my dependencies (in my package.json) and maybe that's the way to go. Seal a local version of your packages and don't update unless is completely needed. But I'm still worried about the fragility of the package environment.
- polynomial 10y agoWhat actually happens when you try to update a required package, but it is gone from upstream? Is there no way to keep the existing package you already have?
- shitgoose 10y agohere is one of the comments to original post: "Immutability at the centralized authority level and more decentralization of package distribution is the solution, not 'write more functions yourself'." what the fuck does that mean?? they just don't give up, do they... Fucking retards.
- AdamN 10y agoOne should think of these requires as like .h files and the underlying code as something like a .c file. They're public definitions with potentially changing underlying code. It's good to have small packages. Don't forget that the underlying ECMA script is changing so the implementation of these 'libraries' are (or will be) different over time from what they used to be. If somebody finds a faster way to do the method, then it will be done. Finally, anybody who has used js in the real world understands how many corner cases there are and how difficult it is to make durable methods (i.e. how to know if an array is empty - which requires like 4 different conditions).
- jmount 10y agoFor more fun, my commentary on leftpad code: http://www.win-vector.com/blog/2016/03/more-on-npm-leftpad/ http://www.win-vector.com/blog/2016/03/more-on-npm-leftpad/
- pklausler 10y agoInsight from this story: If it is important that a thing be done correctly, it should not be made so easy to do that it will end up being done by people who shouldn't be allowed to do it. I may have just invented a rule for choosing programming language and systems there.
- hughw 10y agoOf course I would never create a dependency on a small module like left-pad. I would simply copy the function wholesale into the body of my code!
- raz32dust 10y agoThe author brings up an excellent point, but I disagree with the solution. We should of course reuse existing, well-tested code if it available, even for simple things like left-padding. The real issue here is that there is a module for left-pad alone. If it were something like StringUtils module with a bunch of commonly used string functionality, it would have been great. What is it about the node community that triggered this misunderstanding of package management and code reuse?
- niklabh 10y agonpm had the solution one year ago (namespacing) https://docs.npmjs.com/getting-started/scoped-packages https://docs.npmjs.com/getting-started/scoped-packages if only developer can embrace the "change"
- plugnburn 10y agoHave to put a little clarity over my "so sad yet so true". When the developers of such a serious library as React start to depend on a third-party one-function module made by some Dick-from-a-mountain (a russian idiom that means a random person who did nothing significant but tries to show out in all possible means), that means React developers are even more to blame than that Dick-from-a-mountain himself. If you make any really popular piece of software, you absolutely must have a failover plan. No excuses for not having it. But what's even sadder is that this issue had spawned a new wave of pseudo-elitist attacks on the entire JS dev community. Calm down guys, things like that could have happened for any language that has a widely-used centralized package system (Perl's CPAN, Python's pip, Ruby's gems etc). Let me repeat that again: languages don't make software bad, people do. Just don't let such Dicks-from-a-mountain rule over your own modules with elementary stuff like leftpad, and you'll be safe.
- plugnburn 10y agoBy the way, ES6 syntax (works in modern foxes and chromes): leftpad = (str, len, pd = ' ') => Array(len > str.length ? 1+len-str.length : 0).join(pd) + str WTF are you talking about? Making this into a module?!
- gitaarik 10y agoWhy was it removed anyway? I agree that the ability to unpublish something is the real problem, but I wonder why the author actually unpublished it. I wonder if the author knew about all the projects that depend(ed) on it. Maybe he/she actually did it as an evil experiment, though a very interesting and eye-opening experiment. Does anyone know?
- brohee 10y agohttps://medium.com/@azerbike/i-ve-just-liberated-my-modules-9045c06be67c#.g250yhruf https://medium.com/@azerbike/i-ve-just-liberated-my-modules-... discussed here in this thread : https://news.ycombinator.com/item?id=11340510 https://news.ycombinator.com/item?id=11340510
- collinmanderson 10y agoI'm generally not a big fan of IPFS, but IPFS seems like the perfect solution to this problem.
- ZeWaren 10y agoRegardless of whether micro-modules are good or bad, I think that if you are the owner/manager of a project, you should be able, given its full flat list of dependencies, to explain why each one of them is useful for you. Every project I've seen that uses npm always required 100s or 1000s of dependencies. If building or running your project requires something and you can't explain why, I think there's a problem.
- thkim 10y agoThe core issue here is that there is no included standard package in Javascript. It happened because Javascript did not have authoritative implementation when it first began. Next ECMA should require to pack some batteries in to avoid this micro-module hell.
- jasonbelmonti 10y agoClearly this is insane - but what the solution? Part of the problem, in my opinion, is that packages are not subject to any review process. These dependency chains get out of hand because they are rarely top-of-mind.
- jwongbeee 10y agoLook at these left pads... https://github.com/search?utf8=%E2%9C%93&q=left+pad https://github.com/search?utf8=%E2%9C%93&q=left+pad https://github.com/nameoverflow/left-pads https://github.com/nameoverflow/left-pads