Why Java Won't Have Macros 140
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."
Time is the most valuable thing a man can spend. -- Theophrastus
Finally! (Score:2)
-n
Re:Finally! (Score:2)
Macros and various other types of pre-processing your code are one of the major reasons C/C++ needs to be replaced with a better syntax, like, say.... D [digitalmars.com].
I personally like programming in Java simply *because* of the lack of Macros. I hate the fact that Java requires a VM to run: I'd rather write native code, but I'd rather write in Java than C/C++ any day.
I'm a study in contrasts, however: I wouldn't mind operator overloading in
Re:Finally! (Score:2)
preprocessing? (Score:2)
in the Lisp sense? (Score:5, Funny)
Re:on thecond thought... (Score:2)
Tho thue me.
useless (Score:1)
Re:useless (Score:1)
Re:useless (Score:2)
um... no... GOTOs have completely no organizational purpose for code whatsoever...
Using macros can add another level of abstraction to your code and can make it more expressive. The perceived cost of that it reduces readability for people not familiar with a particular set of macros.
thanks for restating whats said in the article...
Re:useless (Score:4, Informative)
Gotos (Score:3, Informative)
Also, some programs that does loops in irregular ways (such as non-recursive searching programs that backtracks) c
Re:useless (Score:2)
Re:useless (Score:3, Insightful)
Java has labeled statements [sun.com], so you can put a label on the outermost loop statement and then simply write "break label;" when you have to exit all the loops.
Re:useless (Score:2)
It would be difficult to use labeled breaks to make code less readable. However, GOTOs are nearly essential in obfuscated C competitions.
Re:useless (Score:2)
In Ada,
Top_Level_Loop:
for I in 1
for J in 1
for K in 1
exit Top_Level_Loop when Some_Condition;
end loop;
end loop;
end loop Top_Level_Loop;
The goto statement is occasionally useful, but not here.
Re:useless (Score:2)
Does it not state precisely what it means?
Whereas a break somewhere in the middle of the loop simply means, "I'm bugging out! See if you can figure out why!"
Re:useless (Score:3, Interesting)
#define FOO bar + 2 *
(seen in flex source), you have a problem. With a decent macro system (such as Common Lisp, Scheme, and Dylan have), you avoid these kind of problems. (btw, Dylan has an ordinary, infix syntax, so having lots of parentheses is not a requirement...)
Re:useless (Score:1)
You can't replace methods with goto statements in Java. Try writing a byte-code verifier that can verify the output of a compiler for a source language with goto.
Re:useless (Score:5, Funny)
Maybe you wouldn't find macros so useless if you created some keyboard macros to replace ' u ' with ' you '.
Just a thought.
Re:useless (Score:5, Funny)
>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.
Re:youseless (Score:2)
Re:youseless (Score:2)
Re:youseless (Score:2)
Re:useless (Score:5, Informative)
academia (Score:2)
Useful macros from Monday's BRL release (Score:2)
This would bind the local variable a to the value of an HTML input named "a". Similar with b and c. Similar with cookies, session variables and URL path segments. Try writing those as functions.
Re:useless (Score:2)
For an excellent example of the power of the C preprocessor and some of its more advanced usage see The Boost Library Preprocessor Subset for C/C++ [boost.org].
OOP (Score:4, Informative)
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.
Re:OOP (Score:1)
Macros might be able to do more than just expand to a method. They could expand to a language construct such as an inner class, a for loop, a return statement, etc.
Obviously, this leads to more complexity for syntax highlighting and compilers. And it leads to constructs that could drive the programmer nutty (ok, who defined "==" as "!="?). Which is why the Java guys don't want them in the l
Re:OOP (Score:2)
this->==(something) ? this->equals(something) already exists
Re:OOP (Score:2)
Re:OOP (Score:5, Insightful)
Re:OOP (Score:2)
Re:OOP (Score:2)
Re:OOP (Score:2)
Re:OOP (Score:2)
Re:OOP (Score:3, Interesting)
But back to the macro bit. You are right, anything can be made to create a mess... but lemme attack it from the other end. With OOP, an object has its methods on what it can do. If a method calls another objects methods, it's ok. It's straight forward etc... since each object effectively becomes a mini library.
With procedural programming, which what
Re:OOP (Score:2)
It makes code messy.
Re:OOP (Score:3, Insightful)
Well, that depends on the language. In Common Lisp and most other Lisp dialects (not Scheme tough), macro's are normal functions that are run at compile-time instead of at run-time. They can do everything normal functions can do, such as calling other functions, doing I/O, etc..
Re:OOP (Score:2)
As you pointed out the function runs at compile time. Therefore whatever the macro returns, is the text that gets compiled. That is the end of it.
I want to write a macro so that I can now write syntax like this.....
Re:OOP (Score:5, Informative)
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 [kuro5hin.org].
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.
Re:OOP (Score:3, Interesting)
Lemme also take a segment from what your link has.
Re:OOP (Score:4, Informative)
Actually, you're correct. It defines a syntax for a while loop by creating a function that does (in pseudocode): 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.
Re:OOP (Score:3, Insightful)
That's prolly what java doesn't want. Syntax changes done by something like macros, or from what you've pointed out.
Re:OOP (Score:2)
Of course, having said that, I didn't begun to love Java yet: it still has got neither macros nor ADT.
Re:OOP (Score:2)
Re:OOP (Score:2, Insightful)
Sounds like you are bashing procedural. There is no evidence that OOP is objectively better than procedural. For every "fault" you can find in procedural, I bet I can either find a better procedural way to do it, or find flaws with the OO approach also that you either never thought of, or ignored out of habit.
(PS. If you tag this message "flaimbait", then please tag the parent also. Them'r the
Re:OOP (Score:2)
Imagine mixing lisp's style, c's procedural programming, OOP and aspect programming into one. ANYONE can make a bigger mess than using one technology at a time.
And if you mod me as flambait, mod the parent as funny, since he started taking what I said out of context
Re:OOP (Score:2)
Interesting point. (Score:5, Interesting)
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.
Re:Interesting point. (Score:2)
I would have said that writing readable/maintainable code had always been a goal of good developers. I see it as orthogonal to both OOP and XP, and independent of any particular language or paradigm, though.
Some people (Knuth, for example) advocate taking this to
Re:Interesting point. (Score:3, Insightful)
Java is clearly a s
Re:Interesting point. (Score:2)
IMHO that's not a strength. Code that doesn't express the system's überdesign shouldn't be there at all (or at least in a library with a conceptually unified design of its own). And in well-factored code it won't be true--what's the value of being able to tell this block contains simple logic and a few method calls if you don't understand what the methods do?
Esp
Heh heh heh... (Score:2)
A tacit admission that good text-replacement macros are a whole lot harder to do than S-expression macros, perhaps?
Sigh.. (Score:5, Funny)
But... that's my favorite anime! (Score:2, Funny)
Yo, moderators (Score:1, Redundant)
Feature request for slash: the first moderation to a comment can't be "overrated" or "underrated".
Well, obviously it's "underrated" now. "funny" is also an acceptable answer. Help me rebuild my karma rating or I'll never be able to get a loan.
Strange, I've been arguing about this all day ... (Score:4, Interesting)
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).
Re:Strange, I've been arguing about this all day . (Score:5, 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 [tuhs.org] source code. A few simple definitions like yours in mac.h [tuhs.org] result in the horror of xec.c [tuhs.org] and cmd.c [tuhs.org].
Re:Strange, I've been arguing about this all day . (Score:1)
but still: why is it bad?
Re:Strange, I've been arguing about this all day . (Score:1)
To answer your question though, how would you like it if you had to read over and work on someone elses code and they had aliased all the symbols to something different?
Re:Strange, I've been arguing about this all day . (Score:2)
--jeff++
Bourne shell source (Score:2)
That's Bourne for you, he didn't like C's punctuation.
sh(1) has remained very stable from the late 1970s through the present. That coding style had a lot to do with it. sh(1)'s stability insured that features were added as external commands instead of shell builtins, as everyone from MS NT, DEC VMS, IBM JCL did, making scripts not so backwards-compatible. That in turn enforced unix's component software tools philosophy
Re:Strange, I've been arguing about this all day . (Score:4, Interesting)
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.
Re:Strange, I've been arguing about this all day . (Score:2)
Nothing. The point of macros facility in question isn't C-like preprocessor string substitution, but the availability of full language at compile time to do code generation.
Think of defining your own object systems, domain-specific languages, encapsulating boilerplate code and similar rather than of defining constants and changing language keywords to silly names.
Re:Strange, I've been arguing about this all day . (Score:2)
I was browsing at +4, and the direct parent didn't make it through. Sorry for the way-off reply.
Re:Strange, I've been arguing about this all day . (Score:2)
Re:Strange, I've been arguing about this all day . (Score:2)
Suppose I'm sitting down to maintain this. Does "or" mean logical or or does it mean bitwise or? I have to guess from context or look at the header file. As Dilbert said in the TV series, "it's not that it's difficult, it's *unnecessary*". Does that header file ever change? Which version of the header was in use when the code I'm looking at was written?
Worse, suppose I don't look at the header file and think that "until" has the same semantics that it does in other languages, namely
Re:Strange, I've been arguing about this all day . (Score:2)
typedef int DWORD
typedef char* LPSTR
(yes, burn in hell Microsoft)
are bad. There is a delicate balance in a language between the added intellectual overhead of introducing a new statement versus the savings in time and increase in readability. To something as simple as a function call:
do_foo(5);
When a programmer sees that call, he has to think, "well, WTF does do_foo() do?" Now, if do_foo() is well named, and wraps a lot of other code, the added intellectual overhead of u
Re:Strange, I've been arguing about this all day . (Score:3, Insightful)
The reason those typedefs are good is that they insulate the programmer from the compiler that they're using.
Quickly now, can you tell me if 'char' is signed or unsigned by default on your C++ compiler? Or how long is an 'int'?
It's a simple matter to change those definitions in a single place, but if you change compiler you may have to refactor a whole lot of your code to keep it compatible
Re:Strange, I've been arguing about this all day . (Score:2)
>>>>>>>>
In the common case, you're not supposed to care about the exact details. There are a few cases where you should be using specific-sized types (when dealing with file formats and such) but most of the time you're supposed to use the native types because it allows the compiler to use whatever exact sizes are best for the platform. In case where you need to know
Re:Strange, I've been arguing about this all day . (Score:2)
as for LPSTR, the problem with writing "char *" is that you don't necessarily know whether or not the chars being pointed to are signed.
Re:Strange, I've been arguing about this all day . (Score:2)
well that's because your headers are probably tailored to your compiler, but for a different compiler with different char signedness you'd have a different set of definitions. you're really not getting my point, are you?
Re:Strange, I've been arguing about this all day . (Score:2)
If this is what Jabba does, then Jabba will lose. (Score:4, Informative)
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:
OR 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 (Score:4, 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):
Re:If this is what Jabba does, then Jabba will los (Score:2)
Eh, there are some things you can't do with this approach that you can do with macros. A (fairly trivial) instance in my example is how it lets you specify a variable name (color), which then gets bound to the color of the window. Uses of "color" in "non-boiler-plate-code" thus handily become references to the window's color.
Higher-order functions mostly make macros obsolete (Score:3, Insightful)
I used to be a crazy cowboy C programmer, and I loved macros more than anything. But seriously, functions go a long way, as long as they are syntactically brief (anonymous) and semantically powerfu
Re:Higher-order functions mostly make macros obsol (Score:2)
Common Lisp defines no "while" form. Nobody complains about this, because its easy to write a macro to implement while:
Here's a sample call that flips a coin until getting a tails, p
Re:Higher-order functions mostly make macros obsol (Score:2)
Why not make up a simpler syntax, then? You could use a single character for suspending code with zero arguments, and then the use of the while example would be only two characters longer than the lisp macro version. (Lisp programmers surely cannot complain about two extra characters, as their language is filled with extra verbosity!)
The advantage of such a system is that it can be explained simpl
Re:Higher-order functions mostly make macros obsol (Score:2)
Point taken. :) I think I'll actually do this, using lisp's set-macro-character function. Hereafter let ??z be the function that takes no arguments and returns z. ?x?z takes argument x and returns z. ?x y?z takes arguments x and y and returns z.
Re:Higher-order functions mostly make macros obsol (Score:2)
> goto.
Yeah, well, that's how functions are implemented too.
> What this boils down to is that you need a new keyword to tell the compiler your passed function+environment will be stack
> allocated or heap allocated.
You're right, if while lives in a different module and your module system only lets you specify the most basic things about the symbol. But lots of compilers
Re:Higher-order functions mostly make macros obsol (Score:2)
Uh...unsure.
Well it sure can't be any faster, since free-ing stack allocated memory takes zero time -- you already have to bump the stack pointer for function return. Stack allocation just adds a (usually) constant number to the already constant stack bump. I don't know what a "copying collector" is, but if it takes 1 cycle to allocate or one cycle to garbage collect (GC) or 1 cycle to free, its for sure slower than stack allocation.
The language I used where heap
Re:If this is what Jabba does, then Jabba will los (Score:2)
Re:If this is what Jabba does, then Jabba will los (Score:2)
Look closely, that's why I gave it a symbol to pass into which it loads the window's color. And yes I did tack it on at the last minute as a bulkward against just this kind of post.
Re:If this is what Jabba does, then Jabba will los (Score:2)
someMethod(Object something, Method todo) {
todo.invoke(something, null);
}
Yeah, it's just sugar. It's a shame that more folks don't use reflection - it's mighty powerful stuff.
Java reflection (Score:2)
Ah, I've never gone to the trouble to translate what Java means by "reflection" into terms I fully understand. What does it mean in this context?
That code snippet you posted seems to invoke a computed method (todo) on a computed object (something), and p
Re:Java reflection (Score:2)
someMethod = myObject.findMethodNamed("todo");
is what relfection is all about. If that doesn't make reflection clear, bug me again and I'll div
Re:If this is what Jabba does, then Jabba will los (Score:2)
Perl (Score:5, Insightful)
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
Re: Perl (Score:2)
> > 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
>
Maybe I don't grok what you're saying, but ISTM that "abstract" and "unreadable" are very different concepts. To me an "abstraction" is very readable, because the reader can focus o
Java needs Macros, Badly (Score:5, Insightful)
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:Java needs Macros, Badly (Score:2, Interesting)
Why?
Unless you are the only one writing the code you read and the only one reading the code you write, the "sugar" is poison to long term readability and maintenance.
Trying to get junior programmers just to understand all the built-in standard bits of a simple language like Java is bad enough. C++ is murderous in this regard.
In this same regard, I like some aspects of C++ that Java left out -- for my own personal use, but I'd never wish them on a project at a compan
Re:Java needs Macros, Badly (Score:2)
A program that looks like the problem is easy to understand for anyone who knows what the problem is.
Without syntactic sugar, all Java code looks like Java code, no matter what problem it solves. So there is a barrier to seeing the underlying task that is being accomplished.
You could call programmer-defined types as syntacti
Macro's are for the lazy (Score:2)
Re:Macro's are for the lazy (Score:2, Insightful)
Just about any tool/feature can be turned into a mess maker. There is no language that jabs stupid programmers in the eye when they get stupid (other than maybe crashing or buggin' out and being ha
Great... (Score:3, Insightful)
So the idea is to gain wider adoption by not implementing powerful features that might make code harder to understand. That should sound pretty familar to people who use VB... Not that there's anything wrong with that.
Macros are not macros! (Score:3, Informative)
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).
JCP? (Score:2)
Re:JCP? (Score:2)
Nonsense - the JCP is a community - a community of obedient followers of Sun's doctrine. Sun always knows what's best.