gratuitous new features in 2.0

Guido van Rossum guido at beopen.com
Sat Aug 26 23:01:29 EDT 2000


[Didn't see this on usenet yet, responding to the mail.]

> Minor note: your example changes the semantics of the function, that is;
> where the first version prints "to the current sys.stdout" when no file
> argument is given, thus working in PythonWin, IDLE, etceteras, the second
> version requires that all callers of the function retrieve the current
> sys.stdout and explicitly pass it, as sys.stdout is bound during the
> _definition_ of the function.

I was well aware of that, but since the bug was equal in all versions
I decided to ignore it.

I'm tempted to change >> so that print>>None prints to sys.stdout --
this is a *very* small change in the implementation.  Sometimes that
means it's a natural extension.

> The semantically equal version would be:
> 
> 	import sys
>  
> 	def table(n, file=None):
> 		# do this just cause we say :), don't
> 		# look behind the curtain!  You don't
> 		# need to understand compile-versus-
> 		# run-time-binding yet!
> 		if file is None:
> 			file = sys.stdout
> 		for j in range(1, n+1):
> 			for i in range(1, n+1):
> 				print >>file, i, 'x', j, '=', i*j
> 			print >>file
> 
> You might find that taking the argument "None" as your ">>" test means print
> to current stdout?

As I said.  Honestly, I thought of this before I saw your mail. :-)

> Of course, then when a get lookup on a dictionary return
> None you may wind up with "why did that go there" bugs.  More magic in the
> kitchen.

But that would happen anyway if the actual argument happened to be
None.  Doesn't seem a major objection.

> The writeln as method requires:
> 
> 	def table(n, file=None):
> 		# do this just cause we say :), don't
> 		# look behind the curtain!
> 		if file is None:
> 			file = sys.stdout
> 		for j in range(1, n+1):
> 			for i in range(1, n+1):
> 				file.writeln( i, 'x', j, '=', i*j )
> 			file.writeln()
> 
> Big argument against that, of course, is that it requires altering the
> interface for files (need to rewrite _all_ file-like objects).  Serious work
> by serious numbers of people.
> 
> writeln as builtin function:
> 
> 	def table(n, file=None):
> 		# do this just cause we say :), don't
> 		# look behind the curtain!
> 		for j in range(1, n+1):
> 			for i in range(1, n+1):
> 				writeln( i, 'x', j, '=', i*j, file=file )
> 			writeln( file=file )
> 
> 	def writeln( *args, **namedargs ): # untested pseudo-code
> 		if namedargs.has_key( "file" ):
> 			file = namedargs["file"]
> 			if file is None:
> 				file = sys.stdout
> 		else:
> 			file = sys.stdout
> 		output = string.join( map(str, args), ' ')
> 		file.write( output)
> 		if namedargs.has_key( "end"):
> 			file.write( end )
> 		else:
> 			file.write( '\n' )
> 
> More examples:
> 	writeln( a, "+", b, "=",    end=" ", file=file )
> 	writeln( c,    file=file )
> 
> Problems with that are that the "end" is not immediately obvious (though
> it's possible to figure it out).  As noted, there's some (fairly minor)
> symbol clutter introduced.  The end stuff is wordy, but it's explicit, so
> you don't get new users saying "hey, how did that space get there?  Oh,
> there's a trailing comma (that means nothing anywhere else, but in this
> particular context alters the contract of the mechanism.)"  Because the
> argument is explicitly _there_, the user who doesn't understand the
> behaviour is going to look it up, not report a bug about strange spaces
> inserted into their output.

This is all good stuff for a redesign for Python 3000.  I'm inclined
to at least *look* into making print a function in Py3k -- then we can
look into how to make it easy to use, etc.

For Py2.x, that's all too much work, and hence everybody who still
suggests to use a function for the extra functionality should re-read
my previous post.

> With all these short-name-only examples, it's pretty hard to figure out what
> the writeln approach looks like in real code:
> 	writeln( firstOperator, "+", secondOperator, "=",    end=" ",
> file=sys.stderr )
> 	writeln( result )
> 	writeln( withTestEnding, end=('\n','\r\n')[ winBinary ] )
> 
> The "end" is not something a new user is going to say "ah, of course" about.
> Still, given the complete foreign-ness of the ">>" stuff, I don't think
> that's a clear win for one approach or another.

As long as we're discussing this potential Py3k design, I'd rather
have separate methods, e.g. writeln(item, ...) and writesp(item, ...).

--Guido van Rossum (home page: http://www.pythonlabs.com/~guido/)




More information about the Python-list mailing list