{"id":17458123,"url":"https://github.com/pocesar/js-bettercurry","last_synced_at":"2025-03-21T03:33:31.921Z","repository":{"id":14815090,"uuid":"17537567","full_name":"pocesar/js-bettercurry","owner":"pocesar","description":"Forget Function.bind and func.apply(context, arguments), performance matters! For a better curry!","archived":false,"fork":false,"pushed_at":"2014-05-08T04:07:33.000Z","size":308,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-18T06:28:13.436Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"piranha/keymage","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pocesar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-03-08T07:41:17.000Z","updated_at":"2017-10-06T10:26:52.000Z","dependencies_parsed_at":"2022-09-01T19:30:44.508Z","dependency_job_id":null,"html_url":"https://github.com/pocesar/js-bettercurry","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pocesar%2Fjs-bettercurry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pocesar%2Fjs-bettercurry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pocesar%2Fjs-bettercurry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pocesar%2Fjs-bettercurry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pocesar","download_url":"https://codeload.github.com/pocesar/js-bettercurry/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221811374,"owners_count":16884305,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-18T03:54:58.071Z","updated_at":"2024-10-28T09:17:17.512Z","avatar_url":"https://github.com/pocesar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/pocesar/js-bettercurry.png?branch=master)](https://travis-ci.org/pocesar/js-bettercurry?branch=master)\n\n[![browser support](https://ci.testling.com/pocesar/js-bettercurry.png)](https://ci.testling.com/pocesar/js-bettercurry)\n\n# Better Curry\n\nBecause `return function(){ return fn.apply(context, Array.prototype.slice.call(arguments)); }` isn't good enough, that's why better curry.\n\nForget `Function.bind` and `func.apply(context, arguments)`, performance matters! For a better curry!\n\nYou won't find any other curry module that can achieve those benchmarks.\n\n## Install\n\n```bash\n~ npm install better-curry\n```\n\nor\n\n```bash\n~ bower install better-curry\n```\n\nWorks on the browser or on node.js (super duper performance on the latter)\n\n## API\n\n#### `BetterCurry.wrap(fn [, context[, len [, checkArguments]]])`\n\nWhen the function have all arguments defined.\nYou can bind the new resulting function to a new context (change the `this` inside the function).\n\n```js\nfunction base(argument1, argument2){\n    return this.data + ' ' + argument1 + argument2;\n}\n\nvar based = BetterCurry.wrap(base, {data: 'hurry'});\nbased('up','!'); // 'hurry up!'\n```\n\nIf the function doesn't have defined parameters, you can still coerce\nthe function to adopt a length\n\n```js\nfunction base(){\n    return Array.prototype.slice.call(arguments).join(' + ');\n}\nvar based = BetterCurry.wrap(base, null, 3);\nbased('one', 'two', 'three', 'will be ignored'); // 'one + two + three'\n```\n\nPassing a `len` of `-1` will make sure it behaves like variadic (that is, uses `fn.apply(context, Array.prototype.slice.call(arguments));`\n\nWhen passing `true` to `checkArguments`, it will check if the body of the function has the `arguments` keyword.\nIf so, it will use a variadic function instead of a defined length.\n\n```js\nfunction base(){\n    return Array.prototype.slice.call(arguments).join(' + ');\n}\nvar based = BetterCurry.wrap(base, null, -1);\nbased('one', 'two', 'three', 'wont be ignored','its','free for all'); // 'one + two + three + wont be ignored + its + free for all'\n```\n\nGenerated function will have a `__length` property, that equals to the original fn length.\n\nYou may hint the function by appending the expected length to your function (or if it's already wrapped):\n\n```js\nvar myfunc = function(arg1, arg2, arg3, arg4){\n\n};\nmyfunc.__length = 3;\n\nBetterCurry.wrap(myfunc, null, true); // creates a threeArgs wrapped function\n```\n\n#### `BetterCurry.predefine(fn, args [, context[, len [, checkArguments]]])`\n\nPredefine creates a function that, when executed, will have the\npredefined arguments plus any arguments that you pass:\n\n```js\nfunction base(argument){\n  return argument;\n}\nvar based = BetterCurry.predefine(base, ['argument','will be ignored']);\nbased('this will be ignored as well'); // 'argument'\n```\n\nVariadic work as well, just remember to pass the len `-1` (or `8` if you think it will be that big...)\n\n```js\nfunction base(){\nreturn Array.prototype.slice.call(arguments).join(' + ');\n}\nvar curried = BetterCurry.predefine(base, ['1','2','3','4'], null, -1);\ncurried('5'); // '1 + 2 + 3 + 4 + 5'\n\ncurried = BetterCurry.predefine(base, ['1','2','3','4'], null, 5);\ncurried('5','6'); // '1 + 2 + 3 + 4 + 5'\n```\n\nAll `-1` len are slower since it uses `Function.apply` (many times slower than `Function.call`)\n\nWhen passing `true` to `checkArguments`, it will check if the body of the function has the `arguments` keyword.\nIf so, it will use a variadic function instead of a defined length.\n\nGenerated function will have a `__length` property, that equals to the original fn length\n\n#### `BetterCurry.delegate(proto, target)`\n\nA minor rewrite of [visionmedia's delegates](https://github.com/visionmedia/node-delegates) but around 13% faster\n\n```js\nvar obj = {\n  request: {\n    _value: 1,\n    function1: function(){},\n    get value(){\n      return this._value;\n    },\n    set value(val){\n      this._value = val;\n    },\n  }\n};\n\nvar delegated = BetterCurry.delegate(obj, 'request'); //all mirror functions from obj will reflect to obj.request with the same context\n\ndelegated\n.method('function1')\n.access('value')\n.access({name: 'value', as: 'value2'})\n.method({name: 'function1', as: 'function2', args:['arg1']});\n\n//obj is now:\nobj = {\n  function1: function1(){/*...*/},\n  function2: function1(arg1){/*...*/},\n  value: /*..value..*/\n  value2: /*..value..*/\n  request: {/*...*/}\n};\n```\n\n#### `BetterCurry.flatten(...args)`\n\nFlattens all array-like arguments passed (`Array` and `arguments`) and append them in order:\n\n```js\nfunction stuff(){\n    return BetterCurry.flatten([1,2,[3]], arguments);\n}\nstuff(1,2,3, [1,2,3]); // returns [1,2,[3],1,2,3,[1,2,3]]\n```\n\n# Test\n\nJust regular stuff (100% coverage by the way)\n\n```bash\nnpm run test\n```\n\n```bash\nnpm run coverage\n```\n\n```\n=============================== Coverage summary ===============================\nStatements   : 100% ( 138/138 ), 3 ignored\nBranches     : 100% ( 330/330 ), 5 ignored\nFunctions    : 100% ( 30/30 )\nLines        : 100% ( 138/138 )\n================================================================================\n```\n\n# Benchmark\n\nCurious about performance? Get flabbergasted.\n\n```bash\nnpm run benchmark\n```\n\n# License\n\n```\nThe MIT License (MIT)\n\nCopyright (c) 2014 Paulo Cesar\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpocesar%2Fjs-bettercurry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpocesar%2Fjs-bettercurry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpocesar%2Fjs-bettercurry/lists"}