1

Is there a way to achieve the code bellow with Javascript (ES6)?

If yes, how can I do it? I try this example, but it didn't work.

const funcA = (callback, arg1) => {
  console.log("Print arg1: " + arg1); /* Print arg1: argument1 */
  let x = 0;
  x = callback(x, );
  return x;
}

const funcB = (x, prefix) => {
  console.log("Print prefix: " + prefix); /* Print prefix: PREFIX_ */
  x = x + 1;
  return x;
}

/* Exec function funcA */
let x = funcA(funcB( ,"PREFIX_"), "argument1");
console.log("Value of x: " + x); /* Value of x: 1 */
5
  • you have empty arguments and leading comma. what result do you expect? Commented Jan 18, 2018 at 18:17
  • I know that. But what I mean with the blank space and comma is that the arguments are pass in different time. Commented Jan 18, 2018 at 18:19
  • Partial application - that is what I want to know! My example shows that. (see the accepted answer). Commented Jan 18, 2018 at 18:36
  • @PedroGabrielLima Define x as a default parameter funcA(x = () => funcB(x = 0 ,"PREFIX_"), "argument1"); Commented Jan 18, 2018 at 18:52
  • @guest271314 I got this error from console with your example: ReferenceError: can't access lexical declaration `x' before initialization. Commented Jan 18, 2018 at 18:55

3 Answers 3

2

This is an approach with a defined placeholder as symbol to identify the parameter which is not yet set.

It features a this object which is bind to the calling function for further check and evaluation.

If the combined array of arguments object and this.arg has no more placeholder items, the function is called with parameters and return the function call.

If not, the new arguments array is bind to the function and returnd.

[?] denotes the placeholder symbol

funcB x prefix this.args args action
1. call [?] "PREFIX_" [?], "PREFIX_" return calling fn w/ bound args
2. call 0 [?] [?], "PREFIX_" 0, "PREFIX_" return fn call with args
3. call 0 "PREFIX_" return 1

(Of course it could be a bit shorter and delegated to another function, but it's a proof of concept.)

function funcA(callback, arg1) {
    console.log('funcA', callback, arg1)
    return callback(0, placeholder);
}

function funcB(x, prefix) {
    var args = this && this.args || [],
        temp = Array.from(arguments);

    console.log('funcB', isPlaceholder(x) ? '[?]' : x, isPlaceholder(prefix) ? '[?]' : prefix);

    // placeholder part
    if (temp.some(isPlaceholder)) {
        temp.forEach((a, i) => isPlaceholder(a) && i in args || (args[i] = a));
        return args.some(isPlaceholder)
            ? funcB.bind({ args })
            : funcB(...args);
    }

    // origin function body
    return x + 1;
}

const
    placeholder = Symbol('placeholder'),
    isPlaceholder = v => v === placeholder;

console.log("Value of x: " + funcA(funcB(placeholder, "PREFIX_"), "argument1"));

Sign up to request clarification or add additional context in comments.

2 Comments

nice! +1. Could you explain some details of your example? 1. In funcB, where it come the variable "arguments"? It's a default parameter for functions? 2. In the output, it was printed "funcB 0 [?]" and "funcB 0 PREFIX_", that means funcB was called twice. So the first time it called for binding funcB in funcA, the second time was for returned funcB(...args)? 3. The first call for funcB was made in "funcA(funcB(placeholder, "PREFIX_"), "arguments")", the second call was made in "return callback(0, placeholder)"?
every function in Javascript supplies arguments object, which is an array like object with all paramters of the actual function. it is right, the calling series, as you stated, but the function is called three times. it always checks if there is no placeholder in the arguments list. if so, it returns the origin function body evaluation.
1

Partial application is not yet possible in js. You need another arrow function that acts as a callback:

funcA(x => funcB(x ,"PREFIX_"), "argument1");

To call that you don't need that extra comma:

x = callback(x)

Somewhen this proposal might allow to write this:

 funcA( funcB(?, "PREFIX_"), "argument1")

2 Comments

Nice reference to the proposal +1
@pedro glad to help :)
-1

One approach would be to define a default parameter that is a function for the first parameter passed to funcA and use var to define x when funcA is called

const funcA = (callback, arg1) => {
  console.log("Print arg1: " + arg1);
  let x = 0;
  x = callback(x, arg1);
  return x;
}

const funcB = (x, prefix) => {
  console.log("Print prefix: " + prefix);
  x = x + 1;
  return x;
}

/* Exec function funcA */
var x = funcA(x = () => funcB(x = 0 ,"PREFIX_"), "argument1");
console.log("Value of x: " + x);

7 Comments

If you see in my example, I didn't pass the arg1 as argument to callback. Would it make difference?
@PedroGabrielLima Why did you not pass the arg1 argument? How does that change the expected result? What are you trying to achieve?
It this example it's not so clear, but the fact that I isolate the arguments in funcB turn the code modular. In your example, arg1 is part of funcA, but I want funcA be immutable. That way, if a want pass a funcC instead of funcB to funcA, it won't depend on the variable arg1. I hope be clearly about that hehe.
Do you mean that where arg1 is not specifically passed prefix will still be defined at funcB? That is, a default value will be set, and the default value can be the adjacent defined argument?
@PedroGabrielLima You can set prefix as a default parameter at funcN; e.g., const fn = ({x = 0, prefix = "PREFIX_"} = {x:0, prefix:"PREFIX_"}) => { console.log(x, prefix) }; fn(); fn({x:2}); see also Can we set persistent default parameters which remain set until explicitly changed?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.