This approach is perfect for the is-even npm package[1], with 196,023 weekly downloads, or the is-odd npm package[2], with 285,501 weekly downloads. Wouldn't it be cool if you type `npm install` and it starts downloading a 40GB is-even and a 40GB is-odd?
It's always worth mentioning that those packages stem from the effort of one dedicated npm spammer[1] to weasel his way into as many node_modules directories as possible. There's also packages for ansi-colors (no, not one package for all colors, one package for each color) and god knows what else. These then get jammed into any cli tool or other half-way sensible looking package, all referencing each other obviously - and any "real" project is just a single innocuous dependency away from having dozens of jonschlinkert packages.
[1] https://www.npmjs.com/~jonschlinkert
When I first heard of the is-odd and is-even NPM packages I was sure they were a joke, yet there we are: 200K weekly downloads! Publishing the packages may have been the effort of one spammer, but many developers obviously chose to use them - that's the part that boggles my mind.
Well, look at one of the dependents: https://www.npmjs.com/package/handlebars-helpers - certainly a more useful npm package, but by the same author. Seldom do people actually type `npm install is-even` - there's just a jungle of transitive dependencies that can be traced back to one of jonschlinkert's many packages, which then circles back to something inane as `is-even` or `ansi-red`.
I once ran a simple grep in some of my node projects - most of them had a jonschlinkert package in node_modules, certainly not through any (direct) choice of my own.
I see, thanks. I guess that answers one question, but raises another: why have his packages depend on more of his packages? If his goal was to be included in as many node_modules directories as possible, and handlebars-helpers was already included what's the point of pulling in is-odd/is-even, too?
He could sell rights to the repos and disavow any knowledge of its maintenance while maintaining the link in his own repos. When those sold rights are used to commit some crime he has plausible deniability as anyone else but got a payday. If you try spinning off the subpackage just prior to a sale then it shows some sort of intent.
Is there any evidence that he has ever done anything like this, or that he plans to? Or is this just pure speculation?
I didn't declare he's done this only that it is a vulnerability of depending on those packages.
Might be this from his GitHub bio “Several years ago, just before my 40th birthday, I switched careers from sales, marketing and consulting to learn how to program” Good way to get more eyeballs…
Ah yes, that actually explains a lot! Thanks.
Here we are all talking about him now!
Makes is-odd/is-even popular; many downloads; raises their (and his) profile.
Check out this very useful utility: https://github.com/mitsuhiko/is-jonschlinkert :)
Possibly related: https://github.com/SukkaW/nolyfill vs. ljharb and nodejs 4
I recently came across this issue (https://github.com/import-js/eslint-plugin-import/issues/213... and https://github.com/import-js/eslint-plugin-import/issues/181...) and man that person has really found him self a hill.
What is a bit worrying though is that he is an active member and contributor to TC-39. Meaning that this kind of community hostility is very much alive among the people who rule JavaScript.
I love the release notes:
Would it be considered bad practice or in poor taste to make pull requests in projects with the sole objective of implementing is-even natively?
Thinking of being the change I want to see in the world.
It’s probably contextual but I’d say it’s in poor taste to use them in the first place. Removing them is a net benefit imo.
the bigger joke is that programming language have no built in
Huh? Did you miss the modulo operator?
It wouldn't have 200k downloads a week unless there was a large number of programmers who didn't know how to do it.
I mean we're talking FizzBuzz secret sauce here. This must be total black magic for a catastrophic percentage of programmers
I have not read the source but I had always assumed that this was the lovingly crafted effort of someone who is intimately familiar with the js standard making sure that some hypothetical expression like ![1] is neither odd nor even. Surely the idea that modulo is beyond developers is too horrifying to contemplate.
Here you go:
It does some checking the `value` is an integer in the safe range, which doesn't even seem right to me. Why shouldn't you be able to call this on integers outside the save range?All non-safe integers are even, yes?
Sad but true. For JavaScript these kind of functions can actually be useful because of all the quirks. If that was the GPs hint then I can understand.
A more catastrophic number of programmers a) dont know how dependencies work and b) think everyone else are idiots.
Perhaps, I solidly understand how dependencies work and in this case my observation is defensible
Someone made the decision to use that and someone thought using stuff made by a person's who makes those kinds of decisions was a good idea and so on.
You can git blame dependencies all the way down and research the parties involved. I've done it, built tools for it even.
A stack of people who make bad decisions doesn't make good software.
Given the lack of integers and my hesitancy to trust modulo for non-integer variables, I don't know if I would trust it. You would need to add some safety checks, but either you create an is_even/is_odd function that has safety checks, or you have to rely on developers adding in the checks anytime the number might have been in close proximity to a floating point number.
Something as simple as this can end up being neither even or odd.
I did learn one new thing from browsing the is-odd source code: Number.isSafeInteger(n) checks that n falls within the [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER] interval.
Seriously fuck this dude leeching on the open source community.
He's not even a technical guy but has a background i marketing and is directly trolling various Github issues :
https://news.ycombinator.com/item?id=28661094
I've always wondered why node-modules and npm required such an insane amount packages so quickly, and now i know why, people like him that use their 10.000 ridiculous packages to boost their career or do whatever self serving community destroying thing they can think off that day.
There really should be a way to ban people doing this shit.
It's more a statement about the community than him imo. Or maybe about what npm allows to be published. Nobody forced you to use is-odd, yet it's downloaded 200k a week, why? Because js' developer community doesn't know any better
A lot or these downloads may be CI systems running automatic tests.
They clearly are, but this still means a not negligible amount of softwares have those packages in their dependencies.
Exactly right. Its clever way of deflecting blame that whole community should share by piling on this particular person.
This really sounds like victim-blaming. The community is vulnerable to somebody publishing asinine modules, which should be addressed. However, this individual is still the perpetrator.
The author hasn't forced you to import their package. What's there to ban apart from maybe polluting the common namespace?
Isn't the post you linked to about a different person?
I mostly write in languages without package managers so it is possible that my expectations are just wrong, but is there no way of showing your dependency graph when using npm?
This is the first time I'm hearing about this guy, but not sure why there's so much hate.
It looks like he came from a non-technical background, and is trying to make the language more noob friendly.
Compare the pair:
if isEven(n) { }
if (n % 2) == 0 { }
I guarantee you my wife would have no idea what the second snippet even means.
if !(n & 1) {} // rightmost bit(LSB) is always `true` for odd integers
AussieWog93 should marry this guy instead.
For code golf purposes, ~n&1 works fine
The hate is deserved. This person lacks ethics.
There's an argument to be made for writing functions like `isEven` and using them instead of n%2. There's an argument that the JS standard library, or other comprehensive util libraries like Lodash or Underscore should include these functions.
The problem here is introducing separate dependencies for each of these tiny functions. Dependencies are code that you haven't written, but are still your responsibility. For a lot of things, that's a good tradeoff: if you don't have the expertise in a specific area, or if you can offload work to a dependency that you trust, that's great. But for micro dependencies like this, it's usually a bad deal - you don't get anything in return (seriously, how hard is it to write your own isEven function?) but you have to rely on a third party to be secure, to not push anything accidentally broken, to not change the API, etc.
(I think it's also worth pointing out that your wife is not a paid programmer. Software development should be accessible, but this isn't the only goal, and I think it's reasonable to assume that most programmers either understand the n%2 idiom, or know enough to be able to find help on the subject.)
Achieving supply-chain security by controlling every link in the chain. This Jon is very noble.
Packages should specify their entitlements.. network access, file access, executing system calls, being able to monkey patch things, accessing packages outside their own.
Deno has a few of these by default an application has no access to the filesystem, env or network.
You can allow only reading or only writing for files and you can also define what domains are allowed.
Sure it's a huge step forward. But that's on an application level, which honestly I can do with sandbox-exec on macOS (see below).
In Deno, all permissions would still propagate down to the dependencies.
or orRealistically I think they long ago should have been banned from npm, with all submissions deleted.
It seems very uncharitable to describe someone as a “spammer” because their philosophy on the proper size of units of code reuse is different from yours.
Even if you think having a dependency load `is_even()` is a good thing, surely you can see how it's pretty hard to defend having a completely separate and nearly identical `is_odd()` rather than just `!is_even()`
It seems overly charitable to me to frame the dispute in those terms. You and I might differ as to the appropriate amount of vermouth in a martini or pineapple on a pizza and I won't worry much about it, within reason.
There's a limit though! I think up to about 10% pineapple by weight is reasonable for a Hawaiian, if you choose 0 or 20% then we'll have no issue. If you went to 30% I don't think I could stop myself writing a libellous remark on hn. Anything about 50% and I would be morally forced to denounce you to the proper authorities. About 80% is where the nightmares begin.
It checks out, sales/consulting folks are pretty infamous for their tendency to abuse metrics. The metric here is npm downloads and Github stars.
The strategy does mean that he's _technically_ not inaccurate in claiming this on his LinkedIn -
I encountered this type a lot in college consulting groups, it's a little funny seeing one make their way to the OSS community.
[1] https://github.com/jonschlinkert
Yeah but this might make him the Patient Zero for modern tech influencing and blogspam.
Anyone know if this has spread to crates.io yet? I see plenty of name squatting, but I haven't run into real crates trying to insert themselves into everything. Namespaces are sorely needed, including some semi-official ones. candi::rand would be reasonable for candidates to enter std. Watching the battles over tokio getting into candi would be fun.
That's hilarious. The best part is that he didn't even try to make good packages (not that hard) but just took the lazy route.
Well one reason could be this software proverb: Good programers are lazy programers.
You may not like it, but this is what 10x performance looks like
So what excuse do the people installing these packages have?
I'm relatively new to the world of node. Is there anything objectively wrong or should I say nefarious with that this Jon person is doing? I guess, what's the issue here, from your perspective, if he's creating package (that albeit are simple) but some some amount of utility?
Another classic from jon is the venerable https://www.npmjs.com/package/isobject coming in at 30,000,000 weekly downloads for
`function(val) { return val != null && typeof val === 'object' && Array.isArray(val) === false; }`
But honestly, having seen "TypeError: Cannot read properties of null" enough times, I give it a pass.
https://npm-stat.com/charts.html?author=jonschlinkert paints a pretty crazy picture
Every time I see these packages mentioned, I’m reminded of an interview with Joe Armstrong. In it, he said, (paraphrasing from memory) “Wouldn’t it be interesting if a language had a global, flat registry of functions that anyone could pull from and contribute to? That way, bugs are fixed in one place, there’s less reinvention of the wheel, things get more correct over time, and programs just become a simple composition of standard functions.”
I may be misremembering his meaning, but I remember thinking it was an interesting idea. It wasn’t obviously a terrible idea. I thought it would be like the Clojure standard library on steroids, especially if it was coordinated and vetted by a decent team.
But alas, NPM has proven it otherwise.
I don't think NPM has proven that idea infeasible, just that it may not be a good idea to depend on third-party content that may change under your feet, on such a fine-grained level.
But have a look at the Unison language https://www.unison-lang.org/docs/the-big-idea/ , that has such global registry but addresses each function by a hash of its syntax tree, and thus sidesteps the issue.
How are bugs "fixed in one place" that way?
You either accept updates of third party packages, with little to no vetting of your own, and get fixes "for free" or… you don't.
There's no middle ground: the only way to save effort is to trust others.
NPM is a worse idea than Joe's as Joe was talking about a single community vetted monorepo. Not a free for all of individual repos.
With Joe's idea everything is up front and part of the language and not a bulletin board of packages near the checkout line at the git supermarket. This way simple stuff like isint() can make its way into the languages official standard library. This should eliminate the uncertainty of 3rd party packages maintained by a random number of individuals that can be taken down or tainted at any time.
This Joe Armstrong quote sums up NPM:
"You wanted a banana but what you got was a gorilla holding the banana and the entire jungle."
(originally on object oriented programming)
NPM doesn’t capture the full benefit of an open registry of functions because, while anyone can fork and create an alternative @christophilis/is-even or @divbzero/is-even, there is no good way for developers to pick the best version of is-even.
Maybe if NPM required all package maintainers to use a namespace, the global is-even package name could resolve to the most-used fork.
So for an import like:
You could install a specific fork: Or default to the most-used fork: In both cases, package.json would only contain namespaced dependencies and npm outdated could flag if a different fork is more commonly used.To be fair, for all its pitfalls, NPM does provide a limited version of that idea to millions of codebases.
The funniest (or best part) about those two packages is that is-even has a dependency to is-odd and does just negate the output of is-odd.
It’s true, the great thing about clean, reusable, modular code like this is that you can compose both of these packages to make a is-even-or-odd package.
Groundbreaking!
Well first you need to obviously build an OR package, part of your suite of logical operator packages, all depending on your battle-tested, high performance XOR package.
You joke... but https://www.npmjs.com/package/is-odd-or-even
If would be even funnier if is-odd would simultaneously do the same thing in reverse.
Implementing the comparisons by hand seems difficult and primitive. May I suggest introducing some helpful sub-packages and building the solution on top of those. For instance, is-odd would be implemented by using is-one, is-three, is-five, is-seven, etc.
and is-one should be implemented by negating is-two, is-three, and so forth
I read some text where a cheme was implemented such that numbers were `2 = 1+1`, `3 = 2+ 1`...
Probably Peano numbers.
https://wiki.haskell.org/Peano_numbers
...
Amazingly, following “don’t repeat yourself” in its purest form, is-even depends on is-odd:
If this code runs on hundreds of millions of phones and computers, npm seems horrible for the environment! Not only because of runtime, but because we’re talking so much just to host and serve these modules!
These packages are performance art, and shall not be judged by efficiency metrics.
I bet a dollar you started writing "performance" and then rewrote it as "efficiency" :)
That’s right. Npm and the entire node ecosystem is just terrible. Specifically because you can get a production ready package from even Google, and you know it’s going to have some random useless package in the chain somewhere.
Actually it’s not good enough there because JavaScript numbers are f64 rather than u32. Even if you only support the safe integer range (beyond which the answers become somewhat meaningless), that’s 2⁵⁴, more than four million times as large as 2³². Not sure how big the machine code would be, but I’m guessing it’ll just add 4 bytes (40%) to each case, so you’re up to something like 224 exibytes. And that’s when you’re being lazy and skipping the last ten bits’ worth. If you want to do it properly, multiply by another thousand. Or maybe a little less, I haven’t thought too deeply about NaN patterns. Or maybe just infinite if it supports bigints.
But we can probably compress the data very well (e.g. "double delta" is always zero), and then decompress only needed parts.
This still requires reading through it all in memory at run time. Maybe we can optimize it with a JIT -what if the package called the ChatGPT api to get the the python code that generates the machine code just for the number queried?
But you can create a self-modifying function that, ‘for speed’, adds each case when it is called.
The initial function should start with checking for special cases NaN, infinities, 0 and -0, then do (may not be valid JavaScript)
to handle cases over 2^54 or below -2^54, then do to determine whether x is odd or even in isOdd. Doing the self-modification is left as an exercise.This is good defensive programming. It avoids doing a tricky division by 2.0 that might be buggy (I don’t think https://en.wikipedia.org/wiki/Pentium_FDIV_bug was affected, but who knows what other FPUs do?)
I did a nullll package [1] whose only purpose is to export a null and takes 400MB in memory but somehow it got flagged in HN [2]. With 41 stars on github and 100% test coverage [3], it was clearly production ready.
[1]: https://github.com/mickael-kerjean/nulll
[2]: https://news.ycombinator.com/item?id=17072675
[3]: https://github.com/mickael-kerjean/nulll/blob/master/test.js
Shame it was flagged. Would've been handy for a project I was working on. Had to work around not having a performant null
That try-catch block[1] is a thing of beauty.
[1] https://github.com/mickael-kerjean/nulll/blob/master/index.j...
I was wondering that the code looked like...
I mean... when you look at it like that, at least it's got the error checking integrated as well... tho the fact it pulls in is-number is fucking hysterical lol
even (https://www.npmjs.com/package/even?activeTab=dependencies) pulls is-even.
is-even (https://www.npmjs.com/package/is-even?activeTab=dependencies) pulls is-odd.
is-odd (https://www.npmjs.com/package/is-odd?activeTab=dependencies) pulls is-number.
sigh
Theoretically only one 40gb file would be needed. AFAICT almost every odd number is not even (I cannot say "all" bc I have not checked every integer yet).
I'd fire someone who imported those packages.
Big fan of code reuse. Small packages providing single unique functionality is the way to program modern systems. It has to be right if bright minds in NPM / Rust community follow this approach.
But of course WebAssembly is the future. So we should reimplement it in WASM.
I did something similar six years ago called gg-flip for npm - https://github.com/avinassh/gg-flip
It was submitted in HN too - https://news.ycombinator.com/item?id=16194932
I haven't heard about him but checking the source tree of our 2 front-end apps and his 'is-number' package (which his is-odd depends on), seems to be imported by quite a few other packages.
Now looking at the source, that package may make sense if figuring out whether something is a number type in JS is really that cumbersome. (Though I'd expect that there is a more generic package that covers the other built-in types as well.)
Also since isNumber treats strings that can be converted to a number, a number, it can yield weird results since adding two strings will naturally just concatenate them. So e.g.:
Of course, it's standard JS stupidity (and 2*a would be 2, and 1+'1' and '1'+1 would both be '11'), but then maybe stating that '1' is a number is not the right response. However, the package was downloaded 46 million times last week and that seems to be so low only because of Christmas. The previous weeks averaged around 70M. And most of these are dependencies, like in our projects, I'm sure.