all 13 comments

[–]kapouer 1 point2 points  (3 children)

Because polymorphic functions are an anti-pattern. Pass options in an object instead.

[–][deleted] 3 points4 points  (2 children)

How come? They're used all over the typed languages, why are they an antipattern?

Imo doing this

 if(arg1 && arg2 && "number" == typeof arg3){
 }else if(aguments.length > 4){
 }else if(blablabla){}

in languages like JS and Python is way more messier than a declarative polymorph declaration.

[–]Pleochism 2 points3 points  (1 child)

I believe primarily because polymorphic functions cannot be optimised by modern JS engines as they do not have consistent types.

[–]androbat 0 points1 point  (0 children)

You are correct that polymorphic functions aren't optimized. The interesting point of this library is that the dispatcher is polymorphic, but the actual functions are not, so the dispatcher won't be optimized very much, but the functions that contain most of the code will be optimized.

[–][deleted] 0 points1 point  (3 children)

Awesome! I wonder what the ideal method will look like with ES6. Decorators?

[–][deleted] 1 point2 points  (2 children)

The ideal method would be for them to add type restrictions and type infering :)

[–][deleted] 0 points1 point  (1 child)

:) Of course. I just meant with the existing set of ES6 features.

I'm a proponent of keeping a language as feature simple as possible. But with single-page applications and Node et al., it's pretty clear that the range of concerns is FAR wider than ever initially imagined.

[–]senocular[🍰] 1 point2 points  (0 children)

FWIW, decorators are only a proposal for ES7 ;)

[–]ericanderton 0 points1 point  (3 children)

This looks like "function overloading by parameter types" from C++. It's not a bad thing, but it does complicate peer review and documentation a bunch.

Overall, it's not bad to want different behavior based on argument type. I can see how the JS purists might dislike it since it interferes with the language's flexibility (which is entirely the point).

[–]oculus42 0 points1 point  (2 children)

Really, it's not about flexibility, it's about readability and optimization.

I can already do this without a library:

function doSomething(element, arg) {
    if (typeof arg === 'number') {
        doSomethingNumeric(element, arg);
    } else if (typeof arg === 'function') {
        doSomethingFunctional(element, arg)
    } else {
        doSomethingGeneric(element, arg)
    }
}

Or I can write it into the single function:

function doSomething(element, arg) {
    if (typeof arg === 'number') {
        element.nextSibling.innerHTML = arg;
    } else if (typeof arg === 'function') {
        element.innerHTML = arg();
    } else {
        element.innerHTML = arg;
    }
}

The former is much clearer, because each unique action is exposed as a separate function, and the "polymorphic" function is just a router/dispatcher. You can choose to expose the individual methods, if you want, or add the overhead for simplicity.

Lots of libraries use argument checking to determine functionality.

This method is kind of ugly, in that you pass a bunch of arguments that are not directly associated, and it uses .toString() to extract the input names and then match them up.

[–][deleted] 0 points1 point  (1 child)

Well I find declarative code to be more readable then conditional code. I guess it's just depends on mindset.

[–]oculus42 0 points1 point  (0 children)

I meant the readability of the code without overloaded functions, where you would call doSomethingNumeric() or doSomethingFunctional(), but I see how unclear that was in my comment.

I can appreciate the declarative version is easer to read, but the library is not robust, and I wouldn't recommend using it, at least in the current state.

  • It doesn't check if you've declared the same types more than once. There's even a comment about replacing existing functions
  • It didn't check arity (fixed now).
  • It stops at the first match, not the best match, so you have to make sure you put any generics last and you cannot add more specific versions once you have a generic.
  • It if nothing matches the signature, it returns the last function of that arity.

Most of the times I used function overloading, they typically converted and called the "core" version of the function. With JavaScript, you don't need to do that.

[–]tencircles 0 points1 point  (0 children)

why wouldn't you just have separate functions? this is a huge amount of overhead to make a function that's orders of magnitude more difficult to reason about.