Solution with setInterval, and setTimeout with explanation
Intuition\n1. using setInterval - you can just retun a function that clears the interval.\n2. using setTimeout - here I create my own setInterval using setTimeo
# Intuition\n1. using setInterval - you can just retun a function that clears the interval.\n2. using setTimeout - here I create my own setInterval using setTimeout\n\n# Approach\n1.\n    A. setInterval and save it\'s ID\n    B. return a function that clears your interval\n2. A. create a setInterval-like function, I called mine `startInterval`. The startInterval function will use a `setTimeout` that keeps on retriggering the `setInterval`. It does this by calling the `startInterval` function that wraps the `setTimeout` when it\'s time elapses.*\n\n*(To rephrase this:\nI trigger a startInterval.\nThis triggers a setTimeout for i.e. 30 seconds.\nAt the end of the 30 seconds, we trigger the startInterval again,\nwhich in turn triggers a setTimeout again for i.e. 30 seconds.\nAt the end of the 30 seconds, we trigger the startInterval again...)\n\nB. We make sure the `startInterval` function has a "circuit breaker" boolean flag, here `isActive`. If we turned this flag off, we stop calling the `setTimeout` wrapper function (aka `startInterval`).\n\n\n# Code\n```\n/*\n// Using setInterval()\nvar cancellable = function(fn, args, t) {\n    fn(...args);\n    let intervalID = setInterval(() => fn(...args), t);\n\n    return function cancelFn () {\n        clearInterval(intervalID);\n    }\n}\n*/\n\n// Using setTimeout()\nvar cancellable = function(fn, args, t) {\n    fn(...args);\n\n    let timeoutID;\n    let isActive = true;\n\n    const startInterval = () => {\n        timeoutID = setTimeout(() => {\n            if(isActive) {\n                fn(...args);\n                startInterval();\n            }\n        }, t);\n    }\n    startInterval();\n\n    return function cancelFn () {\n        clearTimeout(timeoutID);\n        isActive = false;\n    }\n};\n
['Recursion', 'JavaScript']