Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

>TL;DR: Small modules are easy to reason about, and encourage code reuse and sharing across the entire community.

How does that even remotely applies to the "is positive integer" test, and even more so to "it's positive" and "it's integer"?

What's next? is-bigger-than-5? word-starts-with-capital-letter? add-1-to-a-number?



Not defending javascript because I dislike it immensely, but with javascript being a dynamically typed language, and with the way it handles implicit conversions between types, and with trickiness around NaN, Infinity and null objects, there are sufficient edge cases that writing a correct function to test if some variable contains a positive integer is not as trivial as it is with more sane languages, and is likely to trip up even experienced developers if they miss one or more of those edge cases.

Having pre-written modules that account for all edge cases that have been battle-tested by hundreds, thousands, or even millions of users does have merit.

The main problem here is with the Javascript language, which makes code evolve to things like 'is-positive-integer'.


(That's the whole point of using a dynamic language, what '>' actually does depends on the surrounding code. If you want '>' to type check you should be using a type safe language to begin with.)

The issue I have with this is readability. Type '>' and I know exactly what it does, I know what implicit conversions are involved, and how it would react to a null object. Type 'isPositiveInteger' and I need to check. I can not read your code fluently anymore.


What if sometimes I want the overloaded, type relevant '>', and sometimes I want to do '>' if the inputs are positive integers, and raise an exception otherwise?


If you want to build is-bigger-than-5 yourself, I recommend pulling in fivejs[1] as a dependency.

[1] https://github.com/jackdcrawford/five


five.js was missing something. I fixed it. https://github.com/jackdcrawford/five/pull/234


I laughed way too hard at this :)

Well played.


Did you add dist/five.js to commit by mistake?


Nope, that was on purpose.


No way!


Lucky for you, I just made yeonatural.js, project template generator that can instanciate fully amd compatible <n>.js.

We're doing a GSoC for efficient templating of real number though.


This module is a joke, right? Right?


I would have bet on "yes" until a day ago.


Yes it's a joke. In fact it's a joke on this very matter.


Why is English the only language in which "Five" is capitalized?


Five would only be capitalized at the beginning of a sentence.

You wouldn't write: "I saw Five of my friends last night."


add-1-to-a-number

This seems to be a very common example in educational materials about how to create a function in some programming language. Perhaps they should all be prefaced with "NOTE: you should not actually make such a function, because its triviality means that every time you use it you will be increasing the complexity of your code", or a longer discussion on when abstraction in general is appropriate and when it is not.

Ditto for any other abstraction --- I've found there's too much of an "abstraction is good so use it whenever you can" theme in a lot of programming/software design books and not enough "why abstraction can be bad" sort of discussion, which then leads to the "you can never have too much" mentality and the resultant explosion of monstrous complexity. Apparently, trusting the reader to think about the negatives and exercise discretion didn't work so well...


> Apparently, trusting the reader to think about the negatives and exercise discretion didn't work so well...

That's the whole point. If you use is-positive-integer, you won't have to think about the negatives!


It doesn't.

Of course we have a number of packages that are truly trivial and should probably be inlined. Npm is a completely open platform. Anyone can upload any module they feel like. That doesn't mean anyone else will feel the need to use them.

I think you'll find that the vast majority of small modules that are widely used are ones that also cover obscure corner cases and do benefit from widespread use and testing.


You don't have to be widely used to be widely used, though. I bet there are tons of developers who would never dream of using left-pad or is-positive-integer, but nevertheless have copies of them (multiple copies?) on their computers due to transitive dependencies.


No, you see "is-bigger-than-5" clearly does 4 different things. You need these modules:

module.exports = exec("===");

module.exports = bigger(a, b){return a > b};

module.exports = () => return "than";

module.exports = (a) => a.search('ABCD...');

.. or something like that. These are all plugins of course.


Do you seriously think that "word starts with a capital letter" is an easy function to write?

I feel like you haven't spent enough time with Unicode.


return string[0] === string[0].toUpperCase();

You're welcome!


WRONG. Typical junior developer mistake. Even if we disregard trivial problems such as non-letter input or empty input, this will only work with English and a few other languages. This will TOTALLY fail with e.g. Turkish input (I ı vs İ i).


Not really. (string[0] == string[0].toUpperCase() && string[0] != string[0].toLowerCase()) is the correct way to approach this problem. If toUpperCase() and toLowerCase() don't handle Turkish letters, then that's a BUG in those methods, which should be reported and someone should freaking take responsibility for them and fix them.

Adding another module with a method does not fix the original problem, it just creates more problems for other people to solve.


> var isCapital function(s) { return s[0] === s[0].toUpperCase(); };

> isCapital("שלום");

true

> isCapital("1");

true

> isCapital('\uD83D\uDE00'); // Smiling emoji

true

> isCapital(\u279B); // Right-facing arrow

true

> isCapital("\u061Casd"); //Bidirectional control character

true

> isCapital(" ");

true


If "true" is not a valid answer, what would've been one? Similar code in C# returns the same. E.g. Console.WriteLine("שלום".ToUpperInvariant()=="שלום") returns true.


Hebrew doesn't have upper and lower case, so the question "is this hebrew character capital" is meaningless. So, the function in question should not return just a boolean value; it should have a way to return a third option. (Whether it's nil, a C-style return code, an exception, an enum or something else is irrelevant here.)

Actually, it just means that if you're wondering "if this word starts with a capital", you're asking a wrong question. Instead, you should be asking "if this word is a valid generic name", or "is this word a start of a new sentence", and implement these semantic queries in a language-specific way.


You have final-forms in Hebrew, although probably not at the same level of support for checking as you'd get with a script like Arabic.


That's true, but I don't think that sofits should be viewed as capital/not-capital letters: they're not semantically altering the meaning of the word in wider context, like capital letters do.


This will give

  startsWithCapitalLetter("!") == true
which is not what you want.


TIL 1 is a capital letter.


string[0] === string[0].toUpperCase() && string[0].toUpperCase() != string[0].toLowerCase();


typeof string == "string" && string.length && string[0] == string[0].toUpperCase() && string[0].toUpperCase() != string[0].toLowerCase();


Man, Javascript is AWESOME.


/\p{Lt}/.test(str) would be much more compact, but Unicode properties still aren't available in Javascript regular expressions. It doesn't look like they will be anytime soon. I guess they have some staging system and it's still at stage 0 (https://github.com/tc39/ecma262/blob/master/stage0.md), grouped with lookbehind assertions, named captures, and mode modifiers.


Not that I agree with micro modules (I would rather see a set of js core libs), but your code fails with empty strings.


That code fails in a whole host of cases, kind of proving that sometimes trivial "just one line" functions aren't actual that trivial to get right.

edit: fortunately there's an npm modules you can included to fix it...


Maybe F1axs knows that at this particular spot the string will never be empty? There are two philosophies in libraries; one is to check for every possible error in the lib function, the other is to state the pre-conditions in the documentation.


> Not that I agree with micro modules (I would rather see a set of js core libs)

Why not both? If you just want one part of a module, you can just import the dependency directly, if you want a whole core lib, you can do that.

Some people really like underscore and import that. I use ES6/7 functions for the most part, but underscore has some useful things I can import on their own.


string[0] isn't necessarily one code point.


The three cases you state aren't nearly as hairy as determining whether something is a positive integer.

Someone might do something like ~~n to truncate a float. That works fine until you go above 32 bits. Math.trunc should be used instead. Someone might do something like n >>> 0 === n, and using any bitwise operators will always bake in the assumption that the number is 32 bits. Do you treat negative 0 as a negative integer? Detecting negative 0 is hairy. So, to avoid bad patterns, it makes sense.

For is-bigger-than-5(x), x > 5 is not hairy. For add-1-to-a-number(n), n + 1 is not hairy.

For word-starts-with-capital-letter(word)? That one is actually pretty hairy. There are programmers that would write a regular expression /^[A-Z]/, or check the charCode of the first character being within the A-Z range, amongst other solutions. An appropriate solution, however, would be (typeof word == "string" && word.length && word[0] == word[0].toUpperCase() && word[0].toUpperCase() != word[0].toLowerCase()), because the toUpperCase and toLowerCase methods are unicode-aware, and presently you can't access unicode properties using Javascript's flavor of regular expressions.


People have started to point out the existence of modules in this very vein. And, of course, write them. With two such together, you can probably get is-maybe-5 .

* https://news.ycombinator.com/item?id=11351905

* https://news.ycombinator.com/item?id=11359302


If those functions are reusable or complex enough (partly due to deficiencies in javascript the language, sure) then why not?


>add-1-to-a-number

i++




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: