A PYTHON PREPROCESSOR

Kris J. Zaragoza kzaragoza at mediaone.net
Thu May 18 19:39:32 EDT 2000


On Thu, 18 May 2000 05:52:25 GMT, Courageous <jkraska1 at san.rr.com> wrote:
> 
>> I think the collective wisdom is "don't do this". Not because of
>> whitespace issues -- these can be dealt with, with some thoughts. It's
>> because it's not needed -- Python is *so* flexible right now, there's not
>> much you need macros for.
>
>The longer term effort might be to -- in conjunction with
>eval, apply, and friends -- give python true metalinguistic
>capability. That's quite possibly a larger bite than I can
>chew at the moment, though. :)-
>
>
>C/

I think you may be on the right track with this one.  The biggest
mistake would be, IMHO, to build a text transformation preprocessor
(source to source, a la CPP, the C preprocessor).  As has been seen in 
the C and C++ development world, this is a sub-optimal solution.

The better path, I believe, is to build a macro system or metalanguage 
into Python itself, operating on the syntax tree after parsing, but
before actual compilation.  This would allow incredible amounts of
power in transforming the code while avoiding all the problems that
come with slicing and dicing text.  Common Lisp and Scheme have shown
the power of this approach.  It's quite common in the Lisp world to
use macros to tailor the language to the problem, rather than the
problem to the language.  Why not do the same in Python?  (Mind you,
this is easier said than done, and I understand how difficult this is, 
but I'm allowed to dream. :)

Just imagine a large system where you're regularly repeating certain
idioms, such as complex exception handling.  Here's a purely
hypothetical example.

def generateHTMLForm(response, record_id):
	# Get the record information from the database
	conn = getDBConnectionFromPool()
	try:
		...
		# Build the HTML code
		returnString = ...
		...
		# Write it to the given response object
		try:
			response.write(returnString)
		except IOError e:
			# Log the exception
			...
			# Dump the state of the response/socket
			...
	except DatabaseError dbe:
		# Log the exception
		...
		# If it's a critical error, email the DBA
		...
	except IOError ioe:
		# Log the exception
		...

And so on in all sorts of places throughout the code.  Now, I'm sure
this can be done a bit more cleanly with a good OO design and proper
passing on of exception handlers, but imagine how much cleaner the
code would be if all you had to write was:

def generateHTMLForm(response, record_id):
	withDatabaseConnection (conn, getDBConnectionFromPool()):
		withResponseStream(response):
			# Build the HTML code
			returnString = ...
			# Write it out
			response.write(returnString)

All of the proper error handling would be taken care of by the
user-defined constructs "withDatabaseConnection" and
"withResponseStream".

Now, as for what the macro/metalanguage would actually look like, I
have no clue. :-)

Thoughts?

-Kris

-- 
Kris J. Zaragoza           | "Unfortunately, most people can't out-think a
kzaragoza at mediaone.net     | grapefruit."  --Jon Bodner



More information about the Python-list mailing list