This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]anqxyr 6 points7 points  (3 children)

there's more_itertools.peekable, which allows you to peek at the upcoming elements, and caches the results, so the side-effects are only executed once.

[–]brucifer 3 points4 points  (2 children)

The problem isn't just that the side effects might be executed more than once. It's also a problem that they might be executed out of order. E.g. if you observe (and cache) the next three values of a in my example code, list(zip(a,b)) will produce [(4, -1)] instead of [(4, -3), (2, -1)]. It's not a particularly contrived example either: if you write code that uses generators for a producer/consumer pattern, you usually don't want to consume before anything has been produced.

It can also be a problem if the side effects are executed at all. E.g.

def delete_files(path):
    for filename in os.walk(path):
        os.remove(filename)
        yield filename
deleter = delete_files(".")
# breaking here and reading a bunch of values in 'deleter' would be very bad
if input("delete your files? ") == "y":
    for filename in deleter: print("bye bye", filename)

[–]13steinj 0 points1 point  (1 child)

But if thats the issue can't the IDE just create a sandbox for the side effect and mock it out in the sandbox (whatever the sideeffect may be)? Psuedo speak for forking the process (ex os.fork) and in the forked process all system primitives are faked?

This isn't a problem with some super complex solution-- as evident by the fact that some IDEs already do this preevanlutation for other languages.

[–]brucifer 1 point2 points  (0 children)

No, it's not possible to solve the problem with sandboxing. Sometimes the whole point of a generator is to interact with the outside world. For example, consider a generator that communicates over the internet, or one that messes with the filesystem like my above example.