2016-12-07 1 views
0

Je suis relativement nouveau dans la programmation fonctionnelle et dans les librairies telles que ramda.js mais une chose que j'ai trouvée très utile est la possibilité d'exécuter des fonctions.Fonctions au trait: comment les optimiser

Utilisation des fonctions cari j'écris très souvent des choses comme

suivantes

const myFun = R.curry(
 
    (arg1, arg2) => { 
 
    let calculated = anotherFun(arg1) 
 
     //do something with calculated and arg2 
 
    return calculated * 5 + arg2 
 
    } 
 
) 
 

 
const anotherFun = (arg) => { 
 
    console.log("calling anotherFun"); 
 
    return arg + 1 
 
} 
 

 
var partial = myFun(1) 
 

 
console.log(partial(2)) 
 
console.log(partial(3))
<script src="//cdn.jsdelivr.net/ramda/0.22.1/ramda.min.js"></script>

mais clairement dans cette situation anotherFun est appelée à chaque fois que j'appelle partial même si arg1 et en conséquence calculated sont toujours les mêmes.

Existe-t-il un moyen d'optimiser ce comportement et d'appeler anotherFun uniquement lorsque ses arguments changent?

La seule façon qui traverse mon esprit est ce

const myFun = R.curry(
 
    (calculated, arg2) => { 
 
    return calculated * 5 + arg2 
 
    } 
 
) 
 

 
const anotherFun = (arg) => { 
 
    console.log("calling anotherFun"); 
 
    return arg + 1 
 
} 
 

 
var calculated = anotherFun(1) 
 
var partial = myFun(calculated) 
 

 
console.log(partial(2)) 
 
console.log(partial(3))
<script src="//cdn.jsdelivr.net/ramda/0.22.1/ramda.min.js"></script>

mais de cette façon, je dois changer les arguments passés à myfun et cela complique l'API externe

Répondre

3

Si vous faites le curry manuellement comme ceci

const myFun = arg1 => arg2 => { 
    let calculated = anotherFun(arg1) 
    // do something with calculated and arg2 
    return calculated * 5 + arg2 
}; 

vous pouvez également faire cette optimisation:

const myFun = arg1 => { 
    let calculated = anotherFun(arg1); 
    return arg2 => { 
    // do something with calculated and arg2 
    return calculated * 5 + arg2 
    }; 
}; 

Je ne pense pas que Ramda vous aidera ici avec quoi que ce soit; et les compilateurs JavaScript ne font certainement pas ce genre d'optimisation.

1

@Bergi est juste que Ramda ne vous offrira aucune aide avec ceci. Si vous voulez un résultat de style Ramda, où vous pouvez appeler avec un paramètre pour obtenir une fonction de retour, ou les deux pour obtenir le résultat que vous pouvez faire ceci:

const myFun = function(arg1, arg2) { 
    let calculated = anotherFun(arg1); 
    const newFunc = arg2 => { 
    return calculated * 5 + arg2 
    }; 
    return (arguments.length < 2) ? newFunc : newFunc(arg2); 
}; 

const with3 = myFun(3); 
//: calling anotherFun 

with3(1); //=> 21 
with3(2); //=> 22 
with3(4); //=> 23 


myFun(2, 7); 
//: calling anotherFun 
//=> 22 

myFun(2, 8); 
//: calling anotherFun 
//=> 23 

Cela se fait au prix de ne pas être en mesure d'utiliser ES2015 flèche fonctions. Mais cela pourrait en valoir la peine pour vous.

Vous pouvez également retravailler légèrement pour ne pas créer la fonction interne si les deux paramètres sont fournis, si cela est important pour vous.

0

Que diriez-vous de useWith et memoize de Ramda?

const myFun = R.useWith(
    (a, b) => a * 5 + b, 
    [R.memoize(anotherFun), R.identity] 
);