Posted by
timothy
on from the they-don't-mix-with-the-beans dept.
bugbear writes "Carlos Perez has just posted a page that quotes Sun Java 'theologist' Gilad Bracha about why there is no plan to add macros (in the Lisp sense) to Java."
The problem with macros, is they sorta defeat Java's OOP. Think of it. Defining a symbol, just to be replaced in thousands of other places where it's written, tied only to the global space.
Sounds awfully like a procedure/function to me.
If you tied macros to objects, they'd just be inline methods. So there really is no point.
The problem with macros, is they sorta defeat Java's OOP
Macros have nothing to do with programming methodology (OOP, procedural, functional, etc).
Defining a symbol, just to be replaced in thousands of other places where it's written, tied only to the global space.
Yes? So? What things are named or what text is substituted before the compiler looks at it has nothing to do with OOP.
Sounds awfully like a procedure/function to me.
Macros are text substitution or syntax tree manipulation alone. Macros are not called, so why you think they have anything to with procedures or functions?
-- If you reply, do so only to what I explicitly wrote. If I didn't write it, don't assume or infer it.
The macros the article is talking about are Lisp-style macros.
These are not your "shoot self in foot" C macros (i.e. replace text x with text y), but a very powerful and expressive way to have the entire language at your disposal at compile time.
If you've seen the neat tricks you can do with C++ templates (template metaprogramming, etc), you might have an idea of what real macros would be like, when severely watered-down.
Lisp macros make things like Generic programming and OOP very simple to add to a language, as well as almost any other conceivable programming construct.
For instance, with proper macros in Java, you wouldn't ask, "When will templates be added to Java?"; you could add them yourself.
Note that this kind of recursion is a common way to express iteration in Scheme/Lisp, as it is "tail-recursive" (i.e., doesn't require going back to the calling function once the next loop() is called), and is optimized by the interpreter/compiler to be generally as efficient as iteration.
Interesting point.
by
alyosha1
·
· Score: 5, Interesting
The single best measure of whether a programming language is worth using is: how well does it support communities.
This point doesn't seem to get raised very often when comparing the relative merits of language A against language B. It's easy to forget that while a language is a tool for communicating with a computer, it is also (and arguably more importantly) a tool for communicating with other programmers.
Which is why Python is rapidly becoming my favourite language. I find other people's python code far easier to understand than stuff written in other languages. This despite the fact that I've only been hacking python for a few months, and I've been using C++ and other languages daily for several years.
I feel that there's scope for yet another 'methodology', alongside OO and XP and all that - it might be called 'code as conversation', whereby the quality of a piece of code is judged by how readily it communicates intent to other programmers.
No, in Lisp macro's aren't used for inline functions , but for syntax extensions. For a demonstration of what real macros can do, look at The Swine Before Perl. That presentation shows how easy it is to implement special syntax for automatons in Scheme, and how natural & simple the result looks.
One less language to be used in obfuscated code contests. Where's the fun without macros and overloading? sigh....
Strange, I've been arguing about this all day ...
by
torpor
·
· Score: 4, Interesting
... and losing badly.
Okay, C programmers, tell me why these 4 macros are bad:
#define is == #define and && #define or || #define until(a) while(!(a))
Tell why they're good if you think they're good, but I'm only interested in the bad argument (having lost it all day).:)
-- ; -- the corruption of government starts with its secrets. a truly free people keep no secrets.
--
Re:Strange, I've been arguing about this all day .
by
reynaert
·
· Score: 4, Interesting
They're bad because they don't extend the C syntax, they just change it. Good macros extend the syntax, but keep the new syntax in same style as the original language. If you want to know to what your four macro's lead, look at the famous Bourne shell source code. A few simple definitions like yours in mac.h
result in the horror of xec.c and cmd.c.
If this is what Jabba does, then Jabba will lose.
by
ArmorFiend
·
· Score: 4, Informative
The crux of his argument is that user defined macros make code unreadable. If users are able to create their own macro constructs, they'll be "making their programs unreadable for everyone else". This is pure hogwash from someone that's probably never used hairy-chested lisp macros seriously. I'll demonstrate to you the hogwashishness in two phases.
Flash-back to 1969 when the same arguments were put forward by assembly programmers against named functions:
User defined
functions make code unreadable. If users are able to create their own functions, they'll be "making their programs unreadable for everyone else".
History has show that user defined functions are good. People are finally realizing that lisp macros are perhaps an equally important good. By taking this position, Jabba is positioning itself on the losing side of history.
If you look at it in terms of lines of code, in terms of error-prone-ness, in terms of high-level versus low-level, in terms of maintainability, ONLY AN IDIOT WOULD CHOOSE AGAINST MACROS.
Okay, sorry for being ornery, but mod this scruffy post up!
Re:If this is what Jabba does, then Jabba will los
by
reynaert
·
· Score: 3, Insightful
You're completely right of course. But as many people are complaining macro's don't fit in Java's everything-is-part-of-a-class philosophy, I'll just point out you can easily put macro's in classes and use them like this (assuming you have an OpenGL class):
The real point is that LFSPs (Language for Smart People) have a much greater support for abstraction, and in particular for defining your own abstractions, than LFMs (Language for the Masses)....has anyone declared Perl *the* LFSP? I can't think of a more abstract and unreadable language off the top of my head (Cobol doesn't count just because the younger generation has never used it).
--trb
Re:Strange, I've been arguing about this all day .
by
FroMan
·
· Score: 4, Interesting
Programming languages are similar to spoken/written language, they are meant to convey an idea. In programming the ideas are instructions to the computer and to someone maintaining the code. For each language there are pedantic ways of doing things, usually from tradition or common ideas.
In C when you are writing and infinite loop for a server, the standard way to do it is
for (;;) {
if ((acceptfd = accept(...)) < 0) {/* handle errors here */
}
if ((pid = fork()) < 0) {/* handle errors here */
}
There are two very common C practices used in this. The first is the for (;;) {}. This is the standard way to do it because there is no comparison ever used within the loop, where a while (1) {} would seem to do the same thing it does have a comparison. Well, now it wouldn't matter since the compiler would optimize the loop anyways since the '1' is a constant, older compilers or non-optimizing compilers would not catch that though.
The second practice is the if ((x = f()) < 0) {}. This arises more out of tradition. It gets the return value of a system call and allows the error handling to be done immediately. It also helps keep the indenting level from running away.
Ammusingly enough in Java with JCSC I find that it gives warnings saying it is bad style. I would guess that it would prefer
try {
int acceptfd = accept();// non error condition here } catch (Exception e) {// handle accept error here } finally {// no matter error or not here }
From a C background I find this abhorrent. Look at the level of indentation required! Evil!
Well, what does that have to do with #define or ||? Tradition. C programmers are used to seeing "||" as an "or". There is no keyword "until". If a C developer is hired new into the place he will have to learn the idiosyncracies that this place uses.
Specific arguments against using macros to extend the language are that you are in effect adding keywords to the language. In effect "or", "and", "is" and "until" are now keywords in C. Since these are not part of the language normally, any code that uses any of those as a variable will now have issues.
Well, who would use "or", "and", "is" as a variable name? Well, look at the linux kernel code and you will find that "new" is used occasionally, which causes the kernel to not be able to be compiled with a C++ compiler. I would also argue that "or" could easily mean outputReport and "is" quite often means inputStream to me.
By using this "or", "and", "is" nonsense you are also leaving out the possiblity of using similar ideas for bit fields. You could use "xor", but you would need a "bor" for bitwise or'ing of a field.
Basically what I see by using the macros here is that you are limiting yourself to a number of poor programming practices. When you use these you will be confusing real programmers and potentially inserting errors into the code. In C "||" is well defined and any C programmer is able to understand it. "or" on the other hand is ambigious to C programmers since it is not part of the programming language.
-- Norris/Palin 2012
Fact: We deserve leaders who can kick your ass and field dress your carcass.
Lisp-style macros are, in a sense, all about syntactic sugar. They let you write stuff easily and predicably that would be possible, but inconvenient by hand, to the extent that it becomes natural to implement domain-specific languages with them.
Java, and about every non-Lisp language, lacks syntactic extensibility. Yet, Java programmers obviously consider Java syntax to be not usable for a lot of everyday tasks - hence the ever-growing number of special mini-languages around Java, like Ant-XML, XDoclets, JXPath, to a degree even XSLT.
Of course it is possible to implement such DSLs in Java, but you typically end up writing an interpreter, and that usually means that, if you want to use the DSL in your program (say, evaluating expressions built at runtime), you end up manipulating strings and feeding them to a huge, opaque interpreter machinery - which is error prone and the hell to debug. And, by the way, one of the things people often call one of the biggest problems of macros, when they only know C-style ones.
Basically, much of what macros allow you to do is already done in the Java world, just without the language supporting it, and hence in slow, buggy and hard-to-debug, often ill-specified ways.
Re:useless
by
Procyon101
·
· Score: 3, Informative
I politely disagree. Although I have never actually used goto in a program, I can concieve of a severely nested loop with an exit condition that would have to be propagated all the way out of a the loop. This could prove overly complex, having to check for the condition in every loop (perhapse this is a 16 dimentional data structure and we are doing a search and we happen to find the value early by luck). Throwing an exception is an option, but since this might not be an "exceptional" condition, some people might be philosophically opposed to it. In this (extremely rare) case, goto has a very good organization purpose.
Macros are not macros!
by
mrami
·
· Score: 3, Informative
Just so everyone understands, in Lisp, macros are not text replacement systems. In Lisp, macros are functions that take a set of syntactic forms and return a new syntactic form to the compiler. You're not breaking any OOP principles here, any more than ArrayList breaks them by always using Objects.
So, for example you could write a macro that takes a variable, a list, and a statement and returns a for-loop that iterates over the variable, and call the macro, say, 'foreach'. Or you could write a macro that takes a boolean expression on a set of classes and return a statement block to do some JDBC calls and create a bunch of objects that represent the join of that expression. Or... (substitute here anyting you do on a regular basis that can't be made into a method).
No macroth? Thath too bad. ;)
Just to clarify further why macro's are bad.
The problem with macros, is they sorta defeat Java's OOP. Think of it. Defining a symbol, just to be replaced in thousands of other places where it's written, tied only to the global space.
Sounds awfully like a procedure/function to me.
If you tied macros to objects, they'd just be inline methods. So there really is no point.
-
ping -f 255.255.255.255 # if only
Which is why Python is rapidly becoming my favourite language. I find other people's python code far easier to understand than stuff written in other languages. This despite the fact that I've only been hacking python for a few months, and I've been using C++ and other languages daily for several years.
I feel that there's scope for yet another 'methodology', alongside OO and XP and all that - it might be called 'code as conversation', whereby the quality of a piece of code is judged by how readily it communicates intent to other programmers.
> if u want the extra performance boost
Maybe you wouldn't find macros so useless if you created some keyboard macros to replace ' u ' with ' you '.
Just a thought.
No, in Lisp macro's aren't used for inline functions , but for syntax extensions. For a demonstration of what real macros can do, look at The Swine Before Perl. That presentation shows how easy it is to implement special syntax for automatons in Scheme, and how natural & simple the result looks.
One less language to be used in obfuscated code contests. Where's the fun without macros and overloading? sigh....
... and losing badly.
:)
Okay, C programmers, tell me why these 4 macros are bad:
#define is ==
#define and &&
#define or ||
#define until(a) while(!(a))
Tell why they're good if you think they're good, but I'm only interested in the bad argument (having lost it all day).
; -- the corruption of government starts with its secrets. a truly free people keep no secrets. --
They're bad because they don't extend the C syntax, they just change it. Good macros extend the syntax, but keep the new syntax in same style as the original language. If you want to know to what your four macro's lead, look at the famous Bourne shell source code. A few simple definitions like yours in mac.h result in the horror of xec.c and cmd.c.
Flash-back to 1969 when the same arguments were put forward by assembly programmers against named functions:
History has show that user defined functions are good. People are finally realizing that lisp macros are perhaps an equally important good. By taking this position, Jabba is positioning itself on the losing side of history.Seriously, what's easier to read:
ORIf you look at it in terms of lines of code, in terms of error-prone-ness, in terms of high-level versus low-level, in terms of maintainability, ONLY AN IDIOT WOULD CHOOSE AGAINST MACROS.Okay, sorry for being ornery, but mod this scruffy post up!
You're completely right of course. But as many people are complaining macro's don't fit in Java's everything-is-part-of-a-class philosophy, I'll just point out you can easily put macro's in classes and use them like this (assuming you have an OpenGL class):
given this statement
...has anyone declared Perl *the* LFSP? I can't think of a more abstract and unreadable language off the top of my head (Cobol doesn't count just because the younger generation has never used it).
The real point is that LFSPs (Language for Smart People) have a much greater support for abstraction, and in particular for defining your own abstractions, than LFMs (Language for the Masses).
--trb
Programming languages are similar to spoken/written language, they are meant to convey an idea. In programming the ideas are instructions to the computer and to someone maintaining the code. For each language there are pedantic ways of doing things, usually from tradition or common ideas.
/* handle errors here */
/* handle errors here */
/* parent */ /* child */
// non error condition here // handle accept error here // no matter error or not here
In C when you are writing and infinite loop for a server, the standard way to do it is
for (;;) {
if ((acceptfd = accept(...)) < 0) {
}
if ((pid = fork()) < 0) {
}
if (pid == 0) {
} else {
}
}
There are two very common C practices used in this. The first is the for (;;) {}. This is the standard way to do it because there is no comparison ever used within the loop, where a while (1) {} would seem to do the same thing it does have a comparison. Well, now it wouldn't matter since the compiler would optimize the loop anyways since the '1' is a constant, older compilers or non-optimizing compilers would not catch that though.
The second practice is the if ((x = f()) < 0) {}. This arises more out of tradition. It gets the return value of a system call and allows the error handling to be done immediately. It also helps keep the indenting level from running away.
Ammusingly enough in Java with JCSC I find that it gives warnings saying it is bad style. I would guess that it would prefer
try {
int acceptfd = accept();
} catch (Exception e) {
} finally {
}
From a C background I find this abhorrent. Look at the level of indentation required! Evil!
Well, what does that have to do with #define or ||? Tradition. C programmers are used to seeing "||" as an "or". There is no keyword "until". If a C developer is hired new into the place he will have to learn the idiosyncracies that this place uses.
Specific arguments against using macros to extend the language are that you are in effect adding keywords to the language. In effect "or", "and", "is" and "until" are now keywords in C. Since these are not part of the language normally, any code that uses any of those as a variable will now have issues.
Well, who would use "or", "and", "is" as a variable name? Well, look at the linux kernel code and you will find that "new" is used occasionally, which causes the kernel to not be able to be compiled with a C++ compiler. I would also argue that "or" could easily mean outputReport and "is" quite often means inputStream to me.
By using this "or", "and", "is" nonsense you are also leaving out the possiblity of using similar ideas for bit fields. You could use "xor", but you would need a "bor" for bitwise or'ing of a field.
Basically what I see by using the macros here is that you are limiting yourself to a number of poor programming practices. When you use these you will be confusing real programmers and potentially inserting errors into the code. In C "||" is well defined and any C programmer is able to understand it. "or" on the other hand is ambigious to C programmers since it is not part of the programming language.
Norris/Palin 2012
Fact: We deserve leaders who can kick your ass and field dress your carcass.
>> if u want the extra performance boost
>Maybe you wouldn't find macros so useless if you created some keyboard macros to replace ' u ' with ' you '.
>
>Just a thought.
Maybe yoyou woyouldn't find macros so youseless if yoyou created some keyboard macros to replace 'you' with 'yoyou'.
Jyoust a thoyought.
There are no trails. There are no trees out here.
Java, and about every non-Lisp language, lacks syntactic extensibility. Yet, Java programmers obviously consider Java syntax to be not usable for a lot of everyday tasks - hence the ever-growing number of special mini-languages around Java, like Ant-XML, XDoclets, JXPath, to a degree even XSLT.
Of course it is possible to implement such DSLs in Java, but you typically end up writing an interpreter, and that usually means that, if you want to use the DSL in your program (say, evaluating expressions built at runtime), you end up manipulating strings and feeding them to a huge, opaque interpreter machinery - which is error prone and the hell to debug. And, by the way, one of the things people often call one of the biggest problems of macros, when they only know C-style ones.
Basically, much of what macros allow you to do is already done in the Java world, just without the language supporting it, and hence in slow, buggy and hard-to-debug, often ill-specified ways.
Programming can be fun again. Film at 11.
I politely disagree. Although I have never actually used goto in a program, I can concieve of a severely nested loop with an exit condition that would have to be propagated all the way out of a the loop. This could prove overly complex, having to check for the condition in every loop (perhapse this is a 16 dimentional data structure and we are doing a search and we happen to find the value early by luck). Throwing an exception is an option, but since this might not be an "exceptional" condition, some people might be philosophically opposed to it. In this (extremely rare) case, goto has a very good organization purpose.
So, for example you could write a macro that takes a variable, a list, and a statement and returns a for-loop that iterates over the variable, and call the macro, say, 'foreach'. Or you could write a macro that takes a boolean expression on a set of classes and return a statement block to do some JDBC calls and create a bunch of objects that represent the join of that expression. Or... (substitute here anyting you do on a regular basis that can't be made into a method).