0

The problem is that if you want to use the same function synchronously and in a Promise, the use of arguments would differ because the first arguments could come from the Promise.

Is there a better solution than my current workaround ?

As an example - a function truncating a string:

sync:

truncate('A very long string coming from a sync. operation', 10);

async:

Promise.resolve('A very long string coming from a network request')
  .then( truncate(10) )

The async version would make the truncate Function think that 10 is the string and you would need to check typeof in every function or do ducktyping. What would work:

Promise.resolve('A very long string coming from a network request')
  .then( truncate.it(10) )

if you extended the function prototype before (which is not what I want):

Function.prototype.it = (function() {
  return function() {
    var args = arguments;
    return function(){
        Array.prototype.push.apply(arguments, args);
        return this.apply(null, arguments);
    }.bind(this);
  };
}());

function foo(a, b, c) {
  console.log('a is ' + a, ' | b is ' + b, ' | c is ' + c);
};

// LOGIC :    
foo(1, 2, 3);
// SAME AS
foo.it(2, 3)(1);
// OR
foo.it(3)(1, 2);
// OR pretty useful for .then()
Promise.resolve(1).then(foo.it(2, 3));

fiddle

[edit] : I need it to apply it to a bunch of functions (e.g. all exports) and the user of this functions should not need to import anything else.

sebilasse
  • 3,202
  • 2
  • 30
  • 30
  • This isn't really specific to promises. A better example would be `["…", …].map(…)` – Bergi Aug 19 '16 at 11:27
  • What you are asking for is currying or partial application; but try not to make the argument order so confusing. You might want to have a look at [Ramda](http://ramdajs.com/) – Bergi Aug 19 '16 at 11:29
  • In underscore: `_.partial(truncate, _, 10)` or `_.partial(foo, _, 2, 3)`. In any case, you should not need to let that affect the way you design your interface. – Bergi Aug 19 '16 at 11:31
  • The difference from currying or partial is that either the user using my module/function has to write it or has do import two different functions from my code. I am looking for a solution where the user can simply use the same function. – sebilasse Aug 19 '16 at 13:24
  • and btw: The only specific thing about promises is that it must be partial from right, e.g. https://lodash.com/docs#partialRight - underscore's partial is applying from left as far as I know. – sebilasse Aug 19 '16 at 13:46
  • Yes, you could leave it up to the user to import a currying/partial-application library and apply it to your functions (though for currying you should make sure that data comes last in your parameters), but if you want your user to be able to use the same function then you'll have to (auto)curry yourself. – Bergi Aug 19 '16 at 14:05
  • Regarding partial-right, no, that only depends on the signature of your function (not on where the function is used). If you go for data-last, `_.partial` and `_.curry` will be easy (same for Ramda), if you go for the weird data-first order then you have to use placeholders in `_.partial` or use `_.partialRight` – Bergi Aug 19 '16 at 14:08
  • 1
    You want `truncate.bind(null, 10)` or if you wanna get fancy and use experimental syntax `::truncate(10)` – Benjamin Gruenbaum Aug 21 '16 at 15:29
  • @BenjaminGruenbaum Where does "experimental syntax" come from? – sebilasse Aug 22 '16 at 11:13
  • @BenjaminGruenbaum: Watch out, [the bind operator does (currently?) not feature partial application](http://stackoverflow.com/a/31221199/1048572). `::truncate(10)` is `truncate.call(, 10)` – Bergi Aug 22 '16 at 12:28
  • @Bergi the bind operator was replaced like 10 times in the last month. I'm giving a best guess here :) – Benjamin Gruenbaum Aug 22 '16 at 12:43

0 Answers0