New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support recursive calls that respect merged functions #53
Conversation
This is a really nice solution Nick 😎 It's a very smart idea to utilize the function's If I'm not mistaken, when using the function's function compileArgsPreprocessing(params, fn, resolveSelf) {
// ...
return fn.apply(resolveSelf(), args);
// ...
} We should also double check if this has any impact on the performance. |
examples/recursion.js
Outdated
}); | ||
|
||
// use the typed function | ||
console.log(sqrt(9)); // output: 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe good to also demo console.log(sqrt('9'));
here, passing a string as input 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, oops! Good catch.
aead67c
to
8fa9428
Compare
Thanks for the feedback. I think it's a good call to give directly binding the function a try. Given the way I refactored |
That is a really neat refactoring, thanks 👍 I tested in mathjs and it indeed just works replacing self references with I did run the benchmark in
Can this be related to the extra indirection introduce with |
Good call on checking the benchmarks. It seems that it wasn't actually the refactored I reworked things again and now the numbers look to be comparable. There are couple slower runs in this branch and in the I also ran the new implementation against math.js, with all the recursive function calls replaced with
|
That's awesome news 🎉 ! Your latest PR is very nice and simple. I've done some testing and can confirm that there is no decrease in performance at all. Maybe one last small simplification step: the following chunk of code: // create the typed function
// fast, specialized version. Falls back to the slower, generic one if needed
var makeFn = function () {
var fn = function fn(arg0, arg1) {
'use strict';
if (arguments.length === len0 && test00(arg0) && test01(arg1)) { return fn0.apply(fn, arguments); }
if (arguments.length === len1 && test10(arg0) && test11(arg1)) { return fn1.apply(fn, arguments); }
if (arguments.length === len2 && test20(arg0) && test21(arg1)) { return fn2.apply(fn, arguments); }
if (arguments.length === len3 && test30(arg0) && test31(arg1)) { return fn3.apply(fn, arguments); }
if (arguments.length === len4 && test40(arg0) && test41(arg1)) { return fn4.apply(fn, arguments); }
if (arguments.length === len5 && test50(arg0) && test51(arg1)) { return fn5.apply(fn, arguments); }
return generic.apply(fn, arguments);
}
return fn;
}
var fn = makeFn(); can be simplified to: function fn (arg0, arg1) {
'use strict';
if (arguments.length === len0 && test00(arg0) && test01(arg1)) { return fn0.apply(fn, arguments); }
if (arguments.length === len1 && test10(arg0) && test11(arg1)) { return fn1.apply(fn, arguments); }
if (arguments.length === len2 && test20(arg0) && test21(arg1)) { return fn2.apply(fn, arguments); }
if (arguments.length === len3 && test30(arg0) && test31(arg1)) { return fn3.apply(fn, arguments); }
if (arguments.length === len4 && test40(arg0) && test41(arg1)) { return fn4.apply(fn, arguments); }
if (arguments.length === len5 && test50(arg0) && test51(arg1)) { return fn5.apply(fn, arguments); }
return generic.apply(fn, arguments);
} And lastly, we should also document this new feature in the API description in the README.md. If you want I can do that, no problem. |
That really cleans it up nicely! That would be great if you added the details about this in the README. I wasn't sure which sections this feature should be mentioned in. Once this is merged and a new release is published, I can open a PR in math.js to replace all the existing self references. |
Thanks Nick, looks great 😎 . I've merged your PR and published Thanks for also working on the changes in mathjs, if you need help there please let me know, it may be quite some work. |
That's great - thanks @josdejong! I had already replaced all the instances of recursion I could find in math.js to test against this new functionality locally. I've opened a PR here: josdejong/mathjs#1903 |
👍 |
This PR implements a method of recursion that works with merged typed-functions. The issue was originally discussed here: josdejong/mathjs#1885.
I tested this change against math.js, replacing all recursive typed-function calls I could find in the library, and the tests are passing. I can open a PR for that too, if this looks acceptable.
A slight modification on this approach would be to remove the proxy object and change
to
which would then allow definitions like so:
However, I am not sure if using a function bound as
this
works in all browsers.