[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