Skip to content

Instantly share code, notes, and snippets.

@lagagain
Last active January 31, 2021 01:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lagagain/6b50954e5d088095dbd991a8b00163a0 to your computer and use it in GitHub Desktop.
Save lagagain/6b50954e5d088095dbd991a8b00163a0 to your computer and use it in GitHub Desktop.
callme
call.exec = true;
call.toc = true;
call(callme, 1);
function callme(i) {
if (i < 0) return i;
console.log(i);
return call(callme, i + 1);
}
// function call(fn, ...args) {
// let callable = {fn, args};
// callable.__proto__ = call.prototype;
// return callable;
// }
//
// function TCO(result) {
// while(result instanceof call){
// let {fn, args} = result;
// result = fn(...args);
// }
// return result;
// }
//
// TCO(callme(1))
function call(fn, ...args) {
if(call.exec){
if(call.toc) call.exec = false;
let result = fn(...args);
while(result instanceof call){
let {fn, args} = result;
result = fn(...args);
}
console.log(call.exec, call.toc);
call.exec = true;
return result;
} else {
let callable = {fn, args};
callable.__proto__ = call.prototype;
return callable;
}
}
function callme(i) {
if (i < 0) return i;
console.log(i);
return call(callme, i + 1);
}
function call(fn, ...args) {
let callable = {fn, args};
callable.__proto__ = call.prototype;
return callable;
}
function TCO(result) {
while(result instanceof call){
let {fn, args} = result;
result = fn(...args);
}
return result;
}
TCO(callme(1))
class Callable:
def __init__(self, fn, *args, **kargs):
self.fn = fn
self.args = args
self.kargs = kargs
def __call__(self):
return self.fn(*self.args, **self.kargs)
class Context:
def __init__(self):
self.exec = True
def tco(self, fn):
def _fn(*args, **kargs):
if self.exec:
self.exec = False
result = fn(*args, **kargs)
while type(result) == Callable:
result = result()
self.exec = True
return result
else:
return Callable(fn,*args,**kargs)
return _fn
ctx = Context()
@ctx.tco
def callme(i):
if i < 0: return i
print(i)
return callme(i-1)
callme(5)
callme(5)
def callme(i)
return i if i < 0
puts i
return callme i+1
end
# main.rb
RubyVM::InstructionSequence.compile_option = {
tailcall_optimization: true,
trace_instruction: false
}
require './callme.rb'
(callme 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment