Python syntax in Lisp and Scheme
bokr at oz.net
Tue Oct 7 06:04:09 CEST 2003
On 06 Oct 2003 12:54:30 +0200, Matthias <no at spam.pls> wrote:
>gregm at cs.uwa.edu.au writes:
>> In comp.lang.functional Erann Gat <my-first-name.my-last-name at jpl.nasa.gov> wrote:
>> :> I can't see why a LISP programmer would even want to write a macro.
>> : That's because you are approaching this with a fundamentally flawed
>> : assumption. Macros are mainly not used to make the syntax prettier
>> : (though they can be used for that). They are mainly used to add features
>> : to the language that cannot be added as functions.
>> Really? Turing-completeness and all that... I presume you mean "cannot
>> so easily be added as functions", but even that would surprise me.
>> (Unless you mean cannot be added _to_Lisp_ as functions, because I don't
>> know as much as I'd like to about Lisp's capabilities and limitations.)
>IMHO, these discussions are less usefull when not accompanied by
>specific examples. What are these macros good for? Some examples
>where you might have difficulties with using ordinary functions:
>1.) Inventing new control structures (implement lazy data structures,
You mean like an object olazy with olazy.x and olazy.y, where x might
be an integer 123 and y might be the text of the latest bug python report
on sourceforge? Not so hard with properties (you'd proabably want to cache
the latest for y and not re-check for some reasonable interval, but that
doesn't change client code (unless you later decide you want the value to
be a tuple of (timestamp, text), etc.)
> implement declarative control structures, etc.)
You mean like case or such? It can be done, but Python could use a way
to define a nested functions that just use the local namespace of their lexically
enclosing function. Then case would be easy to build with a dictionary-based dispatch
of such functions.
Wild idea: It might be interesting to be able to do a kind of (quote thing) or 'thing
in Python, but to defer "trailer" evaluation (where trailer is what comes after an
object-specifying expression. E.g., in x.y[z+2](a=3) x has the trailer ".y[z+2](a=3)"
and x.y has the trailer [z+2](a=3), etc. Ok, you could currently write a class to
do deferred trailer evaluation in the form qt=QT(x.y, '[z+2](a=3)') and then
evaluate/unquote it with qt.value ot qt.evaluate(), etc., but you couldn't just
bind and pass a QT instance like an ordinary object and expect an automatic evaluation
on access, as if the quoted expression appeared in that context.
BTW, with trailer, I am just generalizing the first impulse, which was just to do it
for an attribute name, so as to be able to wrap property as well as ordinary attribute
accesses for unqualified (i.e., deferred-qualification -- we're not talking about
rebinding a name (e.g., x above) that is unknown at access time, since it was lost
when the leader object was pased to QT).
There is an ambiguity when assigning to a name that's bound to a QT object though,
i.e., whether to rebind the name as usual without considering its current binding,
or whether to notice the binding to a QT object, and do as-if-the-entire-trailer-
expression-were-there target processing for the assignment. The latter would make
for "interesting" programming ;-) To rebind such a name, you'd have to get at it
via an indirect route, much as you have to do with an object's attribute name if
it is bound to a property.
> => This one is rarely needed in everyday application programming and
> can easily be misused.
>2.) Serve as abbreviation of repeating code. Ever used a code
> generator? Discovered there was a bug in the generated code? Had
> to fix it at a zillion places?
> => Macros serve as extremely flexible code generators, and there
> is only one place to fix a bug.
> => Many Design Patterns can be implemented as macros, allowing you
> to have them explicitly in your code. This makes for better
> documentation and maintainability.
You can generate code many ways in Python. What use case are you thinking of?
>3.) Invent pleasant syntax in limited domains.
> => Some people don't like Lips' prefix syntax. It's changeable if you
> have macros.
> => This feature can also be misused.
You can do this also.
>4.) Do computations at compile time instead of at runtime.
> => Have heard about template metaprogramming in the C++ world?
> People do a lot to get fast performance by shifting computation
> to compile time. Macros do this effortlessly.
This also, but Python has so many possible compile times ;-)
>These are four specific examples which are not easy to do without
>macros. In all cases, implementing them classically will lead to code
>duplication with all the known maintainability issues. In some cases
>misuse will lead to unreadable or buggy code. Thus, macros are
>powerful tools for the hand of professionals. You have to know if you
>want a sharp knife (which may hurt you when misused) or a less sharper
>one (where it takes more effort to cut with).
Python is pretty sharp ;-)
I think we need some realistic use cases for your "specific" [categories of]
examples in order to compare how problems would be approached.
More information about the Python-list