Another grab-bag of language ideas / wishes. Some of these are items that have been raised before on other lists - I want to get them written down so that they can be rejected quickly :)
1) I don't know if this is already on the table, but I sure would like to be able to have more options as far as mixing positional and keyword arguments. A common case that I run into is where I have a function that takes a variable number of positional arguments, but also takes a couple of optional keyword arguments. What I would like to be able to write is: def function( *args, option=False ): ... # Puts (1, 2, 3) into args, option is False function( 1, 2, 3 ) # Puts (1, 2, 3) into args, option is True function( 1, 2, 3, option=True ) In other words, any non-named arguments would be put into 'args', and the 'option' argument would only be used if explicitly named. However, Python gives me a syntax error when I try this - it wants the *args to appear after all other arguments. But I can't write: def function( option=False, *args ) because now option will be assigned the value '1', and *args will get (2, 3). Generally what I end up having to do is: def function( *args, **kwargs ): option = kwargs.get( 'option', False ) ...which is both clumsy and ugly. 2) A suggestion which I've seen others bring up before is the use of the * operator for tuple packing / unpacking operations, i.e.: a, *b = (1, 2, 3) Yes, I realize that you can also do: a, b = v[ 0 ], v[ 1: ] or other variations. But it does seem like a logical extension. Note that I'm only proposing this for lists, not dicts -- generalizing the **syntax seems rather less useful. 2a) One particularly useful variation of *list (again, one which I have brought up before, as have others), is the "yield *" syntax. The primary use case is for chained generators, that is a generator that is yielding the output of multiple sub-generators. Here is an example where we have a list of patterns which we want to check against all of the nodes of a tree, and yield all matching results. Each tree node has a 'left' and 'right' attribute. def search( pattern_list, tree ): for pattern in pattern_list: if pattern.match( tree.name ): yield tree if tree.left for result in search( pattern_list, tree.left ): yield result if tree.rght: for result in search( pattern_list, tree.right ): yield result What's pessimal about this is that each result has to bubble up the stack - so if you are checking a node that is 6 levels down the tree, each value gets yielded 6 times, and the execution context gets changed 12 times - 6 times going up the stack and 6 times coming back down again. What I'd like to write instead would be: def search( pattern_list, tree ): for pattern in pattern_list: if pattern.match( tree.name ): yield tree if tree.left yield *search( pattern_list, tree.left ) yield *search( pattern_list, tree.right ) The 'yield *' syntax basically means 'yield all of the values from the specified iterator, one at a time.' Ideally, this would be implemented via a "short-circuit", such that the output of the lowest-level generator was feeding results directly into the final consumer. In other words, the consumer would be temporarily redirected to consume values directly from the innermost iterator, and when that iteration was complete, the consumer's connection to the original iterator would be restored. (I suspect that the new yield behavior in 2.5 could be used to solve this problem in a different way, however at this point I'm not clever enough to be able to figure out what that might be.) 3) str.join should automatically stringify its arguments. I'm constantly having to write: ' '.join( [ str( x ) for x in items ] ) when I ought to be able to write: ' '.join( items ) I suppose I could do something like: ' '.join( string_iter( items ) ) but having a string function automatically convert its input arguments to strings seems intuitive to me. 4) I still want a prettier lambda. 'nuff said :) 5) At one point, I was a big fan of reduce(), untill I realized that 99% of my use cases were just variations of str.join() :) Even so, I've always wondered if it would be possible to invent a "comprehension- style" syntax for reduce. I have absolutely no good ideas on this one, even though I've been pondering it for years... 6) Although I would not want to propose that Python adopt C's 'assignment is an expression' behavior, I find myself constantly wanting to combine the following two statements into one: m = re.match( ... ) if m: # do something with m -- Talin _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com