Slashdot Mirror


Why Java Won't Have Macros

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."

8 of 140 comments (clear)

  1. 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.
  2. Re:useless by reynaert · · Score: 2, Interesting

    I think the readability argument is bogus: you could say exactly the same about every form of abstraction (functions, classes, ...). Of course, if you have a brain dead macro system as in C and you do things like:
    #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...)

  3. Re:OOP by sporty · · Score: 2, Interesting
    I think you ran into the same problem that a lot of Java purists may have. They want java to look like java and not have a language inside the code which does neat syntatical stuff. Not that it's bad intrinsically, after all what is? :)

    Lemme also take a segment from what your link has.



    (define-syntax (while stx)
    (syntax-case stx ()
    [(_ test body)
    #'(letrec ((loop (lambda () (if test (begin body (loop))))))
    (loop))]
    [else (raise-syntax-error 'while "Illegal syntax in while loop" stx)]))

    Notice in that code fragment how obvious it is what's happening, even if you don't know Scheme



    It's not obvious to us all. I'm slightly confused on what exactly is happening. It looks recusive... though it prolly isn't.
    --

    -
    ping -f 255.255.255.255 # if only

  4. 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. --
  5. 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.

  6. 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 */
    }

    if (pid == 0) { /* parent */
    } else { /* child */
    }
    }

    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.
  7. Re:OOP by sporty · · Score: 2, Interesting

    You are absolutely right. You odnt' have to stop using OO. Point is, you'll start mixing theologies. You'll have objects calling a mess of procedures.

    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 macros are kinda like, code written in place with no object ties, though I know it is inline text replacements, you can have macros call other macros, call objects, call other macros to a very large mess.

    Macros do one thing really well.. it allows you to write clean looking code.. in an inline way. But it's easier to write spaghetti code, everything calling everything else with procedural programming. You can effectively create this mess with macro programming.

    --

    -
    ping -f 255.255.255.255 # if only

  8. Re:Java needs Macros, Badly by Anonymous Coward · · Score: 2, Interesting

    Syntactic sugar is generally harmful.

    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 company I work for.