Emulate / use continuations in JavaScript?

I have a function that calculates the product of numbers in an array. The function should work as follows

function prod (array){ //compute and return product } var arr = [1,2,3,0,4,5,0,6,7,8,0,9]; the function call: prod(arr); //should return 6 prod(arr); //should return 20 prod(arr); //should return 336 (6*7*8) prod(arr); //should return 9 prod(arr); //should return 0 prod(arr); //should return 0 prod(arr); //should return 0 

In the scheme, this is done with continuation, preserving the previous state of the function (the state of the function is captured immediately before its exit point); see this

So, in short, I want the javascript function to return different values ​​at different times with the same parameter passed each time.

JavaScript is a well-developed language, so I hope something can mimic this. If there is nothing in JS to do this, I do not mind concluding with failure and moving on. Therefore, feel free to say that this is not possible.

Thanks.

+4
source share
4 answers

JavaScript is not capable of supporting continuations: it lacks tail calls.

In general, I would write this to use the “queue” in sorts, although CPS is also do-able (it just has a finite stack :-) Note that another state can also be captured in closure, which makes it “explicitly continue” in a very rude sense.

An example of using closure and queue:

 function prodFactory (array){ // dupe array first if needed, is mutated below. // function parameters are always locally scoped. array.unshift(undefined) // so array.shift can be at start // also, perhaps more closured state var otherState // just return the real function, yippee! return function prod () { array.shift() // do stuff ... eg loop array.shift() and multiply // set otherState ... eat an apple or a cookie return stuff } } var prod = prodFactory([1,2,3,0,4,5,0,6,7,8,0,9]) // array at "do stuff", at least until "do stuff" does more stuff prod() // [1,2,3,0,4,5,0,6,7,8,0,9] prod() // [2,3,0,4,5,0,6,7,8,0,9] prod() // [3,0,4,5,0,6,7,8,0,9] 

Happy coding.


"Completed implementation." Although this particular problem can avoid mutating the array and just use the index: the same concepts apply. (Well, a little different. Only with the index the private variable will be changed, whereas with this approach the object will mutate.)

 function prodFactory (array) { array = array.slice(0) return function prod () { var p = 1 for (var n = array.shift(); n; n = array.shift()) { p *= n } return p } } var prod = prodFactory([1,2,3,0,4,5,0,6,7,8,0,9]) prod() // 6 prod() // 20 prod() // 336 
+3
source

You can assign a property to the function that will be remembered between calls:

 function prod (array){ if (typeof prod.index === "undefined" || prod.currentArray != array) { prod.currentArray = array; prod.index = 0; } if (prod.index >= array.length) return 0; //compute and return product var p = 1, c; while (prod.index < array.length) { c = array[prod.index++]; if (c === 0) return p; p *= c; } return p; } 

I just guess from your description of what should be returned, that when calling the function individually, it should take the product of all numbers before, but not including the next zero or end of the array. Should calls after the end of the array return 0? I may have the wrong algorithm, but you realized that I suggest remembering the state of the function between calls.

I added a property to remember the current array being processed. As long as you continue to pass the same array to the function, it will continue with the following elements, but if you pass another array, it will reset ...

+2
source

you can try something like

 var index = 0; function prod (array){ if(index < array.length){ var prod=1; for(int i=index;i<array.length;i++){ if(array[i] != 0){ prod = prod * array[i]; } else{ index = i+1; return prod; } } } return 0; } 

this will update the index of the global variable every time the function is called.

+1
source

Here you will find generators . Starting with version 1.7, JavaScript supports them .

+1
source

Source: https://habr.com/ru/post/1385721/


All Articles