[Python-Dev] Re: anonymous blocks
Josiah Carlson wrote: See the previous two discussions on thunks here on python-dev, and notice how the only problem that seem bettered via blocks/thunks /in Python/ are those which are of the form... #setup try: block finally: #finalization ... and depending on the syntax, properties. I once asked Any other use cases for one of the most powerful features of Ruby, in Python? I have yet to hear any sort of reasonable response. Why am I getting no response to my question? Either it is because I am being ignored, or no one has taken the time to translate one of these 'killer features' from Smalltalk or Ruby, or perhaps such translations show that there is a better way in Python already. for my purposes, I've found that the #1 callback killer in contemporary Python is for-in:s support for the iterator protocol: instead of def callback(x): code dosomething(callback) or with the high-level intent-oriented syntax: dosomething(**): def libraryspecifiedargumentname(x): code I simply write for x in dosomething(): code and get shorter code that runs faster. (see cElementTree's iterparse for an excellent example. for typical use cases, it's nearly three times faster than pyexpat, which is the fastest callback-based XML parser we have) unfortunately, def do(): print setup try: yield None finally: print tear down doesn't quite work (if it did, all you would need is syntactic sugar for for dummy in). /F PS. a side effect of the for-in pattern is that I'm beginning to feel that Python might need a nice switch statement based on dictionary lookups, so I can replace multiple callbacks with a single loop body, without writing too many if/elif clauses. ___ 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
[Python-Dev] Re: Re: anonymous blocks
Shane Hathaway wrote: Brian's suggestion makes the code read more like an outline. In Brian's example, the high-level intent stands out from the details that assumes that when you call a library function, the high-level intent of *your* code is obvious from the function name in the library, and to some extent, by the argument names chosen by the library implementor. I'm not so sure that's always a valid assumption. while in your example, there is no visual cue that distinguishes the details from the intent. carefully chosen function names (that you chose yourself) plus blank lines can help with that. Of course, lambdas are even better, when it's possible to use them: doFoo((lambda a, b: a + b), (lambda c, d: c + d)) that only tells you that you're calling doFoo, with no clues whatsoever to what the code in the lambdas are doing. keyword arguments are a step up from that, as long as your intent matches the library writers intent. /F ___ 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
Re: [Python-Dev] Re: anonymous blocks (off topic: match)
PS. a side effect of the for-in pattern is that I'm beginning to feel that Python might need a nice switch statement based on dictionary lookups, so I can replace multiple callbacks with a single loop body, without writing too many if/elif clauses. That's funny. I keep wondering if match from the ML world would make sense in Python. I keep thinking it'd be a really nice thing to have. -jj -- I have decided to switch to Gmail, but messages to my Yahoo account will still get through. ___ 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
Re: [Python-Dev] anonymous blocks
On 4/19/05, Brian Sabbey [EMAIL PROTECTED] wrote: Guido van Rossum wrote: @acquire(myLock): code code code It would certainly solve the problem of which keyword to use! :-) And I think the syntax isn't even ambiguous -- the trailing colon distinguishes this from the function decorator syntax. I guess it would morph '@xxx' into user-defined-keyword. Hmm, this looks to me like a natural extension of decorators. Whether that is a good or a bad thing, I'm unable to decide :-) [I can think of a number of uses for it, PEP 310-style with-blocks being one, but I can't decide if lots of potential uses is too close to lots of potential for abuse :-)] How would acquire be defined? I guess it could be this, returning a function that takes a callable as an argument just like other decorators: def acquire(aLock): def acquirer(block): aLock.acquire() try: block() finally: aLock.release() return acquirer It really has to be this, IMO, otherwise the parallel with decorators becomes confusing, rather than helpful. and the substitution of @EXPR: CODE would become something like def __block(): CODE EXPR(__block) The question of whether assignments within CODE are executed within a new namespace, as this implies, or in the surrounding namespace, remains open. I can see both as reasonable (new namespace = easier to describe/understand, more in line with decorators, probably far easier to implement; surrounding namespace = probably more useful/practical...) Why not have the block automatically be inserted into acquire's argument list? It would probably get annoying to have to define inner functions like that every time one simply wants to use arguments. If this syntax is to be considered, in my view it *must* follow established decorator practice - and that includes the define-an-inner-function-and-return-it idiom. Of course, augmenting the argument list in that way would be different than the behavior of decorators as they are now. Exactly. Paul. ___ 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
[Python-Dev] Re: anonymous blocks
I guess I should begin by introducing myself: My name is Rüdiger Flaig, I live in Heidelberg/Germany (yes indeed, there are not only tourists there) and am a JOAT by profession (Jack Of All Trades). Among other weird things, I am currently teaching immunology and bioinformatics at the once-famous University of Heidelberg. Into this little secluded world of ours, so far dominated by rigid C++ stalwarts, I have successfully introduced Python! I have been lurking on this list for quite a while, interested to watch the further development of the streaked reptile. As students keep on asking me about the differences between languages and the pros and cons, I think I may claim some familiarity with other languages too, especially Python's self-declared antithesis, Ruby. The recent discussion about anonymous blocks immediately brought Ruby to my mind once more, since -- as you will know -- Ruby does have ABs, and rubynos are very proud of them, as they are generally of their more flexible program structure. However, I have seen lots of Ruby code and do not really feel that this contributes in any way to the expressiveness of the language. Lambdas are handy for very microscopic matters, but in general I think that one of Python's greatest strengths is the way in which its rather rigid layout combines with the overall approach to force coders to disentangle complex operations. So I cannot really see any benefit in ABs... Just the 0.02 of a serpent lover, but maybe someone's interested in hearing something like an outsider's opinion. Cheers, Rüdiger === Chevalier Dr. Dr. Ruediger Marcus Flaig Institute for Immunology University of Heidelberg Im Neuenheimer Feld 305, D-69120 Heidelberg, FRG [EMAIL PROTECTED] Drain you of your sanity, Face the Thing That Should Not Be. -- Diese E-Mail wurde mit http://www.mail-inspector.de verschickt Mail Inspector ist ein kostenloser Service von http://www.is-fun.net Der Absender dieser E-Mail hatte die IP: 129.206.124.135 ___ 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
Re: [Python-Dev] anonymous blocks
On Apr 20, 2005, at 5:43 AM, Paul Moore wrote: and the substitution of @EXPR: CODE would become something like def __block(): CODE EXPR(__block) The question of whether assignments within CODE are executed within a new namespace, as this implies, or in the surrounding namespace, remains open. I can see both as reasonable (new namespace = easier to describe/understand, more in line with decorators, probably far easier to implement; surrounding namespace = probably more useful/practical...) If it was possible to assign to a variable to a variable bound outside your function, but still in your lexical scope, I think it would fix this issue. That's always something I've thought should be possible, anyways. I propose to make it possible via a declaration similar to 'global'. E.g. (stupid example, but it demonstrates the syntax): def f(): count = 0 def addCount(): lexical count count += 1 assert count == 0 addCount() assert count == 1 Then, there's two choices for the block decorator: either automatically mark all variable names in the immediately surrounding scope lexical, or don't. Both of those choices are still consistent with the block just being a normal function, which I think is an important attribute. James ___ 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
Re: [Python-Dev] Re: anonymous blocks
On Wed, Apr 20, 2005, [EMAIL PROTECTED] wrote: As students keep on asking me about the differences between languages and the pros and cons, I think I may claim some familiarity with other languages too, especially Python's self-declared antithesis, Ruby. That seems a little odd to me. To the extent that Python has an antithesis, it would be either C++ or Perl. Ruby is antithetical to some of Python's core ideology because it borrows from Perl, but Ruby is much more similar to Python than Perl is. -- Aahz ([EMAIL PROTECTED]) * http://www.pythoncraft.com/ The joy of coding Python should be in seeing short, concise, readable classes that express a lot of action in a small amount of clear code -- not in reams of trivial code that bores the reader to death. --GvR ___ 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
Re: [Python-Dev] Re: anonymous blocks
On Wed, Apr 20, 2005 at 08:18:11AM -0700, Aahz wrote: antithesis, it would be either C++ or Perl. Ruby is antithetical to some of Python's core ideology because it borrows from Perl, but Ruby is much more similar to Python than Perl is. I'm not that familiar with the Ruby community; might it be that they consider Ruby to be Python's antithesis, in that it returns to bracketing instead of Python's indentation? --amk ___ 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
Re: [Python-Dev] anonymous blocks
Aahz wrote: On Tue, Apr 19, 2005, Shane Holloway (IEEE) wrote: However, my opinion is that it does not read smoothly. This form requires that I say what I'm doing with something before I know the context of what that something is. For me, blocks are not about shortening the code, but rather clarifying *intent*. H How is this different from defining functions before they're called? It's not. In a function scope I'd prefer to read top-down. When I write classes, I tend to put the public methods at the top. Utility methods used by those entry points are placed toward the bottom. In this way, I read the context of what I'm doing first, and then the details of the internal methods as I need to understand them. Granted I could achieve this effect with:: class Before: def readIt(self, filename): def readIt(): withFile(filename, doReading) def doReading(aFile): self.readPartA(aFile) self.readPartB(aFile) self.readPartC(aFile) return readIt() Which is fine with me, but the *intent* is more obfuscated than what the block construct offers. And I don't think my crew would appreciate if I did this very often. ;) ___ 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
[Python-Dev] Newish test failures
Seeing three seemingly related test failures today, on CVS HEAD: test_csv test test_csv failed -- errors occurred; run in verbose mode for details test_descr test test_descr crashed -- exceptions.AttributeError: attribute '__dict__' of 'type' objects is not writable test_file test test_file crashed -- exceptions.AttributeError: attribute 'closed' of 'file' objects is not writable 3 tests failed: test_csv test_descr test_file Drilling into test_csv: ERROR: test_reader_attrs (test.test_csv.Test_Csv) -- Traceback (most recent call last): File C:\Code\python\lib\test\test_csv.py, line 62, in test_reader_attrs self._test_default_attrs(csv.reader, []) File C:\Code\python\lib\test\test_csv.py, line 58, in _test_default_attrs self.assertRaises(TypeError, delattr, obj.dialect, 'quoting') File C:\Code\python\lib\unittest.py, line 320, in failUnlessRaises callableObj(*args, **kwargs) AttributeError: attribute 'quoting' of '_csv.Dialect' objects is not writable == ERROR: test_writer_attrs (test.test_csv.Test_Csv) -- Traceback (most recent call last): File C:\Code\python\lib\test\test_csv.py, line 65, in test_writer_attrs self._test_default_attrs(csv.writer, StringIO()) File C:\Code\python\lib\test\test_csv.py, line 58, in _test_default_attrs self.assertRaises(TypeError, delattr, obj.dialect, 'quoting') File C:\Code\python\lib\unittest.py, line 320, in failUnlessRaises callableObj(*args, **kwargs) AttributeError: attribute 'quoting' of '_csv.Dialect' objects is not writable ___ 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
Re: [Python-Dev] anonymous blocks
[Shane Holloway] When I write classes, I tend to put the public methods at the top. Utility methods used by those entry points are placed toward the bottom. In this way, I read the context of what I'm doing first, and then the details of the internal methods as I need to understand them. Granted I could achieve this effect with:: class Before: def readIt(self, filename): def readIt(): withFile(filename, doReading) def doReading(aFile): self.readPartA(aFile) self.readPartB(aFile) self.readPartC(aFile) return readIt() Which is fine with me, but the *intent* is more obfuscated than what the block construct offers. And I don't think my crew would appreciate if I did this very often. ;) I typically solve that by making doReading() a method: class Before: def readit(self, filename): withFile(filename, self._doReading) def _doReading(self, aFile): self.readPartA(aFile) self.readPartB(aFile) self.readPartC(aFile) Perhaps not as Pure, but certainly Practical. :-) And you could even use __doReading to make it absolutely clear that doReading is a local artefact, if you care about such things. -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ 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
Re: [Python-Dev] Proper place to put extra args for building
Martin v. Lwis wrote: Brett C. wrote: I am currently adding some code for a Py_COMPILER_DEBUG build for use on the AST branch. I thought that OPT was the proper variable to put stuff like this into for building (``-DPy_COMPILER_DEBUG``), but that erases ``-g -Wall -Wstrict-prototypes``. Obviously I could just tack all of that into my own thing, but that seems like an unneeded step. Actually, this step is needed. Damn. OK. [SNIP] It might be reasonable to add a variable that will just take additional compiler flags, and never be modified in configure. The other option is to not make configure.in skip injecting arguments when a pydebug build is done based on whether OPT is defined in the environment. So configure.in:670 could change to ``OPT=$OPT -g -Wall -Wstrict-prototypes``. The line for a non-debug build could stay as-is since if people are bothering to tweak those settings for a normal build they are going out of there way to tweak settings. Seems like special-casing this for pydebug builds makes sense since the default values will almost always be desired for a pydebug build. And those rare cases you don't want them you could just edit the generated Makefile by hand. Besides it just makes our lives easier and the special builds even more usual since it is one less thing to have to tweak. Sound reasonable? -Brett ___ 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
Re: [Python-Dev] Proper place to put extra args for building
Brett C. wrote: The other option is to not make configure.in skip injecting arguments when a pydebug build is done based on whether OPT is defined in the environment. So configure.in:670 could change to ``OPT=$OPT -g -Wall -Wstrict-prototypes``. That's a procedural question: do we want to accept environment settings only when running configure, or do we also want to honor environment or make command line settings when make is invoked. IOW, it is ok if export OPT=-O6 ./configure make works. But what about ./configure export OPT=-O6 make or ./configure make OPT=-O6 All three can be only supported for environment variables that are never explicitly set in Makefile, be it explicitly in Makefile.pre.in, or implicitly through configure. The line for a non-debug build could stay as-is since if people are bothering to tweak those settings for a normal build they are going out of there way to tweak settings. Seems like special-casing this for pydebug builds makes sense since the default values will almost always be desired for a pydebug build. And those rare cases you don't want them you could just edit the generated Makefile by hand. Besides it just makes our lives easier and the special builds even more usual since it is one less thing to have to tweak. Sound reasonable? No. I thought you were talking about extra args, such as -fbrett-cannon. But now you seem to be talking about arguments that replace the ones that configure comes up with. Either of these might be reasonable, but they require different treatment. Replacing configure results is possible already ___ 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
Re: [Python-Dev] Proper place to put extra args for building
Martin v. Lwis wrote: Brett C. wrote: The other option is to not make configure.in skip injecting arguments when a pydebug build is done based on whether OPT is defined in the environment. So configure.in:670 could change to ``OPT=$OPT -g -Wall -Wstrict-prototypes``. That's a procedural question: do we want to accept environment settings only when running configure, or do we also want to honor environment or make command line settings when make is invoked. IOW, it is ok if export OPT=-O6 ./configure make works. But what about ./configure export OPT=-O6 make or ./configure make OPT=-O6 All three can be only supported for environment variables that are never explicitly set in Makefile, be it explicitly in Makefile.pre.in, or implicitly through configure. Hmm. OK, that is an interesting idea. Would make rebuilding a lot easier if it was just an environment variable that was part of the default OPT value; ``OPT=$BUILDFLAGS -g -Wall -Wstrict-prototyping. I say we go with that. What is a good name, though? PY_OPT? The line for a non-debug build could stay as-is since if people are bothering to tweak those settings for a normal build they are going out of there way to tweak settings. Seems like special-casing this for pydebug builds makes sense since the default values will almost always be desired for a pydebug build. And those rare cases you don't want them you could just edit the generated Makefile by hand. Besides it just makes our lives easier and the special builds even more usual since it is one less thing to have to tweak. Sound reasonable? No. I thought you were talking about extra args, such as -fbrett-cannon. I am, specifically ``-DPy_COMPILER_DEBUG`` to be tacked on as a flag to gcc. But now you seem to be talking about arguments that replace the ones that configure comes up with. Either of these might be reasonable, but they require different treatment. Replacing configure results is possible already I am only talking about that because that is how OPT is currently structured; configure.in replaces the defaults with what the user provides if the environment variable is set. This is what I don't want. ___ 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
[Python-Dev] Re: switch statement
Fredrik Lundh wrote: PS. a side effect of the for-in pattern is that I'm beginning to feel that Python might need a nice switch statement based on dictionary lookups, so I can replace multiple callbacks with a single loop body, without writing too many if/elif clauses. PEP 275 anyone ? (http://www.python.org/peps/pep-0275.html) My use case for switch is that of a parser switching on tokens. mxTextTools applications would greatly benefit from being able to branch on tokens quickly. Currently, there's only callbacks, dict-to-method branching or long if-elif-elif-...-elif-else. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Apr 20 2005) Python/Zope Consulting and Support ...http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ...http://python.egenix.com/ ::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,FreeBSD for free ! ___ 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
Re: [Python-Dev] Re: switch statement
On 4/20/05, M.-A. Lemburg [EMAIL PROTECTED] wrote: Fredrik Lundh wrote: PS. a side effect of the for-in pattern is that I'm beginning to feel that Python might need a nice switch statement based on dictionary lookups, so I can replace multiple callbacks with a single loop body, without writing too many if/elif clauses. PEP 275 anyone ? (http://www.python.org/peps/pep-0275.html) My use case for switch is that of a parser switching on tokens. mxTextTools applications would greatly benefit from being able to branch on tokens quickly. Currently, there's only callbacks, dict-to-method branching or long if-elif-elif-...-elif-else. I think match from Ocaml would be a much nicer addition to Python than switch from C. -jj -- I have decided to switch to Gmail, but messages to my Yahoo account will still get through. ___ 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
Re: [Python-Dev] Reference counting when entering and exiting scopes
Matthew F. Barnes wrote: Someone on python-help suggested that I forward this question to python-dev. I've been studying Python's core compiler and bytecode interpreter as a model for my own interpreted language, Might want to take a peek at the AST branch in CVS; that is what the compiler is going to change to as soon as it is complete. and I've come across what appears to be a reference counting problem in the `symtable_exit_scope' function in Python/compile.c. At this point I assume that I'm just misunderstanding what's going on. So I was hoping to contact one of the core developers before I go filing what could very well be a spurious bug report against Python's core. Spurious bug reports are fine. If they turn out to be that they get closed as such. Either way time is spent checking it whether it goes there or here. But at least with a bug report it can be tracked more easily. So for future reference, just go ahead and file the bug report. Here's the function copied from CVS HEAD: static int symtable_exit_scope(struct symtable *st) { int end; if (st-st_pass == 1) symtable_update_free_vars(st); Py_DECREF(st-st_cur); end = PyList_GET_SIZE(st-st_stack) - 1; st-st_cur = (PySymtableEntryObject *)PyList_GET_ITEM(st-st_stack, end); if (PySequence_DelItem(st-st_stack, end) 0) return -1; return 0; } My issue is with the use of PyList_GET_ITEM to fetch a new value for the current scope. As I understand it, PyList_GET_ITEM does not increment the reference count for the returned value. So in effect we're borrowing the reference to the symtable entry object from the tail of the scope stack. But then we turn around and delete the object from the tail of the scope stack, which DOES decrement the reference count. So `symtable_exit_scope' has a net effect of decrementing the reference count of the new current symtable entry object, when it seems to me like it should stay the same. Shouldn't the reference count be incremented when we assign to st-st_cur (either explicitly or by fetching the object using the PySequence API instead of PyList)? Can someone explain the rationale here? If you look at how symtable_enter_scope() and symtable_exit_scope() work together you will notice there is actually no leak. symtable_enter_scope() appends the existing PySymtableEntryObject on to the symtable stack and then places a new PySymtableEntryObject into st-st_cur. Both at this point have a refcount of one; enough to stay alive. Now look at symtable_exit_scope(). When the current PySymtableEntryObject is no longer needed, it is DECREF'ed, putting it at 0 and thus leading to eventual collection. What is on top of the symtable stack, which has a refcount of 1 still, is then put in to st-st_cur. So no leak. Yes, there should be more explicit refcounting to be proper, but the compiler cheats in a couple of places for various reasons. But basically everything is fine since st-st_cur and st-st_stack are only played with refcount-wise by either symtable_enter_scope() and symtable_exit_scope() and they are always called in pairs in the end. -Brett ___ 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
Re: [Python-Dev] anonymous blocks
Alex Martelli wrote: def withfile(filename, mode='r'): openfile = open(filename, mode) try: block(thefile=openfile) finally: openfile.close() i.e., let the block take keyword arguments to tweak its namespace I don't think I like that idea, because it means that from the point of view of the user of withfile, the name 'thefile' magically appears in the namespace without it being obvious where it comes from. (but assignments within the block should still affect its _surrounding_ namespace, it seems to me...). I agree with that much. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ 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
Re: [Python-Dev] anonymous blocks
Josiah Carlson wrote: I once asked Any other use cases for one of the most powerful features of Ruby, in Python? I have yet to hear any sort of reasonable response. Why am I getting no response to my question? Either it is because I am being ignored, or no one has taken the time to translate one of these 'killer features' from Smalltalk or Ruby, or perhaps such translations show that there is a better way in Python already. My feeling is that it's the latter. I don't know about Ruby, but in Smalltalk, block-passing is used so heavily because it's the main way of implementing control structures there. While-loops, for-loops, even if-then-else, are not built into the language, but are implemented by methods that take block parameters. In Python, most of these are taken care of by built-in statements, or various uses of iterators and generators. There isn't all that much left that people want to do on a regular basis. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ 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
Re: [Python-Dev] anonymous blocks
Steven Bethard wrote: Of course, even with the unpack list, you still have to know what kind of arguments the function calls your block with. And because these only appear within the code, e.g. block(openfile) you can't rely on easily accessible things like the function's signature. You can't rely on a function's signature alone to tell you much in any case. A distressingly large number of functions found in third-party extension modules have a help() string that just says something like fooble(arg,...) There's really no substitute for a good docstring! -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ 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
Re: [Python-Dev] anonymous blocks
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. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ 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
Re: [Python-Dev] Proper place to put extra args for building
Brett C. wrote: Hmm. OK, that is an interesting idea. Would make rebuilding a lot easier if it was just an environment variable that was part of the default OPT value; ``OPT=$BUILDFLAGS -g -Wall -Wstrict-prototyping. I say we go with that. What is a good name, though? PY_OPT? I think EXTRA_CFLAGS is common, and it would not specifically be part of OPT, but rather of CFLAGS. I am only talking about that because that is how OPT is currently structured; configure.in replaces the defaults with what the user provides if the environment variable is set. This is what I don't want. The question is whether the user is supposed to provide a value for OPT in the first place. OPT is a set of flag that (IMO) should control the optimization level of the compiler, which, in the wider sense, also includes the question whether debug information should be generated. It should be possible to link object files compiled with different OPT settings, so flags that will give binary-incompatible object files should not be in OPT. It might be desirable to allow the user to override OPT, e.g. to specify that the compiler should not use -O3 but, say, -O1. I don't think there is much point in allowing OPT to be extended. But then, it is already possible to override OPT (when invoking make), which might be enough control. Regards, Martin ___ 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
Re: [Python-Dev] anonymous blocks
Greg Ewing wrote: Steven Bethard wrote: Of course, even with the unpack list, you still have to know what kind of arguments the function calls your block with. And because these only appear within the code, e.g. block(openfile) you can't rely on easily accessible things like the function's signature. You can't rely on a function's signature alone to tell you much in any case. A distressingly large number of functions found in third-party extension modules have a help() string that just says something like fooble(arg,...) There's really no substitute for a good docstring! True enough. But the point still stands. Currently, if we describe a function's input (parameters) and output (return value), we can basically fully document the function (given a thorough enough description of course).[1] Functions that accept thunks/blocks require documentation for an additional piece of information that is not part of the input or output of the function: the parameters with which the thunk/block is called. So while: fooble(arg) is pretty nasty, documentation that tells me that 'arg' is a string is probably enough to set me on the right track. But if the documentation tells me that arg is a thunk/block, that's almost certainly not enough to get me going. I also need to know how that thunk/block will be called. True, if arg is not a thunk/block, but another type of callable, I may still need to know how it will be called. But I think with non thunks/blocks, there are a lot of cases where this is not necessary. Consider the variety of decorator recipes.[2] Most don't document what parameters the wrapped function will be called with because they simply pass all arguments on through with *args and **kwargs. Thus the wrapped function will take the same parameters as the original function did. Or if they're different, they're often a relatively simple modification of the original function's parameters, ala classmethod or staticmethod. But thunks/blocks don't work this way. They're not wrapping a function that already takes arguments. They're wrapping a code block that doesn't. So they certainly can't omit the parameter description entirely, and they can't even describe it in terms of a modification to an already existing set of parameters. Because the parameters passed from a thunk/block-accepting function to a thunk are generated by the function itself, all the parameter documentation must be contained within the thunk/block-accepting function. It's not like it's the end of the world of course. ;-) I can certainly learn to document my thunks/blocks thoroughly. I just think it's worth noting that there *would* be a learning process because there are additional pieces of information I'm not used to having to document. STeVe [1] I'm ignoring the issue of functions that modify parameters or globals, but this would also be required for thunks/blocks, so I don't think it detracts from the argument. [2] Probably worth noting that a very large portion of the functions I've written that accepted other functions as parameters were decorators. I lean towards a fairly OO style of programming, so I don't pass around a lot of callbacks. Presumably someone who relies heavily on callbacks would be much more used to documenting the parameters with which a function is called. Still, I think there is probably a large enough group that has similar style to mine that my argument is still valid. -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy ___ 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