Want to read Slashdot from your mobile device? Point it at m.slashdot.org and keep reading!

 



Forgot your password?
typodupeerror
×
Java Programming

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."
This discussion has been archived. No new comments can be posted.

Why Java Won't Have Macros

Comments Filter:
  • I'm glad someone finally worked up the strength to tackle this difficult subject.

    -n

    • Difficult? I think it's a no brainer. Java should not support macros.

      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
    • I'd appreciate it, though I suppose I could run cpp on my java source, but I'd rather that javac handled it for me.
  • by Tumbleweed ( 3706 ) on Wednesday June 11, 2003 @11:46AM (#6171841)
    No macroth? Thath too bad. ;)
  • macros are useless, theyr just inline functions, if u want the extra performance boost for inline code, just declare a function final...
    • In this same sense, functions are useless because you can just write the code inline and use GOTOs. 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.
      • In this same sense, functions are useless because you can just write the code inline and use GOTOs
        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)

          by Procyon101 ( 61366 ) on Wednesday June 11, 2003 @03:48PM (#6174500) Journal
          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.
          • Gotos (Score:3, Informative)

            by r6144 ( 544027 )
            In some cases GOTOs are very useful, especially in languages like C for error recovery. Look at the many "goto error"s in Linux Kernel code, they cannot look as good in any other C way. Of course in java you don't need to manually destruct things so often, so gotos are not that useful. Multi-level exits are also an important use for GOTO, and IMHO block labels are similar but less readable.

            Also, some programs that does loops in irregular ways (such as non-recursive searching programs that backtracks) c

          • Or you could use a labelled break.
          • Re:useless (Score:3, Insightful)

            by j7953 ( 457666 )

            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.

            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.

            outermost: for (...) {
            //lots of nested for statements here
            if (something) {
            break outermost;
            }
            }

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

            In Ada,


            Top_Level_Loop:
            for I in 1 .. 100 loop
            for J in 1 .. 100 loop
            for K in 1 .. 100 loop
            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:3, Interesting)

        by reynaert ( 264437 )
        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...)
      • 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)

      by Tumbleweed ( 3706 ) on Wednesday June 11, 2003 @11:58AM (#6171992)
      > 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.
    • Re:useless (Score:5, Informative)

      by reynaert ( 264437 ) on Wednesday June 11, 2003 @12:07PM (#6172106)
      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 [ddj.com]. That presentation shows how easy it is to implement special syntax for automatons in Scheme, and how natural & simple the result looks.
      • could you post an example from outside the academic sense of comp sci in a language that anyone actually uses outside of academia?
    • Functions cannot bind variables. Here are some useful macros from Monday's release of BRL, a Scheme system in some ways similar to PHP.

      (define-input a b c ...)
      (define-cookie x y z ...)
      (define-session q r s ...)
      (define-path t u v ...)

      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.

    • There are plenty more features of macros than just inlining code (although arguably C++'s templates cover most of those).

      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)

    by sporty ( 27564 ) on Wednesday June 11, 2003 @11:54AM (#6171936) Homepage
    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.

    • by cookd ( 72933 )
      I like your idea of tying macros to objects (classes, actually). But they could be more than just inline methods.

      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:5, Insightful)

      by pauljlucas ( 529435 ) on Wednesday June 11, 2003 @12:27PM (#6172321) Homepage Journal
      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?
      • Macros have nothing to do with programming methodology (OOP, procedural, functional, etc).

        I understand that macros are an inline replace. But that's what the broad sense of a function is. When you get to this point, perform some functionality. I *know* that a function in c has to deal with throwing stuff on the stack, where as a macro is inline text-replacement.

        They look like called procedures.. THAT is my point. they are treated as such by the programmer though the compiler does something totally dif

        • You can use macros up the wazoo, but the program as a whole can still make heavy use of OOP. The fact that they can be seen as functions in some sense is irrelevant. An OO program uses functions, although they tend to be called methods. Hence using functions doesn't make a program any less OO.
          • Yeah, but when you stop using OO and start using Macros, you create a C mess. Procedural programming. If it's done lightly, everything works for the better. If you use it too much.. ewr. It'd require due dilligence of a group of programmers OR a very small grou of programmers doing "the right thing".
            • Yeah, but when you stop using OO and start using Macros...
              Nothing says that when you start using macros you have to stop using OO. They are not mutually exclusive.
              ... you create a C mess.
              You create a mess only if you are undiciplined and use macros badly. You can create a mess using any language construct.
              • Re:OOP (Score:3, Interesting)

                by sporty ( 27564 )
                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
      • Re:OOP (Score:3, Insightful)

        by reynaert ( 264437 )
        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?

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

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

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

          forEachLockedItem( item in items, foobar

    • Re:OOP (Score:5, Informative)

      by Dr. Photo ( 640363 ) on Wednesday June 11, 2003 @12:31PM (#6172382) Journal
      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 [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)

        by sporty ( 27564 )
        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

        • Re:OOP (Score:4, Informative)

          by Dr. Photo ( 640363 ) on Wednesday June 11, 2003 @01:14PM (#6172885) Journal
          It's not obvious to us all. I'm slightly confused on what exactly is happening. It looks recusive... though it prolly isn't.

          Actually, you're correct. It defines a syntax for a while loop by creating a function that does (in pseudocode):
          def loop() {
          if(test) {
          do_stuff_in_loop_body();
          loop();
          }
          }
          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)

            by sporty ( 27564 )
            But you see, that uncertainty, that new language I need to read, is what java develoeprs shouldn't have to deal with. It's like Java and SQL. EJB solves a lot of that, "I need to know SQL to get stuff from the DB." The exception is when you have to define finder functions in your configuration. Point is, it doesn't change how java looks. No syntax changes.

            That's prolly what java doesn't want. Syntax changes done by something like macros, or from what you've pointed out.
      • Macros are not necessary for making Generic programming. Last time I've checked Haskell didn't have macros. But I did Generic programming using Abstract Data Types.

        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, Insightful)

      by Tablizer ( 95088 )
      The problem with macros, is they sorta defeat Java's OOP.......Sounds awfully like a procedure/function to me.

      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
      • No, I'm stating what someone else in the thread mentioned. "Multiparadymed creamy goodness."

        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 :)
  • Interesting point. (Score:5, Interesting)

    by alyosha1 ( 581809 ) on Wednesday June 11, 2003 @11:58AM (#6171988)
    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.
    • 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.

      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

    • One of Java's biggest strengths is the fact that you can generally pick up and read somebody else's Java code, segment by segment, without having to grok the uber-design of the project. This code readability factor is huge. Another poster mentioned LFSP vs. LFM (languages for smart people vs. languages for the masses) - this division I think is real (though I would trash the loaded descriptors and call them "syntactically powerful languages" vs. "syntactically constrained languages").

      Java is clearly a s

      • you can generally pick up and read somebody else's Java code, segment by segment, without having to grok the uber-design of the project

        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

  • Thanks for the suggestion. Yes, we do know what macros are, and we may have even heard of Lisp. Seriously, some formulations of macros are well structured enough to prevent the onerous kinds of abuse that have given macros a dubious reputation in the C culture.

    A tacit admission that good text-replacement macros are a whole lot harder to do than S-expression macros, perhaps?
  • Sigh.. (Score:5, Funny)

    by DrunkBastard ( 652218 ) on Wednesday June 11, 2003 @12:09PM (#6172121) Homepage
    One less language to be used in obfuscated code contests. Where's the fun without macros and overloading? sigh....
  • Oh, macros, one "s". Gotcha.
    • Yo, moderators (Score:1, Redundant)

      by lightspawn ( 155347 )
      Overrated? How can the only moderation done to parent be "overrated" if it's never been rated before? "offtopic" perhaps, but "overrated"?

      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.

  • ... 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). :)
    • by reynaert ( 264437 ) on Wednesday June 11, 2003 @01:31PM (#6173074)

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

      • good lord that is awful code... thanks.

        but still: why is it bad?
        • That gives me an idea, you know if we #define 'begin' as '{' and 'end' as '}' we'd have finally made pascal useful :P (or is that 'c' useless).


          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?

      • Oh my god. ... Is THAT what the original UNIX source code looks like? I'm going to have nightmares now...
        --jeff++
        • Is THAT what the original UNIX source code looks like? I'm going to have nightmares

          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

    • by FroMan ( 111520 ) on Wednesday June 11, 2003 @01:58PM (#6173378) Homepage Journal
      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.
      • Well, what does that have to do with #define or ||?

        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.
    • the "and" and "or" macros you showed are in fact part of ISO C++ and C99. #include <iso646.h> (or ciso646 for C++) and see for yourself. Personally, I love 'em.

    • On the critical side:

      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
    • For the same reason the following:

      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
      • For the same reason the following:

        typedef int DWORD
        typedef char* LPSTR
        (yes, burn in hell Microsoft)
        are bad

        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

        • Quickly now, can you tell me if 'char' is signed or unsigned by default on your C++ compiler? Or how long is an 'int'?
          >>>>>>>>
          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
    • add an #include and you get much of that.
  • by ArmorFiend ( 151674 ) on Wednesday June 11, 2003 @01:31PM (#6173075) Homepage Journal
    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.

    Seriously, what's easier to read:

    // macro-less call
    {
    window.context().glxMakeContextCurrent();
    float[4] color = window.fgColor();
    glColor(color);
    glPushMatrix() ;
    glIdent();
    glAlphaBlend( GL_FALSE );
    ...non-boiler-plate-code...
    glAlphaBlend( GL_TRUE );
    glPopMatrix();
    }
    OR
    // macro call
    withGLDrawing (color) {
    ...non-boiler-plate-code...
    }
    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!

    • by reynaert ( 264437 ) on Wednesday June 11, 2003 @01:42PM (#6173197)

      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):

      OpenGL.withDrawing (color) {
      ...non-boiler-plate-code...
      }
      • I'll just point out you can easily put macro's in classes and use them like this (assuming you have an OpenGL class):

        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.
        • If you have higher-order anonymous functions in your language, than it's easy to do this kind of thing by turning the binding inside-out and making it an argument to the rest of the code. In general macros that bind variables or have effect are trouble, because, for one thing, the scope of declarations is "open."

          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
          • I understand your post and I agree that most macros can be rewritten as functions that take other functions. I provide an example of this below for other readers. But sometimes you can't. Other times its just too dang inconvenient.

            Common Lisp defines no "while" form. Nobody complains about this, because its easy to write a macro to implement while:

            ;; the macro definition
            (defmacro while (test &body body)
            `(do () ((not ,test)) ,@body))

            Here's a sample call that flips a coin until getting a tails, p

            • > Where "(\ () ...)" is my made-up syntax for introducing a function of 0 arguments with "..." as its body.

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

                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.

                Well, most languages also do not implement

                • > I think when you get down to the nitty gritty language implmentation most languages implement it as a macro with labels and
                  > 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
    • The example doesn't really add up -- stick that code in a utility class static final method and it'll inline. You probably wanted something that'd actually transform its input instead of just saving some typing. Most lisp macros need to work on the parsed form of the sexp that is their argument, splicing bits in here and there, inserting control statements or special forms that wouldn't work in a function. Java has neither the sexp format nor any special forms in such formats that would lend itself to a

      • The example doesn't really add up -- stick that code in a utility class static final method and it'll inline. You probably wanted something that'd actually transform its input instead of just saving some typing.


        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. :)
    • As opposed to
      someMethod(Object something, Method todo) { ... Do your prep stuff ...
      todo.invoke(something, null); ... Do your post stuff ...
      }

      Yeah, it's just sugar. It's a shame that more folks don't use reflection - it's mighty powerful stuff.
      • Yeah, it's just sugar. It's a shame that more folks don't use reflection - it's mighty powerful stuff.

        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?

        As opposed to

        someMethod(Object something, Method todo) {
        ... Do your prep stuff ...
        todo.invoke(something, null);
        ... Do your post stuff ...
        }

        That code snippet you posted seems to invoke a computed method (todo) on a computed object (something), and p

        • Huh. What is reflection? Traditionally it is the ability to ask an object what it's methods and/or variables are, grab them, tweak them, or invoke them. Really my snippet isn't a good example of reflection - you could do that with C++, which does not support reflection out of the box. Something like (I'm paraphrasing here - look up the java.lang.reflect stuff)

          someMethod = myObject.findMethodNamed("todo");

          is what relfection is all about. If that doesn't make reflection clear, bug me again and I'll div
  • Perl (Score:5, Insightful)

    by (trb001) ( 224998 ) on Wednesday June 11, 2003 @01:58PM (#6173375) Homepage
    given this statement

    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
    • > > 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

  • by __past__ ( 542467 ) on Wednesday June 11, 2003 @02:15PM (#6173573)
    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.

    • by Anonymous Coward
      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 compan
      • Syntactic sugar is harmful when it is just sugar. When it radically transforms your programming language to fit the problem domain like a glove, then it is an extremely powerful tool.

        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
  • While laziness can be a virtue for a good programmer, the truth is that Macros lead down that ugly slippery slope that ends in completely unreadable code. It may work great for a few programmers, however once you start working on large projects with many people coming and going you end up with a freaking mess.
    • While laziness can be a virtue for a good programmer, the truth is that Macros lead down that ugly slippery slope that ends in completely unreadable code. It may work great for a few programmers, however once you start working on large projects with many people coming and going you end up with a freaking mess.

      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)

    by MeanMF ( 631837 ) * on Wednesday June 11, 2003 @05:37PM (#6175732) Homepage
    Programming languages are cultural artifacts, and their success (i.e., widespread adoption) is critically dependent on cultural factors as well as technical ones.

    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.
  • by mrami ( 664567 ) on Thursday June 12, 2003 @08:50AM (#6180732) Homepage
    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).

  • I guess it shows just how much the Java Community Process is worth when someone from Sun comes out and says "Java will not have X because we say so".
    • I guess it shows just how much the Java Community Process is worth when someone from Sun comes out and says "Java will not have X because we say so".

      Nonsense - the JCP is a community - a community of obedient followers of Sun's doctrine. Sun always knows what's best.

He has not acquired a fortune; the fortune has acquired him. -- Bion

Working...