How to make a function call itself n times - javascript

Let's say I have a function called f that takes an integer argument called x and returns an integer. I also have an integer n that says how many times the function must call itself. So for example if my function call looks like this f(x) when n = 1, then it would look like this f(f(f(x))) when n = 3. How could something like that look in my example bellow:
function succ(n) {
return function (f, x) {
return f(x);
};
}

You could loop inside the inner function:
for(let i = 0; i < n; i++) x = f(x);
return x;
or alternatively let your function call itself:
return n > 0 ? succ(n - 1)(f, f(x)) : x;

We can express this algorithm corecursively. Corecursion builds its result on the way forward from the starting point:
const iterate = f => x =>
[x, () => iterate(f) (f(x))];
const main = iterate(x => x * 2) (1);
console.log(
main[1] () [1] () [1] () [1] () [1] () [1] () [1] () [1] () [0]); // 256
This is just a proof of concept but not what we actually want. How can we avoid the clunky interface? We can use a Proxy to make the non-argument function implicit. It is basically the same mechanism as with lazy property getters. Additionally we don't want to access values from the stream manually but with a function for convenience:
class ThunkProxy {
constructor(f) {
this.memo = undefined;
}
get(g, k) {
if (this.memo === undefined)
this.memo = g();
if (k === THUNK)
return true;
else if (k === Symbol.toPrimitive)
return () => this.memo;
else if (k === "valueOf")
return () => this.memo;
else return this.memo[k];
}
}
const THUNK = "thunk";
const thunk = f =>
new Proxy(f, new ThunkProxy(f));
const iterate = f => x =>
[x, thunk(() => iterate(f) (f(x)))];
const takeNth = n => ([head, tail]) =>
n === 0
? head
: takeNth(n - 1) (tail);
const main = iterate(x => x * 2) (1);
console.log(
main[1] [1] [1] [1] [1] [1] [1] [1] [0]); // 256
console.log(
takeNth(16) (main)); // 65536

You could build a times high order function and use it to wrap other functions...
const times = (fn, n) => (...args) => {
if (!n) { return; }
fn(...args);
return times(fn, n - 1)(...args);
}
const log10 = times(console.log, 10);
log10('hello');

Related

Evaluating Nested function call represented as string

how to solve nested function call represented as string in javascript
as "PRODUCT(SUM(PRODUCT(2,2),2),3)" => 18
as "SUM(12,PRODUCT(1,2))" => 14
This would be easy using eval().But need to do without using eval().
const SUM = (...args) => args.reduce((a, b) => a + b);
const PRODUCT = (...args) => args.reduce((a, b) => a * b);
const evaluateString = str => {
//code to evaluate "PRODUCT(SUM(PRODUCT(2,2),2),3)"
}
As Yeldar said the cleanest way to do it would be to create syntax tree and to evaluate it but with your given example it looks like you will always get only 2 args since your functions just implement trivials operators. Given those informations it would be a pain to code for such a basic use so i recommand to create your own evaluator in this case.
Ok this is clearly not a very clean way to do and their is probably a lot of possible upgrades but here is a piece of code doing the job :
const SUM = (...args) => args.reduce((a, b) => a + b);
const PRODUCT = (...args) => args.reduce((a, b) => a * b);
const strToEvaluate = "PRODUCT(SUM(PRODUCT(2,2),PRODUCT(SUM(1,1),2)),3);";
function myEval(str) {
if(!isNaN(str)) {
return Number(str);
}
if(str.includes('(')) {
let fn = str.split('(')[0];
let pos = getParenthesisAndComaPos(str.substring(str.indexOf('(')+1));
let arg1 = myEval(str.substring(str.indexOf('(')+1).substring(0, pos[0]));
let arg2 = myEval(str.substring(str.indexOf('(')+1).substring(pos[0]+1, pos[1]));
switch(fn) {
case 'PRODUCT':
return PRODUCT(arg1, arg2);
case 'SUM':
return SUM(arg1, arg2);
}
}
}
//Will return a tab with position of the coma between arg0 and arg1 and position of the end parenthesis
function getParenthesisAndComaPos(str) {
let counter = 1;
let i=0;
let c=0;
while (counter>0 && i<=str.length) {
if(counter==1 && str.charAt(i)==',') {
c = i;
}
if(str.charAt(i)==')') {
counter--;
} else if(str.charAt(i)=='(') {
counter++;
}
i++;
}
return [c, i-1];
}
console.log(myEval(strToEvaluate));

Recursively calling a curried function in Javascript

As a toy example lets say we have this function and its usage:
const map = (f = n => n + 1) => (lst = [1,2,3]) => {
if(lst.length === 0)
return [];
else
return [f(...lst.splice(0,1)), ...map(f)(lst)];
}
const inc = n => n + 1;
const map_inc = map(inc);
map_inc([1,2,3]) // => (produces) [2,3,4]
Inside of the curried function map I am using "recursion" by calling map(f)(lst).
The example above rebuilds the function before it can be called.
Is it possible to do this recursion without rebuilding the function?
I know of this way:
y = (f = (f, ...args) => [...args],
...args) => f(f, ...args);
const map = (mapper = n => n + 1) => (self = mapper, lst = [1,2,3]) => {
if(lst.length === 0)
return [];
else
return [mapper(...lst.splice(0,1)), ...self(self, lst)];
}
const inc = n => n + 1;
const map_inc = (...args) => y(map(inc), ...args);
map_inc([1,2,3]) // => (produces) [2,3,4]
I do not really like how this requires the passing of the function to itself.
Can this be done without the y function and without passing the function to itself? Can this be done in a more point-free style?
If I'm understanding your question correctly, you can't return named arrow functions, but you can return a named regular function and call it recursively like this:
const reducer = k => function recurse(a, item) {
//...
const s_res = _.split(item, k, 1);
return recurse(a.withMutations(a => {
a.push(s_res[0]);
let a_element = document.createElement('a');
a_element.setAttribute('href', '#');
a_element.addEventListener('click', () => display_gen_element(k, obj));
a.push(a_element);
}), s_res[1]);
};
P.S. For the sake of readability please don't use one-letter variable names unless it's blindingly obvious what they're for, e.g. a counter in a for loop, etc.
If your purpose was remove the need to pass self to itself
...self(self, lst)
You can do this by adding 1 more function named recursor
const map = (mapper = n => n + 1) => (lst = [1, 2, 3]) => {
const recursor = lst => {
if (lst.length === 0) return [];
else return [mapper(...lst.splice(0, 1)), ...recursor(lst)];
};
return recursor(lst);
};
const inc = n => n + 1;
const map_inc = map(inc);
console.log(map_inc([1, 2, 3])); // => (produces) [2,3,4]
You didn't need the y combinator-like function called y at all.
recursor has mapper in its closure

JavaScript call multi function, but input value is output from last function

I have a function like that:
function intiFun(initValue) {
const firstResult = firstFun(initValue);
const secondResult = secondFun(firstResult);
const thirdResult = thirddFun(secondResult);
const fourthResult = fourthFun(thirdResult);
return fourthResult;
}
but i want to write it better. and i dont want to save value from each function as variable.
is there any solution to to call functions with out save old value
like rxjs or somthing like that:
function intiFun(initValue) {
return firstFun(initValue).secondFun().thirddFun().fourthFun();
}
or more better like that:
function intiFun(initValue) {
return firstFun(initValue)
.secondFun(secondInput)
.thirddFun(secondInput)
.fourthFun(secondInput)
}
function secondFun(value, secondInput) {
return ...;
}
...
or some liberally to do that (maybe lodash)
My guess is you're looking for function composition: we can construct the composite function from an array of functions in JavaScript using for example reduce (with the initial value being the identity function (v) => v:
const composeAll = (functions) => functions.reduce(
(composition, f) =>
((v) => f(composition(v))),
(v) => v
);
const firstFun = (s) => `${s}a`;
const secondFun = (s) => `${s}b`;
const thirdFun = (s) => `${s}c`;
const fourthFun = (s) => `${s}d`;
const intiFun = composeAll([firstFun, secondFun, thirdFun, fourthFun]);
console.log(intiFun(''));
OUTPUT:
abcd
NOTES:
As you can see, composeAll creates a chained function call by wrapping each function f in an arrow function which takes a value v, executes it on the composite function constructed from the preceding functions in the array and finally passes the result to f.
You can convince yourself that the construction is correct by induction over the array length: if we define the composition of an empty list of functions to be the identity function then
in the base case (for a singleton array [f] with length 1) the result is
(v) => f((v => v)(v)) === (v) => f(v)
in the step case (for an array with length n) assume the function obtained for the n-1 preceding functions in the array was correctly constructed (let this be g), then the result is
(v) => f_n(g(v)) === (v) => f_n(f_n-1(...(f_0(v))...))
pipe, manual currying & partial application to the rescue:
const pipe = funs => x =>
funs.reduce ((o, fun) => fun (o), x)
const f = x => x + 1
const g = x => y => x + y * 2
const h = x => x * x
const i = x => y => z => x + y / z + 3
const j = x => x + 5
const init = pipe ([
f
,g (4)
,h
,i (10) (33)
,j
])
const input = 1
const output = init (input)
console.log (output)
You can do something like this
const firstFun = x => x + 1;
const secondFun = x => x + 1;
const thirdFun = x => x + 1;
const fourthFun = x => x + 1;
const pipe = (...functions) => x => functions.reduce((x, f) => f(x), x);
const initFun = pipe(firstFun, secondFun, thirdFun, fourthFun);
console.log(initFun(3));
const firstFun = x => { /* return ... */ };
const secondFun = x => { /* return ... */ };
const thirdFun = x => { /* return ... */ };
const fourthFun = x => { /* return ... */ };
const callAll= (value, ...functions) => {
functions.forEach(fn => value = fn(value));
retrun value;
}
const result = callAll(3, firstFun, secondFun, thirdFun, fourthFun);
console.log(result);
The result you're looking for can be achieved using reduce.
let log = (head, ...args) => { console.log('log:', head, ...args); return head },
firstFun = (str, ...args) => log(str, ...args) + ' firstFun',
secondFun = (str, ...args) => log(str, ...args) + ' secondFun',
thirddFun = (str, ...args) => log(str, ...args) + ' thirddFun',
fourthFun = (str, ...args) => log(str, ...args) + ' fourthFun';
function initFun(initValue) {
let functions = [
[firstFun],
[secondFun, 'extra argument'],
[thirddFun],
[fourthFun, "I'm here too"],
];
return functions.reduce((result, [fn, ...args]) => fn(result, ...args), initValue);
}
console.log( 'result: ' + initFun('foo bar') );
Keep in mind that I log the incomming arguments of the methods, not the resulting value. This means that for example secondFun (log: foo bar firstFun extra argument) has the argument 'foo bar firstFun' and 'extra argument'. But you only see the added string 'secondFun' when thirdFun is called (since it is given as the argument).
function initFun(initValue) {
return fourthFun(thirddFun(secondFun(firstFun(initValue))));
}
Alternatively, convert your function into promises:
function initFun(initValue) {
return firstFun(initValue)
.then(secondFun)
.then(thirddFun)
.then(fourthFun);
}
Bad Method — See Below
If you want something like a.firstFunc().secondFunc().thirdFunc().fourthFunc(), you should define those functions to Object.prototype (or Number.prototype, String.prototype, etc.):
Object.prototype.firstFunc = function() {
var value = this;
// ...
return something;
};
Object.prototype.secondFunc = function() {
var value = this;
// ...
return something;
};
Object.prototype.thirdFunc = function() {
var value = this;
// ...
return something;
};
Object.prototype.fourthFunc = function() {
var value = this;
// ...
return something;
};
P.S. "Function" is normally shortened to "func" but not "fun".
Update
If you want something like myObject(a).firstFunc().secondFunc().thirdFunc().fourthFunc(), you should:
var myObject = function(value) {
this.value = value;
};
myObject.prototype.firstFunc = function() {
var value = this.value;
// ...
return something;
};
myObject.prototype.secondFunc = function() {
var value = this.value;
// ...
return something;
};
myObject.prototype.thirdFunc = function() {
var value = this.value;
// ...
return something;
};
myObject.prototype.fourthFunc = function() {
var value = this.value;
// ...
return something;
};

How to correctly serialize Javascript curried arrow functions?

const makeIncrementer = s=>a=>a+s
makeIncrementer(10).toString() // Prints 'a=>a+s'
which would make it impossible to de-serialize correctly (I would expect something like a=>a+10 instead.
Is there a way to do it right?
This is a great question. While I don't have a perfect answer, one way you could get details about the argument/s is to create a builder function that stores the necessary details for you. Unfortunately I can't figure out a way to know which internal variables relate to which values. If I figure out anything else i'll update:
const makeIncrementer = s => a => a + s
const builder = (fn, ...args) => {
return {
args,
curry: fn(...args)
}
}
var inc = builder(makeIncrementer, 10)
console.log(inc) // logs args and function details
console.log(inc.curry(5)) // 15
UPDATE: It will be a mammoth task, but I realised, that if you expand on the builder idea above, you could write/use a function string parser, that could take the given args, and the outer function, and rewrite the log to a serialised version. I have a demo below, but it will not work in real use cases!. I have done a simple string find/replace, while you will need to use an actual function parser to replace correctly. This is just an example of how you could do it. Note that I also used two incrementer variables just to show how to do multiples.
function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace)
}
const makeIncrementer = (a, b) => c => c + a + b
const builder = (fn, ...args) => {
// get the outer function argument list
var outers = fn.toString().split('=>')[0]
// remove potential brackets and spaces
outers = outers.replace(/\(|\)/g,'').split(',').map(i => i.trim())
// relate the args to the values
var relations = outers.map((name, i) => ({ name, value: args[i] }))
// create the curry
var curry = fn(...args)
// attempt to replace the string rep variables with their true values
// NOTE: **this is a simplistic example and will break easily**
var serialised = curry.toString()
relations.forEach(r => serialised = replaceAll(serialised, r.name, r.value))
return {
relations,
serialised,
curry: fn(...args)
}
}
var inc = builder(makeIncrementer, 10, 5)
console.log(inc) // shows args, serialised function, and curry
console.log(inc.curry(4)) // 19
You shouldn't serialize/parse function bodies since this quickly leads to security vulnerabilities. Serializing a closure means to serialize its local state, that is you have to make the closure's free variables visible for the surrounding scope:
const RetrieveArgs = Symbol();
const metaApply = f => x => {
const r = f(x);
if (typeof r === "function") {
if (f[RetrieveArgs])
r[RetrieveArgs] = Object.assign({}, f[RetrieveArgs], {x});
else r[RetrieveArgs] = {x};
}
return r;
}
const add = m => n => m + n,
f = metaApply(add) (10);
console.log(
JSON.stringify(f[RetrieveArgs]) // {"x":10}
);
const map = f => xs => xs.map(f)
g = metaApply(map) (n => n + 1);
console.log(
JSON.stringify(g[RetrieveArgs]) // doesn't work with higher order functions
);
I use a Symbol in order that the new property doesn't interfere with other parts of your program.
As mentioned in the code you still cannot serialize higher order functions.
Combining ideas from the two answers so far, I managed to produce something that works (though I haven't tested it thoroughly):
const removeParentheses = s => {
let match = /^\((.*)\)$/.exec(s.trim());
return match ? match[1] : s;
}
function serializable(fn, boundArgs = {}) {
if (typeof fn !== 'function') return fn;
if (fn.toJSON !== undefined) return fn;
const definition = fn.toString();
const argNames = removeParentheses(definition.split('=>', 1)[0]).split(',').map(s => s.trim());
let wrapper = (...args) => {
const r = fn(...args);
if (typeof r === "function") {
let boundArgsFor_r = Object.assign({}, boundArgs);
argNames.forEach((name, i) => {
boundArgsFor_r[name] = serializable(args[i]);
});
return serializable(r, boundArgsFor_r);
}
return r;
}
wrapper.toJSON = function () {
return { function: { body: definition, bound: boundArgs } };
}
return wrapper;
}
const add = m => m1 => n => m + n * m1,
fn = serializable(add)(10)(20);
let ser1, ser2;
console.log(
ser1 = JSON.stringify(fn) // {"function":{"body":"n => m + n * m1","bound":{"m":10,"m1":20}}}
);
const map = fn => xs => xs.map(fn),
g = serializable(map)(n => n + 1);
console.log(
ser2 = JSON.stringify(g) // {"function":{"body":"xs => xs.map(fn)","bound":{"fn":{"function":{"body":"n => n + 1","bound":{}}}}}}
);
const reviver = (key, value) => {
if (typeof value === 'object' && 'function' in value) {
const f = value.function;
return eval(`({${Object.keys(f.bound).join(',')}}) => (${f.body})`)(f.bound);
}
return value;
}
const rev1 = JSON.parse(ser1, reviver);
console.log(rev1(5)); // 110
const rev2 = JSON.parse(ser2, reviver);
console.log(rev2([1, 2, 3])); // [2, 3, 4]
This works for arrow functions, that do not have default initializers for the arguments. It supports higher order functions as well.
One still has to be able to wrap the original function into serializable before applying it to any arguments though.
Thank you #MattWay and #ftor for valuable input !

Why my JavaScript function won't end?

So I have the following code, from which I expect the x function to return null after being called 3 times but it keeps returning the the same function:
const repeat = (n, tailFn) => {
for (let i = 0; i < n; i++) {
tailFn = () => tailFn;
}
return tailFn;
};
const x = repeat(2, x => null);
console.log(x()); // function tailFn() { return _tailFn }
console.log(x()()); // function tailFn() { return _tailFn }
console.log(x()()()()()()); // function tailFn() { return _tailFn }
What am I doing wrong? See it on CodePen.
Your function just assigns () => tailFn to tailFn three times and then returns it. Instead, you should return a function which returns repeat(n - 1, tailFn) if n is not 0, and tailFn otherwise.
const repeat = (n, tailFn) => {
return n !== 0 ? () => repeat(n - 1, tailFn) : tailFn;
};
const x = repeat(2, x => null);
console.log(x()); // () => repeat(n - 1, tailFn)
console.log(x()()); // x => null
console.log(x()()()); // null
You have created a function that ALWAYS returns itself,
tailFn=()=>tailFn;
actually the loop is meaningless.Its behavior is similar to a recursive function without a base case.

Categories

Resources