43 ms·
Holy moly-- is-positive-integer/index.js: var passAll = require('101/pass-all') var isPositive = require('is-positive') var isInteger = require('is-integ
by runin2k1 11y ago
Holy 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 11y 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 11y 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 11y 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 11y agoDon't know. If that approach works reliably, I'd see some value in it. Maybe this does not need any more code if you do it that way. If it does not work reliably, than you are absolutely right and that were useless.
- IncRnd 11y agoYea. I don't think many argue against abstracting complexity into more easily understood orthogonal modules. But some of these modules aren't abstracting complexity. They are ludicrous. They are nonsense. They are a symptom of a very real problem with how JS is programmed, how people expect to program in JS, and the difficulty people have with decomposing problems. So many people on this page have written about how these are well tested, performant, and correct modules. But, the modules aren't even correct in many cases, let alone providing incomplete coverage over edge cases or the slow performance and horrendous dependencies of many of the modules.
- 21 11y agoI think this is some sort of cargo cult UNIX minimalism - do one thing and one thing only.
- krisdol 11y agoFor some reason I misread that as "do one thing and do one thing ugly". Either way, it applies. Lodash does this (and versioning, and clean code, and tests) really well though.
- stcredzero 11y agoPhilistine! You should just be doing i things.
- tomc1985 11y agoNo, its a byproduct of programming-interview-via-GitHub-repo
- agumonkey 11y agorequire the ultimate
- magicalist 11y agoit's a module with exactly one dependent module -- by the same author. Daily WTF material but who cares beyond that?
- runin2k1 11y agoFormerly 9 dependent modules... but who cares maybe it was a homework assignment or a joke. I don't use NPM so maybe it doesn't really matter aside from the level of abstraction being implemented being relatively ridiculous. However, if my build system had to go out and grab build files for every X number of basic functions I need to use, grab Y number of dependencies for those functions, run X * Y number of tests for all those dependent packages, AND then also fell apart if someone threw a tantrum and removed any one of those packages basically shutting me down for a day... then I'd question every single thing about my decisions to use that technology. [Quick Edit] Basically I'm saying "Get off my lawn ya kids!"
- magicalist 11y ago> I don't use NPM so maybe it doesn't really matter aside from the level of abstraction being implemented being relatively ridiculous. Except, again, it's no more ridiculous than pick a random bit of code from anywhere and isn't any more emblematic than that random bit because, again, it's not used anywhere. > [Quick Edit] Basically I'm saying "Get off my lawn ya kids!" tl;dr: going for buzzfeed headlines but for comments, got it. Good job, I guess?
- runin2k1 11y agoTrying to keep the conversation light-hearted with a closing joke is more like it since everybody takes these things so seriously-- sorry I pissed in your cheerios good chap!
- ghamrick 11y ago"This isn't your average everyday darkness.... this is Advanced Darkness." - S. Squarepants
- nikic 11y agoA fun r/programming subthread about this package: https://www.reddit.com/r/programming/comments/4bjss2/an_11_line_npm_package_called_leftpad_with_only/d19vysi https://www.reddit.com/r/programming/comments/4bjss2/an_11_l... Those are just the three top-level dependencies. The package has 9 recursive dependencies. There's also a nice table explaining how a package called "is-positive" managed to reach version 3.1.0.
- kzisme 11y agoThis is just baffling...
- jperras 11y agoSimilarly, the `average` package on NPM is one that I came across: https://www.npmjs.com/package/average https://www.npmjs.com/package/average var average = require('average'); var result = average([2, 5, 0, 1, 25, 7, 3, 0, 0, 10]); console.log('The average for all the values is:', result); It's hard to not stare at that in complete disbelief; someone thought that it was worthwhile to create a package for determining the mean of an array of numbers.
- nv-vn 11y agoAnd 54 people found it a worthwhile package to install _this week alone_.
- agumonkey 11y agoLet's say these are just prescient trolls. For our sanity.
- jessaustin 11y agoThat could be one dependent module that got installed in 54 places. More likely, it was mostly various bots that install everything on some semi-regular schedule.
- rtpg 11y agoWell a bunch of standard libraries have sum defined, right? JavaScript has suffered from a lack of a standard library for a while. Having a small package like this means that (in theory) everyone is using the same bug free version of summing instead of writing their own. Honestly having JS start building a standard library at this point would be wonderful.
- guscost 11y agoThere's already `Array.prototype.reduce()` in most browsers, which will do summing, string concatenation, and any other kind of aggregation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... If you need something more convenient I highly recommend just adding lodash and getting a whole bag of rock-solid awesome tools.
- aub3bhat 11y agoThe recursive folder structure in npm-modules was the first indication. At least Java had a single tree with com.bigco.division.application.framework.library.submodule.NIHObject.java
- LoneWolf 11y agoThat recursive node_modules or whatever it is called was what made me hate this whole npm thing, specially because it is not centralized somewhere in my computer. And that means the same files a few times repeated on my drive just eating space. Being a Java developer I don't understand why the approach was not more like maven.
- aub3bhat 11y agoits a long standing issue, and gets worse when there is node_modules inside node_modules inside node_modules ... so on that someone suggested renaming node_modules to n_m . https://github.com/nodejs/node-v0.x-archive/issues/6960#issuecomment-46704998 https://github.com/nodejs/node-v0.x-archive/issues/6960#issu...
- JaRail 11y agonpm does a decent enough job deduping shared packages. The reason is different packages consume different versions of things. Java only lets you have a single version of a package. If the API changes, it can be a pain when your dependencies were written for different versions. That slows adoption since you have to wait until everyone you depend on has updated first.
- david-given 11y agoAre you thinking of the new flat-tree npm? Because in my 1.3.10 installation, I see this: $ find node_modules/ -type f | wc -l 56278 $ find node_modules/ -type f | xargs md5sum | gawk '{print $1}' | sort | uniq | wc -l 8545 That's a lot of duplicate files.
- jacobolus 11y agoYou should then go dive into the passAll function: https://github.com/tjmehta/101/blob/master/pass-all.js https://github.com/tjmehta/101/blob/master/pass-all.js It’s written in such a way that every time you call... passAll(f1, f2, ..., fn)(args..) ... there are something like 5 + 2n attribute accesses, 5 + 3n function calls, 3 + n new functions created, as well as some packing and unpacking of arguments, not including the actual application of the functions to the arguments that we care about. That’s in addition to the several functions defined in the dependent submodules, which you only have to pay for constructing once. [From my quick eyeball count. These numbers could be a bit off.]
- jdmichal 11y agoI'm more disappointed that it doesn't short-circuit the operation at all. It applies all the functions, THEN it determines whether all of them passed. Even worse, it uses `every` (which does short-circuit) to determine that all the functions are, indeed, functions, but apparently the ability to use that function to determine whether every predicate passes was missed.
- jacobolus 11y agoIt could have been a simple for loop with a break whenever one evaluates false. Blazing fast in every javascript engine, and easy to see all the code in one place. Instead, it’s a slow tower of bloat, which you need to read 5 files to reason about. Javascript implementation: function passAll() { var fns = [].slice.call(arguments); return function() { for (var i = 0, len = fns.length; i < len; i++) { if (!fns[i].apply(null, arguments)) { return false; } } return true; }; } Or Coffeescript (including the function check): passAll = (fns...) -> for fn in fns then if typeof fn isnt 'function' throw new TypeError 'all funcs should be functions' (args...) -> (return false if not fn args...) for fn in fns true
- tjmehta 11y agoLol, nice, I wrote "pass-any" first. I then copied the code and replaced "or" w/ "and" to create "pass-all". I will probably have go back and change this now that I know about it. In general though, not gonna a lie, I am not very concerned about micro performance optimizations.
- mozumder 11y agoIt really is the fault of the language that something this fundamentally horrible is allowed to exist in itself. When people ask why Javascript is terrible, show them this.
- mikekozak 11y agoThe same could be said for your post. When people ask why commenting on message boards is terrible, show them this. If you don't want to write modules this way, don't. Nothing about javascript requires that you even read articles about modules that you don't want to use. Or read articles and then follow up by posting on message boards about articles about modules you aren't going to use. Bang some code out instead. Your opinion of javascript is about as valuable as the opinion of the person who wrote the modules.
- mozumder 11y agoWhen every major Node package depends on this, starting with Babel, then it actually does becomes something thats required. There's no such thing as "don't use it if you don't like it!" in this case. Javascript is a completely broken, shameful system that rightfully deserves all the scorn it's gotten. It really is the worst. (note that i actually write Python & VanillaJS, and avoid Node packages entirely for now.)
- zanny 11y agoThis is more a reflection of how bad the JS language is than anything. Real programming languages have means of standardizing the most common UX and simple patterns into a standard library. Javascript is a consortium hell that never gets updated sufficiently, and has no good standard library, so NPM basically replaces the standard library with a thousand micropackages.
- bbcbasic 11y agoAlso it is a lot easier to get it wrong in JS. Is it null? Is it undefined? Is it bird? Is it a plane? No it's a string!(but sometimes a number). Good programming languages make it easy to write is negative e.g. isNegative = (<0) where implicitly by the 0 and < it will take a Num and return a bool and this is type checked at compile time.
- EvanPlaice 11y agoUse the null object pattern. If you're checking a value to see if it's set by testing for null/undefined, you're doing it wrong. This is good advice for any language, not just JS. Besides, using null as the default for an undefined value is a mistake. Null should indicate a non-value not the absence of a value. Maybe one day the static OOP languages will die so devs have a chance to learn the difference.
- bbcbasic 11y agoMy point is more that the compiler* can't detect these mistakes but in other languages you can. E.g. in Haskell you only allow Null on types when you want it (you do this by using the Maybe type). Objects where you probe for values that could be undefined or could be defined but null doesn't exist as a concept but if you badly wanted it you could use a dictionary. In Haskell if you use Maybe and you process a Maybe object you have to deal with the null and not null case otherwise you get a compiler error. All these checks seem annoying but we've all seen the bar chart of when you discover the bug vs. the cost of that bug. The compiler finding the bug is cheap. Haskell is a cheap language to program in, compared to JS! * I forgot there is no compiler in JS but let's say the linter for argument sake.
- lewisl9029 11y agoThis comes up a lot when people discuss anything related to npm modules. It's easy to simply dismiss these trivial one-line modules as "insanity" and move on, but there's actually plenty of good reasons as to why many prefer to work with multiple small modules in this manner. This GitHub comment by Sindre Sorhus (author of over 600 modules on npm) is my favorite writeup on the topic: https://github.com/sindresorhus/ama/issues/10#issuecomment-117766328 https://github.com/sindresorhus/ama/issues/10#issuecomment-1... TL;DR: Small modules are easy to reason about, and encourage code reuse and sharing across the entire community. This allows these small modules to get a tremendous amount of real world testing under all sorts of use cases, which can uncover many corner cases that an alternative naive inlined solution would never have covered (until it shows up as a bug in production). The entire community benefits from the collective testing and improvements made to these modules. I also wanted to add that widespread use of these small modules over inlining everything makes the new module-level tree-shaking algorithms (that have been gaining traction since the advent of ES6 modules) much more effective in reducing overall code size, which is an important consideration in production web applications.
- wodencafe 11y agoBut this doesn't address the author's point that each module, each dependency is an additional point of failure.
- lewisl9029 11y agoThere are definitely trade-offs involved when making decisions to inline vs import. Strictly speaking, you're definitely right. Each dependency is an additional point of failure, but so is each additional line of code you inline. The benefits of these small modules is that they're very thoroughly tested by the entire community. I'd say for most cases, they will be much more robust than any solution an individual developer can spontaneously whip up. Of course, these modules don't exist in a vacuum, and infrastructure failures such as this one do pose another point of failure you wouldn't have with inlining code, but I think in this particular case it had more to do with the failure of npm to adhere to package management best practices to not include an unpublish feature.
- deleted 11y ago[deleted]
- mpeg 11y agoIt's a fucking nightmare, is what it is. I wanted to use a javascript tool that would make my life easier, and when I looked at the npm dependency tree it had 200+ dependencies in total. If I used that javascript tool, I'd be trusting hundreds of strangers, lots of which had absolutely no clout in github (low number of stars, single contributor projects) with my stuff. And not just them, I'd be trusting that no one steals their github credentials and commits something harmful (again, these projects are not very popular). It doesn't help that npm doesn't (AFAIK) implement code signing for packages which at least would let me manage who I choose to trust
- ts330 11y agoYES YES YES! In all the debate about this, why is the trust-dependency-fuck-show not getting more attention? Every dependency you take is another degree of trust in someone else not getting compromised then suddenly finding all sorts of horribleness making it into your production environment. It beggars belief!
- tjmehta 11y agoAuthor of "is-positive-integer" here. I will admit the implementation is pretty funny, but I move-out all single-purpose utils out of projects to modules for a bunch of reasons. DRY is the most obvious one, but one that may be less obvious is for better testing. I move out modules so I can write really nice tests for the independent of the projects I am using them in. Also, I tend to write projects w/ 100% test coverage, breaking out utils allows me to test projects easier and faster. Also note, the implementation of this module changed a few times today. With it being open source and having the collaboration of other engineers, we ended up with a very performant version, and discovered interesting quirks about "safe integers" in JS.
- phaedryx 11y agoWith how weird javascript can be about numbers, it actually didn't surprise me that your module existed.
- gizmo385 11y ago"DRY is the most obvious one, but one that may be less obvious is for better testing." Isn't that why we just write functions? Turning simple functions into entire modules just adds an unnecessary level of abstraction that helps nobody.
- tedmiston 11y agoOf course that's why we write functions. But we can't share a function with others and across projects... so we make it into a module to do that. It's like (micro)crowdsourcing (the smallest components of) the standard library that JavaScript never had. Some bit of logic could go from being DRY in one project, to DRY in all of my projects, ... to eventually be DRY in all projects. It's globally DRY.
- lolidaisuki 11y ago>Of course that's why we write functions. But we can't share a function with others and across projects... so we make it into a module to do that. Sounds an awful lot like a library.
- sergiotapia 11y agoDRY taken to the dogmatic extreme where everything is made up and the github stars are the only thing that matters. This article touches on things that are wrong in the javascript culture. I always had this nagging feeling when working with NPM, this article brings it to light. For what it's worth I never felt this while writing Ruby, C# or Go. It's the -culture- that needs to change here, not the tools.
- kaonashi 11y agoYou create unit tested functions and expose them to client code with a factory pattern, how is that so ridiculous?
- khy 11y agoThis implementation reads almost as parody, although I don't suspect that the author meant it as such. If you didn't have a sense of what lurked behind the abstraction, it would be kinda beautiful.
- rycfan 11y agoYeah, there are a few shitty examples on npm. It's an open system and anyone can upload anything. The market speaks on how valuable those are. Cherry picking poor modules says nothing about the rest. Plus, if you think that's too small, write your own broader module that does a bunch of stuff. If people find it valuable, they'll use it. If they find it more valuable than a bunch of smaller modules, you'll get 10,000 downloads and they'll get 10. The module you roundly ridicule has had 86 downloads in the last month, 53 of which were today (at the time of this writing). I imagine most of those 53 were after you posted. So that's 40 downloads in a month, as compared to the express framework which has had 5,653,990 downloads in the last month. The wailing and gnashing of teeth over this module is ridiculous.
- dbpokorny 11y agoI can't stop laughing. I think you have to admire the elegance of the concept as performance art though: this is cheap insanity. In fact, I've got to hand it to them, this is the most fun I've had looking at something programming related in a while. I recall the opening lines of SICP, > I think that it's extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customers got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don't think we are. I think we're responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don't become missionaries. Don't feel as if you're Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don't feel as if the key to successful computing is only in your hands. What's in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more. Quoted in The Structure and Interpretation of Computer Programs by Hal Abelson, Gerald Jay Sussman and Julie Sussman (McGraw-Hill, 2nd edition, 1996).
- xorcist 11y agoWhat I want to know is how many systems does the author of is-positive-integer have implicit root access to? Sounds to me like publishing oneliners on NPM is a trivial way to build a botnet.
- insin 11y agoSeems like the answer is "none" by default, from https://docs.npmjs.com/misc/scripts#user https://docs.npmjs.com/misc/scripts#user > If npm was invoked with root privileges, then it will change the uid to the user account or uid specified by the user config, which defaults to nobody. Set the unsafe-perm flag to run scripts with root privileges.
- xorcist 11y agoThat's good, even if nobody is perfectly enough to a botnet. I thought more of the user running the node application.
- roddux 11y agoI have an extremely hard time believing this module is not a joke, ditto for many other NPM modules.
- teddyuk 11y agoI end up spending most of my working life working on other peoples code, rather than new features I end up debugging and fixing bad code. (I actually rather like it) The majority of code I have ever seen is awful (20 years across large + small companies) but that is why I am hired to fix awful code so I am skewed. The amount of times I have seen people implement something simple, in a convoluted error prone was is unbelievable. I know this seems ridiculous but when you see time and time again how people fail to do the simplest things it seems like a good idea.
- nailer 11y ago> They've already taken it to an entirely different level of insanity. Why is this insane? What alternatives would be better?
- StreamBright 11y agoI had several arguments about JS and I was shocked how many developers consider this platform great. I am not sure why these extremely bad practices are defended by devs, what are they getting out of it? I am only hoping we are moving towards more sensible development environment, there are many of them with better best practices and more sane libraries.
- mikeash 11y agoI can't decide what's crazier to me: that such a package exists, or that JavaScript is such a ridiculously bad language that an "is positive integer" function is non-trivial to write.
- plugnburn 11y agoSure, because just writing isPositive = (x) => +x === x && x > 0 is boring. Need more requires to require the requires... Keep in mind though that absolutely not all JS programmers are like that. Not everyone wants to be an aforementioned Dick-from-a-mountain.