Comment by bluejekyll
11 years ago
Perhaps another reason for this is that Javascript is inherently unsafe. By relying on these small rigorously tested libraries they are avoiding the need to test their own code, and thus avoiding basic null check or conversion errors.
Other languages handle this with compilers, may be strongly typed, and/or have features that don't allow nulls. Javascript doesn't exactly have that luxury. So maybe it makes sense in Javascript, where it wouldn't in other languages (though one could argue this is a flaw in the language design).
edit: to be clear I'm not really defending the practice, but trying to give a little perspective.
> By relying on these small rigorously tested libraries they are avoiding the need to test their own code, and thus avoiding basic null check or conversion errors.
In practice, many, if not most, of these one-line modules don't even work correctly, and it is difficult to get people to care to collaborate on fixing them instead of just replacing them with a new one-line module that works slightly better as the concept of complex collaboration to perfect one line of code is so foreign to a generation of developers who would rather just throw code to the world and never look back (an issue made all the worse as tiny bugs in these one-liners can almost seem dangerous to fix when you aren't really sure how they are being used: maybe it actually is better to not fix anything and just have people rely on the replacement better module :/).
Odd, the ones I use all have tests, thousands of downloads, and active bug trackers. If I reinvented the wheel, or copy pasted, I wouldn't get those things.
Doing a for loop is not equal to re-inventing the wheel.
Words and phrases have lost their meaning nowadays.
By the JS community's standards if I wanted code to capitalize the 3rd or sometimes 4th letters of a string, they would be 2 different npm modules.
Maybe they didn't forget how to program, as the article implies; maybe they never knew how to program in the first place.
11 replies →
The OP's example ( is-positive-integer) has tests, and is only three lines long, and is on major release version 3.X, because despite all that, it had serious problems in versions 1 and 2.
1 reply →
Case in point: the left-pad package has quadratic complexity.
Depends on the JS implementation in question. And I think node uses one that optimizes string concatenation, possibly making that the fastest way to do it.
2 replies →
The equivalent in C would then be replacing
#include <math.h> and "-lm"
with
#include <sin.h> #include <cos.h> #include <tan.h> #include <sinh.h> …
and "-lsin -lcos -ltan -lsinh …"
Which is nuts no matter what language you are coding in.
The difference with C is that with a good linker, functions you don't call are removed from the resulting binary (or are maybe not even in the binary if you are dynamically linking to the c runtime).
With javascript however, if you import a hypothetical "math.js" instead of just "sin.js", "cos.js" or "tan.js", then you'll need to download and evaluate a whole bunch of javascript that you might not need.
I'm not defending javascript, because I dislike it and avoid it where possible, but I can understand some of the reasons why short, specific modules came about.
Webpack 2 (probably the closest thing to a JS linker) can do that same tree shaking.
what you describe is the "-flto" option in GCC and I believe the equivalent in JS is donr by Google Closure compiler.
5 replies →
> #include <sin.h> #include <cos.h> #include <tan.h> #include <sinh.h>
I've written worse - at least those cover multiple variations each (or overloads in C++ for float/double/std::complex?/...)
While I'm not a fan of the enforced java route of 1 file = 1 class, I do trend towards 1 file ~ 1 (main, public) thing - which might be a single function with no overloads. #include <string_left_pad.h>? Better than #include <everything.h>, which I see far too often...
I don't have to figure out which grouping of things my coworkers decided to throw something into if I can just #include by name - whereas aggregation headers more often than not will trigger a full project file-system search.
Unnecessary #include s don't accumulate nearly so much when you don't have to audit 100 functions to see if any of them use features from said header.
I don't trigger a rebuild of everything when the only things that #include stuff actually need it.
Lots of benefits!
> and "-lsin -lcos -ltan -lsinh …"
Or sin.o, cos.o, tan.o, sinh.o... which suddenly sounds a lot more reasonable. I wouldn't bat an eye at string_left_pad.o either.
Sure, I want to use tools to simplify the use of those micro-modules by aggregating them into libraries for convenience. But that's not a knock against micro-modules - just their packaging and tooling. Rewind time back far enough and I would've been manually specifying .o files on the command line and kvetching too...
Java doesn't enforce 1 file = 1 class but rather 1 file = 1 public class, which is exactly what you asked for. You can put as many private classes in the file as you want.
2 replies →
So have libmath depend on libsin, libcos, libtan and libsinh. People who want the kitchen-sink version can get it. People who want just one specific submodule can depend on that. What's not to like?
Having a full set of math functions isn't kitchen sink, it's the right level of granularity for a module. If I want math functions I really want them to all be written by the same author and kept in lock-step as a unit.
Why don't you want the whole module? Because it's bloat? Surely it's far less bloat than one submodule per function?
7 replies →
There's a cognitive load to every additional thing you need to know to use a module. At a certain point, added flexibility becomes more trouble than it's worth.
1 reply →
What's not to like? The fact that every one of those dependencies is an attack vector when one of those package's maintainers gets compromised / project hijacked / bought off by some black hat operator.
It's easier to keep an eye on a small number of trusted parties than 200 random strangers.
You thought this SNAFU was bad...
2 replies →
> What's not to like?
That depends; in the case of mathematics libraries they have to be bundled together because of functional dependencies. It's either that or ignoring DRY principles -- which if you do that, you're ignoring the entire point of what breaking things into submodules is intended to do.
1 reply →
Oh, but javascript is dynamically typed, so it doesn't matter if your sin-module works with a different kind of arbitrary-precision decimal number module than your geolocation module, your cosine module or your openg-draw-triangle or opengl-draw-circle modules... /sarcasm
It's not sarcasm if it's true!
1 reply →
You can get approximate feeling if you get rid of a library and don't use -lm but instead unpack it to separate .o files and link against each.
> basic null check
What's funny to me is that leftpad(null, 6, ' ') outputs " null".
Am I right that len(" null") here is 5, so it's working incorreclly?
I think the joke here is that javascript has a long history of thinking that this:
is the same as this:
...Which it isn't.
Thought it was a typo on my part... but HN seems to be trimming running spaces.
3 replies →
I think it's a very valid (and concerning) point. JavaScript is made in way that one fears to implement isPositive or isArray.