Hacker News new | past | comments | ask | show | jobs | submit login

Generators can restore you to any point in the control flow, whereas your closure-based solution (or an object-oriented solution where variables are class fields) always has to start from the top of the send() function. For simple examples, closures can present an easy alternative implementation.

But here's an example where you need to do a lot of extra work with a closure. It reads a file with '#' style comments, separates comment from non-comment strings, and keeps track of a few counters which a caller in the same file can access as global variables (technically "module-level" variables in Python).

    comments = 0
    uncommented_lines = 0
    commented_lines = 0

    def tokenize_comments(src):
        # Point A
        for line in src:
            p = line.find('#')
            if p < 0:
                yield line
                #Point B
                uncommented_lines += 1
            else:
                yield line[:p]
                #Point C
                comments += 1
                yield line[p:]
                #Point D
                commented_lines += 1
            #Point E
        return
Try to write a functionally identical implementation of this code with closures that preserves the behavior of the counters.

The API could be much improved, for example, we might want to wrap this in a class to get rid of those global variables. But that's not the point. The point is that rewriting functionally equivalent code will require you to keep track of whether the code is at Point A, B, C, or D.

I purposely included the counters in this example to make it impossible to unify different control paths, which would make a closure-based implementation a lot easier. For example, if it wasn't for the counters, points B, D, and E would be identical.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: