Hacker News new | comments | show | ask | jobs | submit login

Personally i'm going to use an installable module for something even that small, because i can, and it works.

The benefits from an install registry don't go away just because the module is very tiny...

Why would i spend my time re-inventing the wheel for every little thing i do? And if i'm not reinventing, then i'd be copy/pasting which is much worse. At best that's a waste of time and effort to properly document the source, and at worst it's stealing or license violations.

I don't care if a module is a single line, if it does what i need it to and is well tested, then i'll use it. That might seem silly, but the fact is that it's pretty much no overhead, and no software is immune from bugs (even a 16 line function), so updates might be useful in the future.

Yeah, there is a chance that stuff like this can happen, but within an hour there were several alternatives to solve issues with installs, i'd say the system is working pretty well. Plus with proper software development techniques (like vendoring your dependencies) this wouldn't even be a problem at all.

The overhead is in your management of your dependencies. The size of the module isn't the problem, it's the fact that you end up using so many of them (especially recursively).

Consider this specific case. This author moved all their modules from one hosted location to another. Now, if you want to use these modules from that author, you need to update the scripts and configs that install them (some package.json files in this case). In a better world, like the C or Python world, you might need to update one or two urls which point to a couple of this author's popular libraries (maybe one you use directly, and one used by one of your handful of direct dependencies).

In this crazy npm world, this author has 272 modules. Maybe 20 are in widespread use ... it's already a lot of work to figure that out. Maybe you use a couple directly, and your dependencies have private recursive sub-dependencies on additional copies or versions of these or other of this author's modules! Maybe you have to cut your own versions of some of your dependencies just to change their package.json to refer to the new URLs! Anyway, you probably have to sift through hundreds of your dependencies and sub-dependencies to see if any of them are included in these 272 moved modules.

I've seen npm dependency trees with over 2000 modules (not all unique of course). That's totally unmanageable. I think that's why privately versioned sub-dependencies is a big feature in nodejs: so you can try to ignore the problem of an unmanageable dependency tree. But if you need to make reliable software, at some point you need to manage your dependencies.

I agree that NPM needs to push namespacing much harder, as that would make the whole process much easier.

Also a "provides" field could go a long way into stopping issues like this. Allow packages to say that they provide a package in them that is compatible with another in these version ranges.

That would let "API compatible" packages be dropped in to replace even deeply nested packages easily, and would allow easy "bundling" in big libraries while still allowing easy creation and access to "micro libs".

I really believe that composing tons of small libraries is the way to go, but there needs to be better tooling to make it work. In my (admittedly not extremely expirenced) opinion, bundling many small libs into one big package to make it manageable is a symptom of a problem, not its resolution.

This will become easier with rollup, webpack@2, and so on, which can effectively reduce the penalty of including large modules like lodash by tree-shaking out all of the parts you don't use. I would expect many more utility libraries to then be aggregated into a single package/repo and for users to simply pick and choose functions at will.

By this logic, every Stack Overflow snippet should be a module. I'm almost hesitant to suggest this since many people who read this will be capable of building such a thing.

I'm not saying that everything should be a module, but that well designed, well tested bits of code should be modules.

These 17 lines had 100% test coverage and were used by a stupidly large amount of people (read: battle tested), why not use it?

As is pointed out elsewhere in this thread, echo.c is roughly the same size, does that mean it's not a worthy program?

"echo" is not versioned and delivered on its own. It's part of gnu coreutils (which contains ~ 100 utilities), or part of various BSD core distributions (more than 100 utilities, plus the kernel and libc), and also built-in to shells.

IMO that doesn't change anything.

The fact that in JS land it would be it's a standalone module means you get more choice in what you need (no need to pull down 100 programs if you only need 1 or 2).

You have the same amount of choice. There's no reason that you have to use the other hundred pieces of the package. In the Unix world, there's nothing precluding you from deciding to use the FreeBSD version of tar but keeping the rest of the GNU utilities there.

I guess it's a philosophical difference.

But to be fair this would have the same outcome if left-pad were part of a library that included another 50+ libs (that he also wrote and published, and subsequently un-published today).

More choice, but now you need 50 different modules from 50 different authors to duplicate what would be in one good standard library, any of which could have bugs or be pulled out from under you for a multitude of reasons that are beyond your control.

Choice can be a bad thing too - when there are 10 different modules for doing a moderately complex thing, you have to figure out which one is best for your project, and whether it's still actively maintained, bugs are fixed, how do they feel about making breaking changes, etc.

>now you need 50 different modules from 50 different authors

Not necessarily, take a look at lodash and friends. There is nothing stopping bundling of tiny modules into big "libraries" to be used.

As for the rest, you need to do that validation anyway. But if it were bundled in a large library there is MUCH more code that you need to review.

with something like the module "left-pad", it's a no brainer to use the library. I know that it's under an EXTREMELY open license, the code is really small, and by vendoring your dependencies (you are vendoring your dependencies right?) this whole issue would have been a 5-10 minute fix that only needed to be done when you want to upgrade your dependencies next time.

But also, if you're shipping things to users browsers, please cut out all the stuff you don't use. I don't want to download 100 extra module's worth of JS code because it was bundled.

Why not just put it into the core? Why should it even be a module at this point?

Because in JavaScript there are many different implementations of engines, and they run on all kinds of stuff. Adding something to the standard is not a small task, and it means that it's now extra code that needs to be installed on practically every single PC.

And that doesn't remove the need for a library like this (or your own implementation) for a long time because you can't rely on a brand new release to be available for everyone.

Realistically 17 lines of code is total overkill for this function. In many cases you could achieve the same thing more efficiently in a single line.

Feel free to show a smaller implementation that's more efficient.

I've seen several "one liners" in this thread already, and most of them either blow up when something that's not a string is passed in (regardless of how you view strict typing, js doesn't have it and this shouldn't happen), or are extremely slow comparatively (most of them creating and destroying an array every time they are called).

Plus this has 100% test coverage (even as trivial as it is, it still counts), and is "battle tested" (something like 2.5 million installs per month counts for something).

Sorry, but i'll stick to left-pad vs 20-seconds of thought one-liner.

> Feel free to show a smaller implementation that's more efficient.

How's this:

  function leftpad (str, len, ch) {
    ch = (len -= str.length) <= 0 ? '' : !ch && ch !== 0 ? ' ' : String(ch);

    while (--len > 0) ch += ch[0];
    return ch + String(str);
No local variables, less manipulation of the input string, the string grows at the tail which is more efficient, and the code is much shorter.

(With a bit of work you can use the longer ch string that is built to reduce the number of string appends even more by appending multiple characters at once. Although probably not worth it for this function.)

No offense, but that code is much more difficult to understand. If your goal is to minimize the amount of lines, then you succeeded. If the goal is to produce both correct and readable code, then there's room for improvement.

> No offense, but that code is much more difficult to understand.

I strongly disagree. My code has no magic initializers (the -1 in the original) and a simple linear code path, with no branching. It's very easy to read and understand.

The ternary operator at the top is simply read from left to right, it's not complicated.

> If your goal is to minimize the amount of lines, then you succeeded.

My goal was to maximize efficiency. Often that means less lines, but that was not the overt goal. And in fact this version runs faster, and uses less memory.

> If the goal is to produce both correct and readable code, then there's room for improvement.

You think so?

Then now it's your turn - rewrite this (or the original) to make it as readable as possible. I think you will find that a: mine is more readable than the original, and b: you won't be able to (need to) change much except to lift the len initializer out of the ternary operator in the first line onto its own line.

If you are talking about a module that everyone just includes and expects to work, then I'd imagine the goal would be a combination of correct and efficient, not readable.

I wasn't planning on passing a non-string to my function. The type-checking only needs to happen because this is a needlessly generic function

Okay, but then when you pass a string that's just `12` in and get `16` instead of ` 12` don't blame javascript...

I didn't intend to, although since I was going to prepend a string to the start that would be a rather surprising result

Re-inventing the wheel in 17 lines of code is called programming.

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