These are chat archives for evhub/coconut

Sep 2016
Chuck Daniels
Sep 12 2016 21:07
@evhub I’ve been looking at your example fib recursive iterator in your docs on the develop branch, and thus at the implementation of recursive_iterator. Very interesting, and I’m still trying to wrap my head around it. As an experiment, I played around with calling fib without the decorator a number of times, and noticed significant slowdown after about 20+ calls. With the decorated fib function, I saw no such slowdown, so the decorator is very handy indeed for such situations! However, in looking at the implementation of recursive_iterator, correct me if I’m wrong (which may very well be the case since this is all rather mind-bending), but won’t independent calls to the same function using the same arguments interfere with each other? For example, if I call fib from someplace in my code (and iterate a few times), and then call it again from some other place in my code (i.e., another top-level call, not a recursive call), won’t my second call produce an iterator that picks up where my first iterator left off? In fact, won’t this be the case even for different functions to which the same arguments (in this case, no arguments) are passed? In other words, it appears to me that the decorator function is only memoizing based upon the arguments passed to the decorated function, so isn’t this highly likely to cause problems?
@evhub Silly me, I just answered my own question by experimentation, and no such interference occurs. So my question then becomes, how does this black magic work? :-)
Chuck Daniels
Sep 12 2016 21:24
@evhub Mind blown. I think I just realized what you’re doing with the tees in the recursive_iterator function. Absolutely brilliant!
Evan Hubinger
Sep 12 2016 22:57
@chuckwondo Glad you appreciate my code! You're right, though, it is very much black magic. I think you get the idea, but I'll try my best to explain it. Underneath the hood, recursive_iterator keeps a dictionary that maps function arguments to a tee created from calling the underlying function with those arguments. When the decorated function is called again with the same arguments, a new tee is created by copying the tee stored in the dictionary, and that is returned instead of calling the underlying function again.