gratuitous new features in 2.0

Mike Fletcher mfletch at tpresence.com
Sat Aug 26 19:05:30 EDT 2000


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.

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?  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.

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.

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.

Ah well, I suppose it's already been decided, so I'll go do real work now
instead of spinning the tires (W=F*d).  Enjoy yourself, 
Mike


> -----Original Message-----
> From: Guido van Rossum [mailto:guido at beopen.com]
> Sent: Saturday, August 26, 2000 10:39 AM
> To: python-list at python.org
> Subject: Re: gratuitous new features in 2.0
> 
> 
...
> The new print syntax makes this a straightforward change:
> 
>     import sys
> 
>     def table(n, 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
...




More information about the Python-list mailing list