Guido van Rossum wrote:
PEP 310 forms the basis for a block construct that I _do_ like. The question
then becomes whether or not generators can be used to write useful PEP 310 style
block managers (I think they can, in a style very similar to that of the looping
block construct from PEP 340).


I've read through your example, and I'm not clear why you think this
is better. It's a much more complex API with less power. What's your
use case? Why should 'block' be disallowed from looping? TOOWTDI or do
you have something better?

I'm no longer clear on why I thought what I suggested would be better either. Can I use the 'it was late' excuse? :)


Actually, the real reason is that I hadn't figured out what was really possible with PEP 340. The cases that I thought PEP 310 would handle better, I've since worked out how to do using the PEP 340 mechanism, and PEP 340 handles them _far_ more elegantly. With PEP 340, multi-stage constructs can be handled by using one generator as an argument to the block, and something else (such as a class or another generator) to maintain state between the blocks. The looping nature is a big win, because it lets execution of a contained block be prevented entirely.

My favourite discovery is that PEP 340 can be used to write a switch statement like this:

    block switch(value) as sw:
        block sw.case(1):
            # Handle case 1
        block sw.case(2):
            # Handle case 2
        block sw.default():
            # Handle default case

Given the following definitions:

    class _switch(object):
        def __init__(self, switch_var):
            self.switch_var = switch_var
            self.run_default = True

        def case(self, case_value):
            self.run_default = False
            if self.switch_var == case_value:
                yield

        def default(self):
            if self.run_default:
                yield

    def switch(switch_var):
        yield _switch(switch_var)


With the keyword-less syntax previously mentioned, such a 'custom structure' could look like:


    switch(value) as sw:
        sw.case(1):
            # Handle case 1
        sw.case(2):
            # Handle case 2
        sw.default():
            # Handle default case

(Actually doing a switch using blocks like this would be *insane* for performance reasons, but it is still rather cool that it is possible)

With an appropriate utility block manager PEP 340 can also be used to abstract multi-stage operations. I haven't got a real use case for this as yet, but the potential is definitely there:

def next_stage(itr):
    """Execute a single stage of a multi-stage block manager"""
    arg = None
    next_item = next(itr)
    while True:
        if next_item is StopIteration:
            raise StopIteration
        try:
            arg = yield next_item
        except:
            if not hasattr(itr, "__error__"):
                raise
            next_item = itr.__error__(sys.exc_info()[1])
        else:
            next_item = next(itr, arg)


def multi_stage(): """Code template accepting multiple suites""" # Pre stage 1 result_1 = yield # Post stage 1 yield StopIteration result_2 = 0 if result_1: # Pre stage 2 result_2 = yield # Post stage 2 yield StopIteration for i in range(result_2): # Pre stage 3 result_3 = yield # Post stage 3 yield StopIteration # Pre stage 4 result_4 = yield # Post stage 4

def use_multistage():
    blk = multi_stage()
    block next_stage(blk):
        # Stage 1
        continue val_1
    block next_stage(blk):
        # Stage 2
        continue val_2
    block next_stage(blk):
        # Stage 3
        continue val_3
    block next_stage(blk):
        # Stage 4
        continue val_4

Cheers,
Nick.

--
Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---------------------------------------------------------------
            http://boredomandlaziness.skystorm.net
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to