On Fri, Feb 19, 2010 at 9:21 AM, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@remove-this-cybersource.com.au">steve@remove-this-cybersource.com.au</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im">On Fri, 19 Feb 2010 09:51:54 -0600, Robert Kern wrote:<br></div><div class="im">
>> But he doesn't say anything about side-effects.<br>
><br>
> "I have some generators *that do stuff*, then start yielding results."<br>
</div>> [emphasis mine].<br>
<br>
What does "do stuff" have to do with side-effects? Here's a generator<br>
that does stuff, and it has no side-effects.<br>
<br>
def generator_that_does_stuff(x):<br>
    y = 3*x**2 - 5*x + 1<br>
    yield y<br>
<br>
"Do stuff" is ambiguous -- it could mean stuff with side-effects, or<br>
stuff without. The first is potentially harmful, the second is pointless.</blockquote><div><br></div><div>What does it matter what *do stuff* means? My point is, there's *stuff* I need to do there, and what that stuff is really has absolutely nothing to do with the issue at hand. Its certainly a side-effect, at least in terms of the generator, otherwise there would be no point really in having the generator there at all.</div>

<div><br></div><div>I have a system that consumes generators which, almost always, yield over objects to be handled. One in ten-- nay, one in 20, if not worse-- cases has me wanting to inject into this system some arbitrary code that gets run. Some bit of processing I need to get done in the context of that cycle.</div>

<div><br></div><div>There's nothing harmful about it. These aren't generic generators that are going to be passed around and consumed by random things or anything else. They exist solely to be consumed by the core system. They're never composed or loaded by anything else, its just the API of how the system works. It loads bunches of modules dynamically, each module has a generator for yielding objects to be consumed. That generator is the one and only line of connection between the core system and the modules.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">> Then he gives an example of a generator that does<br>
> side-effect stuff and returning before yielding anything.<br>
<br>
</div>Unfortunately the OP's original post isn't visible to me, so I can only<br>
respond to your post, which may or may not quote the entire original post.<br>
<br>
The only example I have seen was an empty generator with a comment saying<br>
"do my one-time processing here", with *no* indication of what that one-<br>
time processing is supposed to be, why it is necessary, and whether it<br>
has side-effects or not.<br></blockquote><div><br></div><div>It doesn't matter what the one-time processing is supposed to be. I could say, "This particular module doesn't yield objects like all the rest, but instead just needs to override a certain utility function the system uses, to change how name equality is handled so that tests compare on normalized forms. The API for integrating into the the core system -- to be loaded as a module and integrated into the system -- is to have a generator of a certain name, which yields N objects. In this case, N = 0.". </div>

<div><br></div><div>Now, having said that, why in the world does that matter at all to my question? :) It changes no part of anyone's possible solution, be it Robert's once-wrapped-to-decorator, to Holden's just-comment-the-oddity, to your empty-for-loop-yield, to any others.</div>

<div><br></div><div>It doesn't *matter* what the processing has to be. And if it has side-effects or not is only relevant to the question of the perversity of my use-case, a discussion I just don't really even have any interest in =) </div>

<div><br></div><div>Thanks, all, though, for your responses and solutions.</div><div><br></div><div>Much to my embarrassment, sometime last night I realized I was being a complete idiot, and the 'correct' way to handle this in my scenario is really just:</div>

<div><br></div><div>def initialize():</div><div>    # do one time processing here</div><div><br></div><div>    return []</div><div><br></div><div>A generator is just a callable that returns an iterator, after all. If I don't want to yield anything, returning an empty iterable accomplishes the same goal to get the code loaded and run by the host-cycle while contributing nothing at all to the object pool.</div>

<div><br></div></div><div name="mailplane_signature">--S</div>