Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circular Programming in Python (corecursion) - is it possible?

Tags:

python

I know Python has some lazy implementations, and as such, I was wondering if it is possible to use circular programming in Python.

If it isn't, why?

like image 249
Edward Coelho Avatar asked Jan 20 '26 02:01

Edward Coelho


1 Answers

I think you mean co-routines, not co-recursion. Yes, it's perfectly possible in Python, since PEP 342: Coroutines via Enhanced Generators has been implemented.

The canonical example is the consumer decorator:

def consumer(func):
    def wrapper(*args,**kw):
        gen = func(*args, **kw)
        next(gen)
        return gen
    wrapper.__name__ = func.__name__
    wrapper.__dict__ = func.__dict__
    wrapper.__doc__  = func.__doc__
    return wrapper

Using such consumer then let's you chain filters and push information through them, acting as a pipeline:

from itertools import product

@consumer
def thumbnail_pager(pagesize, thumbsize, destination):
    while True:
        page = new_image(pagesize)
        rows, columns = pagesize / thumbsize
        pending = False
        try:
            for row, column in product(range(rows), range(columns)):
                thumb = create_thumbnail((yield), thumbsize)
                page.write(
                    thumb, col * thumbsize.x, row * thumbsize.y
                )
                pending = True
        except GeneratorExit:
            # close() was called, so flush any pending output
            if pending:
                destination.send(page)

            # then close the downstream consumer, and exit
            destination.close()
            return
        else:
            # we finished a page full of thumbnails, so send it
            # downstream and keep on looping
            destination.send(page)

@consumer
def jpeg_writer(dirname):
    fileno = 1
    while True:
        filename = os.path.join(dirname,"page%04d.jpg" % fileno)
        write_jpeg((yield), filename)
        fileno += 1


# Put them together to make a function that makes thumbnail
# pages from a list of images and other parameters.      
#
def write_thumbnails(pagesize, thumbsize, images, output_dir):
    pipeline = thumbnail_pager(
        pagesize, thumbsize, jpeg_writer(output_dir)
    )

    for image in images:
        pipeline.send(image)

    pipeline.close()

The central principles are python generators, and yield expressions; the latter lets a generator receive information from a caller.

Edit: Ah, Co-recursion is indeed a different concept. Note that the Wikipedia article uses python for it's examples, and moreover, uses python generators.

like image 138
Martijn Pieters Avatar answered Jan 21 '26 17:01

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!