Shane Holloway (IEEE) wrote:
class After: def readIt(self, filename): withFile(filename): self.readPartA(aFile) self.readPartB(aFile) self.readPartC(aFile)
In my opinion, this is much smoother to read. This particular example brings up the question of how arguments like "aFile" get passed and named into the block. I anticipate the need for a place to put an argument declaration list. ;)
My current thought is that it should look like this:
with_file(filename) as f: do_something_with(f)
The success of this hinges on how many use cases can be arranged so that the word 'as' makes sense in that position. What we need is a corpus of use cases so we can try out different phrasings on them and see what looks the best for the most cases.
I also have a thought concerning whether the block argument to the function should come first or last or whatever. My solution is that the function should take exactly *one* argument, which is the block. Any other arguments are dealt with by currying. In other words, with_file above would be defined as
def with_file(filename): def func(block): f = open(filename) try: block(f) finally: f.close() return func
This would also make implementation much easier. The parser isn't going to know that it's dealing with anything other than a normal expression statement until it gets to the 'as' or ':', by which time going back and radically re-interpreting a previous function call could be awkward. This way, the syntax is just
expr ['as' assignment_target] ':' suite
and the expr is evaluated quite normally.
Another set of question arose for me when Barry started musing over the combination of blocks and decorators. What are blocks? Well, obviously they are callable. What do they return? The local namespace they created/modified?
I think the return value of a block should be None. In constructs like with_file, the block is being used for its side effect, not to compute a value for consumption by the block function. I don't see a great need for blocks to be able to return values.
How do blocks work with control flow statements like "break", "continue", "yield", and "return"? Perhaps "break" and "continue" raise exceptions similar to StopIteration in this case?
Something like that, yes.