Re: macros
ram@zedat.fu-berlin.de (Stefan Ram) writes:
pjb@informatimago.com (Pascal J. Bourguignon) writes:
Well at that point I can only say that, well over here we're not (all)
raving maniacs, that we have useful tools that help solve or obviate a
lot of problems found with other programming languages, and point to
that tutorial: http://www.lisperati.com/casting.html
Assume for a moment I had advanced macro capabilities in Java.
I'd write:
public static String getMultiValue( Object valueObject )
{ String result = null;
if( valueObject == null )result = null;
else if( StringValue stringValue =? valueObject )
result = getStringValue( stringValue );
else if( SprayValue sprayValue =? valueObject )
result = getSetValue( setValue );
return result; }
The macro here is marked by the occurence of ?=??, which is
not a regular Java operator, but part of my hypothetical macro
call pattern.
The problem here is readability:
Can others know, what ?=?? means in my macro package?
Can they know how to immediately find its documentation?
If I invent and use this macro now, will even I myself
remember its meaning a year later?
These are valid questions.
Happily they have been solved by Lisp programmers, perhaps even before
you were born.
To help knowing what =? means, lisp programmers tend to avoid using
punctuation character in their operator names. They rather use
english words (separated by dashes). For example, they would have
used 'equivalent' instead of '=?'.
Do you think Java programmers would be able to use this advanced
technology? The reference manuals you need to consult to use it are
rather thick. Cf. http://www.merriam-webster.com/
More over, to help knowing what arguments a new operator such as
'equivalent' may take, they use another technological advancement :
the parentheses. Stand with me, it's rather complicated. They use
two (*TWO* !) special characters, named 'open parenthesis' and 'close
parenthesis' that look like: '(' and ')'. The trick here is that
they put all the arguments used by the new operators 'inside' the
parentheses. This means that they write: the open parenthesis '(',
the operator (eg. 'equivalent'), and the arguments separated by
spaces, and finally the close parenthesis ')'. This may sound
complicated as explained here, but it's rather simple:
(equivalent stringValue valueObject)
So there you can see clearly that the operator is meant to indicate
whether the _two_ arguments (in this case) stringValue and valueObject
are equivalent.
Notice that if you have a keyboard of the most recent generation you
may be lucky to be able to enter them directly with a special movement
of the fingers: first press one of the two "shift" keys, keep one
finger on the shift key pressed, and then type either 9 or 0. You
should get an open parenthesis for 9, and a close parenthesis for 0.
You may laugh at my explications here, but this is really quite
advanced a technology. They are a lot of happy consequences from the
use of these "parentheses". To answer your second question, one of
the consequences is that parsing lisp expressions is trivial; the
grammar is:
expression ::= atom | '(' { expression } ')' .
Yes, only one non-terminal, only one terminal (plus the two
parentheses), and only one grammar rule. It's can hardly be simplier.
So this grammar can easily be implemented in any tool such as in
editors. And therefore editors can easily provide support for
syntactic editing. Since the operator is always placed in the first
position of a form (a code expression), the editors can easily find
it, and then call up the documentation about the operator.
And finally, using these two advanced technologies, your third
question becomes irrelevant. One year later, you won't need to
remember what it is, you will just read the expression and be able to
understand what it does without even needing to check the source of
the macro.
But notice that if you have some doubt, you may:
- ask the editor to show you the documentation.
- ask the editor to show you the source.
- ask the lisp system to expand the macro call, so you can see the
code that's generated, and if you can understand it, you will
understand the meaning of the macro.
The same coded in Java without macros /is/ more verbose,
but also more readable to someone who knows Java:
public static String getMultiValue( Object valueObject )
{ String result = null;
if( valueObject == null )result = null;
else if( valueObject instanceof StringValue )
{ StringValue stringValue =( StringValue )valueObject;
result = getStringValue( stringValue ); }
else if( valueObject instanceof SprayValue )
{ SprayValue setValue =( SprayValue )valueObject;
result = getSetValue( setValue ); }
return result; }
Why do you stop there? Why don't you read the JVM byte code to
understand the method? It would be more readable and more
understandable, wouldn't it?
--
__Pascal Bourguignon__