3 ms·
I in the distant past when I was still in Uni attempted to do something similar, though I never finished it. I think I should take up my project again and try t
by kosievdmerwe 11y ago
I in the distant past when I was still in Uni attempted to do something similar, though I never finished it. I think I should take up my project again and try to finish it this time. I got stuck last time trying to figure out how to do a try/catch.
The one big thing I notice this is doing "wrong", is that it is not linear in recursion depth: Each statement increases the stack depth by 1. The way around this is to instead sequence the commands using arrays, since python guarantees the execution order is left to right. So his example could have been rewritten as:
(lambda s: [s.__setitem__('x', 3), s.__setitem__('y', 4), print(s['x'] < s['y'] < 5)])({})
(though for this example you could just modify the result of globals())
Then you can also do trickery to get for and while loops into generator expressions as opposed to lambdas. The hard part is handling continues and breaks. For instance:
while <cond>:
<stmts>
can get compiled into something like
list(<compiled_stmts> for _ in itertools.takewhile(lambda _: <compiled_cond>, itertools.cycle([1])))
(though you'll want to replace list with a function that evaluates the iterator but doesn't take up O(N) space where N is the number of iterations, something like a no-op accumulator)
To handle breaks and continues, you'd have to make your <compiled_stmts> be aware that a break/continue was called (a flag on some meta table was my plan), so they can terminate early. You'd also have to change <compiled_cond> to terminate the loop (on a break) and reset the continue flag.