JavaScript callbacks and functional programming

"Functional programming describes only the operations to be performed on the inputs to the programs, without use of temporary variables to store intermediate results."

The question is how to apply functional programming and yet use async modules that utilize callbacks. In some case you had like the callback to access a variable that a function that invokes the async reference poses, yet the signature of the callback is already defined.

example:

function printSum(file,a){
     //var fs =....
     var c = a+b;
     fs.readFile(file,function cb(err,result){
          print(a+result);///but wait, I can't access a......
     });
}

Of-course I can access a, but it will be against the pure functional programming paradigm

Answers:

Answer
fs.readFile(file, (function cb(err,result){
    print(this.a+result);
}).bind({a: a});

Just inject context with variables and scope into the function if you must.

Because you complain about the API

fs.readFile(file, (function cb(a, err,result){
    print(a+result);
}).bind(null, a);

It's called currying. This is a lot more FP.

Answer

I think the problem is that you're misunderstanding what they mean by the use of an intermediate value (or they're misrepresenting it, I haven't read the link). Consider that a variable in a functional language is the definition of something, and that definition cannot change. It's perfectly acceptable to use names for values/formulas in functional programming, as long as they don't change.

function calculate(a,b,c) {
    // here we define an name to (a+b) so that we can use it later
    // there's nothing wrong with this "functionally", since we don't 
    // change it's definition later
    d = a + b;
    return c * d;
}

On the other hand, the following would not be ok, functionally

function sum(listofvalues) {
    sum = 0;
    foreach value in listofvalues
        // this is bad, since we're re-defining "sum"
        sum += value;
    return sum
}

For something closer to what you had in your code... consider you have a function call map that takes a list of things and a function to apply to a thing and returns a new list of things. It's perfectly acceptable to say:

function add_value(amount) {
    amount_to_incr = amount * 2;
    return function(amount, value) {
        // here we're using that "amount" value provided to us
        // the function returned will always return the same value for the same
        // input... its "referentially transparent"
        // and it uses the "intermediate" value of amount_to_incr... however, since 
        // that value doesn't change, it's fine
        return amount_to_incr + value;
    }
}
map [1,2,3] add_value(2) ;// -> [3,4,5]
Answer
function printSum(file, a) {
     //var fs =....
     var c = a + b;
     fs.readFile(file, function cb(err, result, aa = a) {
          print(aa + result);
     });
}

With the default parameters nowadays, a can be passed into the callback.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.