On Monday 05 October 2009 16:07:50 Nathan Davis wrote:
> 1. You really should use a consistent naming convention -- either call the
> decorators blockingProducer and transformGenComponent or BlockingProducer
> and TransformGenComponent.

This is currently a sketch - basically a proof of concept, written when I had 
time.

In this case concept comes first, followed by an implementation. Point is 
taken though :-) Suggestions for better names welcome. (As noted before)

This is after all also the point of /Sketches - it's not intended to
be "perfect" or great - just a place to play with ideas until they become
clear whether they're useful or not. It's a place for putting ideas into, in 
concrete form for discussion. It's far easier to point at code after all :)

As you'd expect several things have been renamed on their way out from 
Sketches, along with implementation.

> 2.  What are these decorators supposed to do, exactly?  When would I use
> one over the other?  

blockingProducer wraps a generator that contains calls to blocking operations, 
and generates data, and transforms it into a component that sends the yielded 
values out the default outbox "outbox".

Literally, it results in producer component which uses blocking operations.

Likewise "TransformGenComponent" wraps a generator that performs some 
transformation, and returns a component that has that logic. This is actually 
the more awkward case - because it requires the generator be push and pull.

For example, currently I essentially do this:

            argv = self.argv
            if argv[0] == None:
                argv = (self.Inbox,) + argv[1:]

Which gets passed to this:

    @TransformerGenComponent
    def grep(lines, pattern):
        regex = re.compile(pattern)
        while 1:
            for l in lines():
                if regex.search(l):
                    yield l
        
Resulting in lines() meaning self.Inbox() is called. This means this:
            for l in lines():

Iterates over messages waiting in the component's inbox "inbox". (The yielded 
values get sent out the outbox "outbox").

If instead of this, we created the generator self.Inbox() outside the 
generator like this:

            argv = self.argv
            if argv[0] == None:
                argv = (self.Inbox(),) + argv[1:]

    @TransformerGenComponent
    def grep(lines, pattern):
        regex = re.compile(pattern)
        while 1:
            for l in lines: # Change
                if regex.search(l):
                    yield l

Then the problem here is that as soon as the inbox was empty, self.Inbox() - 
ie "lines" would raise StopIteration, and not be reusable.

Fundamentally, both wrappers are suggested to be used like this:

@wrapper
def someFunction(arg1, otherargs):
     do something, possible iterating over arg1, yielding values

The upshot of this being that this transforms the generator function, so that 
rather than returning a generator, it returns a component, which can then be 
used like any other component.

http://yeoldeclue.com/cgi-bin/blog/blog.cgi?rm=viewpost&nodeid=1254693316

may make this more obvious.

> Adding some descriptive docstrings would go a long way.

It's a proof of concept - there's no way it'd get in the core without doc 
strings :-)

> 3.  Why did you choose to return a factory function for a single class for
> blockingProducer, but return a dynamically generated class for
> TransformGenComponent?

Again, same reason. 4 months ago I couldn't see how to do this sensibly in 
either case. Yesterday it became clear to me that it could be done sensibly, 
and so wrote each version in the most directly obvious way to me at the time.

Obviously there's a schism form an implementation perspective, but from a 
concept perspective, they're equivalent:
   * You decorate a generator function containing your logic
   * The resulting function when called returns a component.
   * The "input generator" callback gets values from the
      component's primary inbox. 
   * The values yielded are sent out the component's primary outbox.

Does that help?

Incidentally, I generally have the viewpoint of "get it working; get it 
working properly/nicely/correctly; make it faster". The stage this code is at 
is "get it working".


Michael.
-- 
http://yeoldeclue.com/blog
http://twitter.com/kamaelian
http://www.kamaelia.org/Home

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"kamaelia" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/kamaelia?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to