[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: the uses of macros



Matthias Felleisen writes:
> At Sat, 25 May 2002 05:01:07 -0400 (EDT), Kragen Sitaker wrote:
> > in Python ... I often wish for more, for a variety of reasons
> > explained in _On Lisp_.  Most often, I wish for unwind-protect
> > macros (Scheme's with-open-file, for example, and sometimes I wish
> > for an analogous with-lock-held) and new binding constructs,
> > although I would like these to be merely a more convenient
> > interface to existing functions.
> 
> I'd like to propose that there are three disciplined uses of macros: 
> 1. data sublanguages: ...
> 2. binding constructs: ...
> 3. evaluation reordering: ...
> 
> I understand that Lispers use macros for other reasons. In all honesty, I 
> believe that this is partly due to compiler deficiencies, and partly due to 
> "semantic" irregularities in the target language. 

I was thinking of "with-input-from-file" here, and a look at R5RS says
that it (a) doesn't do what I thought it did and (b) isn't a macro.
So I guess I have to explain.

It's desirable to limit the number of concurrently-open file
descriptors; one convenient tool for this is tying a file descriptor's
lifetime to a particular stack frame.

(All of this also applies to locks, too.)

So I want a construct like Emacs's save-excursion, which cleans up on
either normal exit or exceptional exit; in Python I often find myself
writing this:

    myfile = open(somefilename)
    try:
	foo(myfile)
	bar(myfile)
    finally:
	myfile.close()

and I'd rather be able to write this:

    myfile = open(somefilename)
    with_open_file(myfile):
	foo(myfile)
	bar(myfile)

or even, with a binding construct, this:

    with_open_file(myfile, somefilename):
	foo(myfile)
	bar(myfile)

I can't write these two examples in actual Python because it doesn't
have macros or Ruby-style block arguments.

In actual Python, it's possible to define a with_open_file like
Scheme's call-with-input-file or with-input-from-file, which lets me
do the following:

    def foobar(myfile):
	foo(myfile)
	bar(myfile)

    with_open_file(somefilename, foobar)

but that is noisy to me.

In C++, I can just say:
    { 
        File myfile = somefilename; 
        foo(myfile); 
        bar(myfile; 
    }

and let File's destructor clean up the mess.

(Implementing the above in Scheme seems problematic to me, because the
difference between a nonlocal return to implement error-handling and
the calling of some other continuation to implement threading is not
visible to the language implementation, and I guess this is why
with-input-from-file doesn't do what I thought it did.)

It doesn't seem to me that this use of macros is a data sublanguage,
and it isn't really evaluation reordering, and while having a binding
construct there makes it a little more convenient to use, it's sort of
orthogonal to the real purpose.

So, Matthias, is this use of macros undisciplined, in your view?  Or
does it constitute another category?

-- 
<kragen@pobox.com>       Kragen Sitaker     <http://www.pobox.com/~kragen/>
Irony and sarcasm deflate seriousness, and when your seriousness becomes detum-
escent, you're not held responsible for your thoughts. Irony beats thinking like
rock beats scissors. -- http://www.hyperorg.com/backissues/joho-june2-98.html