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

140 comments

  1. Finally! by Nathan+Ramella · · Score: 1
    I'm glad someone finally worked up the strength to tackle this difficult subject.

    -n

    --
    http://www.remix.net/
    1. Re:Finally! by Randolpho · · Score: 1

      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.

      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 Java. ;)

      --
      "Times have not become more violent. They have just become more televised."
      -Marilyn Manson
    2. Re:Finally! by Anonymous Coward · · Score: 0

      GCJ!! Just stop being addicted to sun's own classes like the crack whore you are

    3. Re:Finally! by MojoMonkey · · Score: 1

      That'd be great if you could get support for all the libraries you might use (i.e. AWT/Swing, Log, NIO, etc, etc). GCJ is only nice if you are doing very minimal Java apps.

      --

      ----- "Blame the guy who doesn't speak English." -- Homer J. Simpson
  2. in the Lisp sense? by Tumbleweed · · Score: 4, Funny

    No macroth? Thath too bad. ;)

  3. Re:on thecond thought... by Tumbleweed · · Score: 1

    That was an obviouth joke.

    Tho thue me.

  4. useless by ddd2k · · Score: 0

    macros are useless, theyr just inline functions, if u want the extra performance boost for inline code, just declare a function final...

    1. Re:useless by rmull · · Score: 1

      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.

      --
      See you, space cowboy...
    2. Re:useless by Tumbleweed · · Score: 4, Funny

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

    3. Re:useless by reynaert · · Score: 4, Informative

      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.

    4. Re:useless by ddd2k · · Score: 1

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

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

    6. Re:useless by bloo9298 · · 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.

    7. Re:useless by Elwood+P+Dowd · · Score: 5, Funny

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

    9. Re:useless by spongman · · Score: 1
      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++.

    10. Re:useless by LadyLucky · · Score: 1

      Or you could use a labelled break.

      --
      dominionrd.blogspot.com - Restaurants on
    11. Re:useless by maxgilead · · Score: 1

      boolean found = false;
      for (int i1 = 0; i1 MAX_I1 && !found; i1++) {
      for (int i2 = 0; i2 MAX_I2 && !found; i2++) {
      if (data[i1][i2] == x) {
      found = true;
      }
      }
      }

      No gotos, no breaks.

      Max

    12. Re:useless by j7953 · · Score: 2, Insightful
      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, 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;
      }
      }
      --
      Sig (appended to the end of comments I post, 54 chars)
    13. Re:useless by Anonymous Coward · · Score: 0

      You've just used a flag, which when set, has exactly the same effect as a break except it makes the code harder to read!

    14. Re:useless by Sir+Robin · · Score: 1

      if u want the extra performance boost for inline code, just declare a function final...

      No. Please read Java theory and practice: Is that your final answer? for a discussion of this "urban performance legend".

      --
      My /. ID is only 5,210 away from Bruce Perens's.
    15. Re:useless by DugzDC · · Score: 1

      'final' doesn't give you a performance boost in Java: http://www-106.ibm.com/developerworks/java/library /j-jtp1029.html
      I used to believe this one too, but it's actually an urbal myth. I can't remember where I heard it, but it sounded reasonable at the time.

    16. Re:useless by Anonymous Coward · · Score: 0

      how is this different froma GOTO?

    17. Re:useless by blancolioni · · Score: 1

      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.

    18. Re:useless by Master+of+Transhuman · · Score: 1

      What makes the expression "!Found" hard to read?

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

      --
      Richard Steven Hack - This sig is TOO GODDAMN SHORT TO DO ANYTHING USEFUL WITH! MORONS!
    19. Re:useless by karlm · · Score: 1
      You could think of it as a very constrained form of GOTO. The problem with GOTOs are they are often used to jump into the middle of blocks and other convoluted control flow "tricks". GOTOs are sometimes useful, but often abused, particulalry in the early years of C. Read Dijkstra's famous paper on the subject.

      It would be difficult to use labeled breaks to make code less readable. However, GOTOs are nearly essential in obfuscated C competitions.

      --
      Copyright Violation:"theft, piracy"::Anti-Trust Violation:"thermonuclear price terrorism"<-Overly dramatic language.
  5. OOP by sporty · · Score: 3, Informative

    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

    1. Re:OOP by cookd · · Score: 1

      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 language. "Shoot, I can't do that with that set of macros loaded, I need my own personal custom set of macros for this project..."

      --
      Time flies like an arrow. Fruit flies like a banana.
    2. Re:OOP by sporty · · Score: 1

      Ok, I'll bite. How do you tie = or == to an object syntatically?

      this->==(something) ? this->equals(something) already exists :)

      --

      -
      ping -f 255.255.255.255 # if only

    3. Re:OOP by pauljlucas · · Score: 4, Insightful
      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.
    4. Re:OOP by Dr.+Photo · · Score: 4, Informative

      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.

    5. Re:OOP by sporty · · Score: 1
      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 different, like inline functions.
      --

      -
      ping -f 255.255.255.255 # if only

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

    7. Re:OOP by pauljlucas · · Score: 1

      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.

      --
      If you reply, do so only to what I explicitly wrote. If I didn't write it, don't assume or infer it.
    8. Re:OOP by reynaert · · Score: 2, Insightful
      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..

    9. Re:OOP by sporty · · Score: 1

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

      --

      -
      ping -f 255.255.255.255 # if only

    10. Re:OOP by pauljlucas · · Score: 1
      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.
      --
      If you reply, do so only to what I explicitly wrote. If I didn't write it, don't assume or infer it.
    11. Re:OOP by Dr.+Photo · · Score: 3, Informative
      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.
    12. Re:OOP by Hard_Code · · Score: 1

      So override equals()

      --

      It's 10 PM. Do you know if you're un-American?
    13. Re:OOP by sporty · · Score: 2, Insightful

      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.

      --

      -
      ping -f 255.255.255.255 # if only

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

    15. Re:OOP by pyrrho · · Score: 1

      >Sounds awfully like a procedure/function to me.

      because we all know that procedures and functions are evil. Who want to go to hell just for a little convienience!? Oh, it's tempting, but just not worth it. God likes pure OOP. Don't think that means C++ style multi-paradigms OOP if you want it type OOP? That kind of OOP is condemned... stupid... and condemned!!!

      PS: a bit unfair of me... but fun! no offense intended sporty

      --

      -pyrrho

    16. Re:OOP by Anonymous Coward · · Score: 0

      No-one was talking about adding C-style macros to Java. The kind of macros proposed were more sophisticated "hygenic" macros, which can be used to add new control constructs to the language, etc. They would never be used as a crude way of implementing inline functions.

    17. Re:OOP by sporty · · Score: 1

      New constructs to java defined randomly by developer w/o java consortium == bad.

      It makes code messy.

      --

      -
      ping -f 255.255.255.255 # if only

    18. Re:OOP by sporty · · Score: 1

      lol, none taken. in your defense, nothing is wrong with procedural programming. just don't dirty one theology w/ the other, or otherwise you get C++, where you can do both. Yuck.

      --

      -
      ping -f 255.255.255.255 # if only

    19. Re:OOP by Tablizer · · Score: 2, Insightful

      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 one who started the paradigm war. As far as macros being good, I am on the fence on that one.)

    20. Re:OOP by pyrrho · · Score: 1

      :)

      I think what you are refering too is properly called "multiparadigmed creamy goodness".

      --

      -pyrrho

    21. Re:OOP by sporty · · Score: 1

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

      --

      -
      ping -f 255.255.255.255 # if only

    22. Re:OOP by axxackall · · Score: 1
      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.

      --

      Less is more !
    23. Re:OOP by chanceH · · Score: 1

      Don't talk bad about Perl

    24. Re:OOP by jasoegaard · · Score: 1

      > It's not obvious to us all.
      > I'm slightly confused on what exactly is
      > happening.

      I won't blame you - the example is bad.

      The idea of the macro system is that
      it is very easy to state the rewrite
      rules.

      Let us write a small or macro that works
      the same way as C.

      We want (my-or e1 e2 e3) to evaluate the
      arguments in turn and return the value
      of the first expression that is true and
      false (writen #f) otherwise.

      This way if e2 is true then e3 is never evaluated.
      [Of course this construct is already in the
      language, but it is a nice example].

      Let us see what rules we need.

      (my-or) becomes #f (false)

      (my-or e1) becomes e1

      (my-or e1 e2) becomes (let ([tmp e1])
      (if tmp tmp e2))

      This evaluates e1 and store the result
      in tmp. If tmp is true then the result is tmp.
      If tmp is false the result is e2.

      And in general if there is more than one
      expression after e1:

      (my-or e1 e2 ...) becomes
      (let ([tmp e1])
      (if tmp
      tmp
      (my-or e2 ...))))

      where I didn't bother expanding the (my-or e2 e3 ...).

      The macro system of Scheme allows us to write this as:

      (define-syntax my-or
      (syntax-rules ()
      [(my-or) f)
      [(my-or e1) e1)
      [(my-or e1 e2) (let ((tmp e1))
      (if tmp tmp e2)))]
      [(my-or e1 e2 ...) (let ((tmp e1))
      (if tmp
      tmp
      (my-or e2 ...)))]))

      Note that the macro introduces a new variable
      tmp. Even in the case that e2 uses the variable
      tmp it works. The macro system makes sure to
      "rename" our tmp variable so no name clashes occur. One calls this "hygienec macros".

      --
      -- A Mathematician is a machine for turning coffee into theorems. - Paul Erdös
    25. Re:OOP by Anonymous Coward · · Score: 0

      a very powerful and expressive way to have the entire language at your disposal at compile time.


      I write my code before compile time, so that's actually when it's most important for me to have access to the entire language. gvim and javac give me access to the entire language when I need it.

    26. Re:OOP by J.+Random+Software · · Score: 1

      I'd rather write just enough to let the compiler automatically insert all the trivial boilerplate it takes to make the code executable. Methods and exceptions are good examples--you get the "call this object's override" and "find the nearest handler on the stack" behaviors without explicitly mentioning them. A good macro system lets you add syntax like this to a language that didn't have those features.

    27. Re:OOP by ReelOddeeo · · Score: 1
      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( item ) );
      The macro expands to something like this...

      forEach( item in items ) {
      lock( item );
      foobar( item );
      unlock( item );
      }
      The macro function can go through whatever gyrations it wants to to transform the source into the replacement text at compile time. But then that replacement text is statically compiled.

      It seems irrelevant to me whether a macro is used in global procedures, or methods of an object.
      --

      Those who would give up liberty in exchange for security and DRM should switch to Microsoft Palladium!
  6. 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.
    1. Re:Interesting point. by Anonymous+Brave+Guy · · Score: 1
      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 extremes in the same sort of way that XP advocates taking things like unit testing to extremes. IMHO, you can go too far with all of these things, but it's quite hard to do so, and most people don't go nearly far enough.

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    2. Re:Interesting point. by Fnkmaster · · Score: 2, Insightful
      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 syntactically constrained language. As a programmer seeking to build a powerful library or problem solving toolkit for a complex application domain, this can be annoying. And several others have pointed out that this seems to keep resulting in people creating meta-languages (XML-based or otherwise), code-generators and the like for complex Java projects because they are needed to solve certain kinds of problems in an efficient manner. This is certainly true, and such systems can become rather ungrokable fairly rapidly. However, you can generally isolate such complexity from the hordes of mediocre developers who are there to pound out mediocre, simple code.


      With LISP, or even C/C++, the power is there all the time. Programmers will inevitably try to use the tools they learned about in school and _will_ shoot themselves, their development projects, and their managers in the foot. Java creates a hierarchical system of complexity - most Java code is universally readable, and if there is a need to learn special metalanguages (EJB descriptors for example), they are usually highly constrained XML dialects, separated out from the rest of the Java code. Sure, there's an XML parser and code generator that only one guy really understands and can maintain, but if that lets the rest of the development team pound away on their mediocre code in standard, vanilla Java, and edit some simple XML documents, then it makes software development more efficient.


      When you are managing mediocre people, you can appreciate the benefits of having them work in a language that prevents them from doing too much damage. Development is more predictable, bugs tend to be more apparent and less insidious, even though it's not always the most powerful or most efficient language for every problem domain. Of course, there are a lot of domains where you'd be crazy to try to use Java. And when you tackle those problems, you need to hire better developers who can handle the power of LFSPs (or at least languages with more foot-shooting power).


      And I consider Python to be comparable to Java in terms of readability. It is similarly somewhat syntactically constrained, with relatively few obvious mechanisms to accomplish a task, as opposed to way too many mechanisms to accomplish a task - and I love the forced code indentation as well (it forces consistency of style, another readability barrier). Where Python loses out is its far less comprehensive, standardized or well documented API, though I'm sure Jython has come quite a ways since I last looked at it (Python code + Java API - potentially a very good tool for scripting use in large Java projects). However, for larger software projects involving a large number of modules and many developers, a weakly typed language fails utterly - you need strict enforcement of method contracts and object typing that you get from a strictly typed language. This goes a long way to improving code readability and modularity for larger projects, and lets you catch many simple errors during compilation instead of having to rely on yourself to catch them all, or waiting until runtime to find problems ("oh, of course, I need to pass method foo an Orange object and two strings, not an Orange, a Grape and an integer").

    3. Re:Interesting point. by J.+Random+Software · · Score: 1
      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?

      Especially in this market, why are you even hiring "mediocre" (I'd say "unqualified") developers who can't handle packaging complexity or building toolkits to express the best solution to a problem?

  7. Heh heh heh... by Dr.+Photo · · Score: 1

    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?

  8. Sigh.. by DrunkBastard · · Score: 5, Funny

    One less language to be used in obfuscated code contests. Where's the fun without macros and overloading? sigh....

  9. But... that's my favorite anime! by lightspawn · · Score: 1, Funny

    Oh, macros, one "s". Gotcha.

  10. difficult enough without by Anonymous Coward · · Score: 0

    It's difficult enough without macro's, so why would you need them? The advantages of Java is that everyone can read a Java program and understand what is going on. User defined macros destroy that property.

  11. Yo, moderators by lightspawn · · Score: 0, Redundant

    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.

    1. Re:Yo, moderators by Anonymous Coward · · Score: 0
      Except it isn't funny, and it certainly started with a higher score (at 2 - you used your Karma Bonus) than it deserved. Actually, I'd say it'd have had too high a rating at 1, but you modding it up yourself certainly pushed it over the edge.

      It's quite possible for something to be overrated that hasn't been modded yet. In this case, the gratituous use of a +1 Karma Bonus together with the fact it was barely on-topic, content free, and not terribly funny, means overrated is probably the politest way of describing it...

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

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

    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!

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

    OpenGL.withDrawing (color) {
    ...non-boiler-plate-code...
    }
  16. Perl by (trb001) · · Score: 4, Insightful

    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

    1. Re: Perl by Black+Parrot · · Score: 1


      > > 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 on the concept rather than on the details.

      > (Cobol doesn't count just because the younger generation has never used it).

      I would say that Cobol is very readable - to the point of being tedious. (That's why we poke fun at it.)

      And not very abstract at all, at least in my limited experience with the way it is used.

      --
      Sheesh, evil *and* a jerk. -- Jade
    2. Re:Perl by Giggle+Stick · · Score: 1

      Insightful? Am I the only one who saw this as an obvious joke? The trb knows what abstraction means, he was making a connection between abstract in the obscure sense.

  17. 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.
  18. Re:Strange, I've been arguing about this all day . by torpor · · Score: 1

    good lord that is awful code... thanks.

    but still: why is it bad?

    --
    ; -- the corruption of government starts with its secrets. a truly free people keep no secrets. --
  19. Re:If this is what Jabba does, then Jabba will los by ArmorFiend · · Score: 1
    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.
  20. Higher-order functions mostly make macros obsolete by Tom7 · · Score: 2, Insightful

    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 powerful (nestable, higher-order). I program mostly in SML these days, and hardly ever wish I had macros.

  21. Re:youseless by Tumbleweed · · Score: 1

    Please to note my post said ' u ' to ' you ' - see the spaces? I put those there just for someone like you, Elwood. :)

  22. Java needs Macros, Badly by __past__ · · Score: 4, Insightful
    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.

    1. Re:Java needs Macros, Badly by dave_f1m · · Score: 1
      Java, and about every non-Lisp language, lacks syntactic extensibility.

      What about Forth(late 60's), Postscript(mid 80's), I'm sure others can jump in with many modern examples. - dave f.

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

    3. Re:Java needs Macros, Badly by Anonymous Coward · · Score: 0

      So junior programmers shouldn't have to learn? Why should they use a knife and fork when eating with their hands is so much easier?

      Why should they learn Java when VB initially seems so much easier?

      As time goes on, the computing "mainstream" of corporate drone-programmers slowly moves towards stuff real computing people have been doing for years. XML + associated X??? stuff is the emergence of cut-down Lisp-like technology on the scene. Some day in the future, the drones will be capble of grokking full lisp.

    4. Re:Java needs Macros, Badly by jaoswald · · Score: 1

      Talking about Lisp macros as if they were syntactic sugar misses an important point: the syntactic sugar is defined using the full Lisp language. It's potentially *very smart* sugar. You apparently understand this (you mention domain-specific languages), but I think it is important to emphasize that Lisp macros can be about code transfiguration, instead of just code sweetening.

    5. Re:Java needs Macros, Badly by jaoswald · · Score: 1

      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 syntactic sugar, which has the same hazard: unless the next programmer understands what your types are, he presumably can't understand your problem. But all users of OOP languages know that this isn't true. Imagine the argument: "all programs should use just the built-in types, so that every program can be read more easily."

      Well-designed user-defined types make the program easier to understand because you have created a language of types which reflects the problem domain. Well-designed user-defined code structures do the same thing, with a potentially huge gain in clarity.

      Admittedly, poorly-designed code structures can make the program hard to understand. But poorly-designed programs always are hard to understand.

  23. Re:Strange, I've been arguing about this all day . by PapaSMURFFS · · Score: 1
    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?

  24. Useful macros from Monday's BRL release by brlewis · · Score: 1
    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.
  25. Re:If this is what Jabba does, then Jabba will los by scrytch · · Score: 1

    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 macro facility like lisp.

    Anyway, if you really want to extend the language in a clean way, just use OpenJava like everyone else does. As long as OJ is developed independently from Sun, it stands more chance of being actually being useful and not crippled.

    --
    I've finally had it: until slashdot gets article moderation, I am not coming back.
  26. Re:youseless by Elwood+P+Dowd · · Score: 1

    Ack. Pthpt. [thump]

    --

    There are no trails. There are no trees out here.
  27. Re:Higher-order functions mostly make macros obsol by ArmorFiend · · Score: 1
    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, printing BORK for each heads flip:
    ;; the macro definition
    (while (plusp (random 2))
    (print 'BORK))
    IMHO this is prettier and more intuitive than the function-passing approach:
    ;; function call
    (while (\ () (plusp (random 2)))
    (\ () (print 'BORK)))

    ;; function definition
    (defun while (testfn bodyfn)
    (do () ((not (funcall testfn)))
    (funcall bodyfn)))
    Where "(\ () ...)" is my made-up syntax for introducing a function of 0 arguments with "..." as its body.

    This approach is what I'd call "too dang inconvenient". :) I think history bears me out that macros are the superior approach, as most languages do NOT implement while as a function. ;)

    Also there's an efficiency argument to be made against passing too many functions with "closed variables", as this will often cause those variables to be heap allocated instead of (faster) stack allocated. On the other hand 99% of the time you've got a fast enough computer to not care, but I have had times where the efficiency matters.

    To really get off topic, even for this thread, I like LISP macros, because they can do dangerous things like variable capture. Perl has almost every flow control construct binding $_ to the most recent interesting expression. If I wanted to add that functionality to LISP, I could easily do so without touching a line of source code. I create my own package that uses most of the symbols from the lisp package, but has its own definitions for if, while, etc:

    ;; "my:if" is this alternate-universe "if", which
    ;; binds "it" to the test caluse result.
    ;; "cl:if" is the normal lisp "if".
    (defmacro my:if (test then else)
    `(let ((it ,test)) (cl:if it) ,then ,else)))

    (defmacro my:while (test &body body)
    `(let (it) (cl:while ,(setf it ,test) ,@body))))
    Presumably users of these functions will intentionally refer to the symbol "it" to get the test result. That's all there is to Perl's $_. I don't think you can do this by passing around functions. (in any case not prettily :)
  28. Re:Strange, I've been arguing about this all day . by scrytch · · Score: 1

    the "and" and "or" macros you showed are in fact part of ISO C++ and C99. #include (or ciso646 for C++) and see for yourself. Personally, I love 'em.

    --
    I've finally had it: until slashdot gets article moderation, I am not coming back.
  29. Re:If this is what Jabba does, then Jabba will los by ArmorFiend · · Score: 1

    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. :)
  30. Macro's are for the lazy by MushMouth · · Score: 1

    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.

    1. Re:Macro's are for the lazy by Tablizer · · Score: 2, Insightful

      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 hard to debug).

      However, I will agree that some features can be downright ugly in the wrong hands. I would rather debug sloppy Pascal than sloppy Perl, for example. But, that might not necessarily be my same choice if it is my own code that I have to work with.

  31. Re:If this is what Jabba does, then Jabba will los by kwerle · · Score: 1

    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.

  32. Re:Higher-order functions mostly make macros obsol by Tom7 · · Score: 1

    > 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 simply in terms of other features in the language, and so it behaves rationally. You can't incur capture or otherwise violate the scope of variables (except in the ways that lisp already does), you can't change around the code that is passed in (except in the normal lisp way, again) and most importantly a programmer can look at a piece of code and know "what it does" at the same level as he looks at other code. For the uses of macros that I think of as good coding practice, this is certainly possible.

    > This approach is what I'd call "too dang inconvenient". :) I think history bears me out that macros are the superior
    > approach, as most languages do NOT implement while as a function. ;)

    Well, most languages also do not implement it as a macro. As a lisp programmer, do you REALLY want to argue that the popular historic ways is the superior way? (In fairness, I think you have a good argument, but this isn't it!!)

    > Also there's an efficiency argument to be made against passing too many functions with "closed variables", as this will often
    > cause those variables to be heap allocated instead of (faster) stack allocated. On the other hand 99% of the time you've got
    > a fast enough computer to not care, but I have had times where the efficiency matters.

    I don't know what "closed variables" means; do you mean an environment? Who says a compiler has to heap-allocate closures? There is an efficiency issue, sure, but this is not something that the programmer should have to deal with. A good optimizer should be able to tell that inlining the 'while' function turns its arguments into beta-redices, and then you end up with the same code that the macro pre-compiler produces.

    > I don't think you can do this by passing around functions.

    No, because this is precisely the kind of hack that makes lexically-scoped functions nice and macros unhygienic! ;)

  33. Re:Strange, I've been arguing about this all day . by Beryllium+Sphere(tm) · · Score: 1

    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 always executing the body at least once. Ouch.

    They're also bad if you are a believer in the philosophy "syntactic sugar causes cancer of the semicolon" (Alan Perlis).

  34. Re:youseless by Fjord · · Score: 1

    That was pretty smart of u.

    --
    -no broken link
  35. Great... by MeanMF · · Score: 2, Insightful

    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.

  36. preprocessing? by SHEENmaster · · Score: 1

    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.

    --
    You can't judge a book by the way it wears its hair.
  37. Re:Higher-order functions mostly make macros obsol by ArmorFiend · · Score: 1
    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 [while] as a macro. As a lisp programmer, do you REALLY want to argue that the popular historic ways is the superior way? (In fairness, I think you have a good argument, but this isn't it!!)


    I think when you get down to the nitty gritty language implmentation most languages implement it as a macro with labels and goto. That their macro language isn't exposed to the user is not completely germane.

    I don't know what "closed variables" means; do you mean an environment?

    Exactly.
    Who says a compiler has to heap-allocate closures?

    Well, consider we've got our "while" implemented as a function in while.o. All the callers of "while" in foo.o, bar.o, and baz.o pass stack allocated environments to while. While looks like this:
    void
    while (test_fn, body_fn)
    {
    for(;test_fn();)
    body_fn();
    }
    Then late one night a disgruntled employee does this:
    void
    while (test_fn, body_fn)
    {
    static bool old_test_fn (void) = function_which_always_returns_false;
    for (;old_test_fn();)
    body_fn();
    old_test_fn = test_fn;
    }
    This means that the nth call to while will use the (n-1)th call's test clause. The next morning your "make world" rebuilds while.o, but in the meantime foo.o, bar.o, and baz.o will still pass stack allocated environments to a function that expects the environment to be valid across multiple calls. Bus errors ensue. 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. The optimizer can't make the decision unless its inlining the function call. (And sometimes you can't inline function calls, like when you compute which function you'll be calling :)


    No, because this is precisely the kind of hack that makes lexically-scoped functions nice and macros unhygienic! ;)

    I love that word when applied to macros! I feel sooo dirty :)
  38. Java reflection by ArmorFiend · · Score: 1
    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 pass it a constant argument (null). This is reflection?

    1. Re:Java reflection by kwerle · · Score: 1

      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 dive into it a bit more.

  39. Re:Strange, I've been arguing about this all day . by be-fan · · Score: 1

    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 understanding what do_foo() is and what it does is outweighed by the time and energy saved reading and understanding all the code in do_foo(). Now, in these other examples, the intellectual overhead is relatively high (if only because a programmer can easily become suspicious that those macros must be doing something more, because why would anyone create such a simple 1:1 mapping to a built-in feature) and the payoff is zilch, because C programmers except to see || rather than 'or'.

    --
    A deep unwavering belief is a sure sign you're missing something...
  40. academia by sporkboy · · Score: 1

    could you post an example from outside the academic sense of comp sci in a language that anyone actually uses outside of academia?

    1. Re:academia by Anonymous Coward · · Score: 0

      People "outside academia" (if you mean the masses of grunts who never read research papers and go on coding like it's still 1980) generally aren't smart enough to adopt sophisticated languages with features like this. Or rather, their leads stick to dumbed-down C and BASIC variants and their teams don't care enough to push back.

  41. Re:Strange, I've been arguing about this all day . by statusbar · · Score: 1

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

    --
    ipv6 is my vpn
  42. Re:Higher-order functions mostly make macros obsol by Tom7 · · Score: 1

    > 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 do cross-module optimizations, and in this case a proper leaf procedure where the argument functions don't escape (like the original implementation of while) could be called with pointers to closures on the stack without any problem.

  43. Gotos by r6144 · · Score: 2, Informative
    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) can be rewritten in a way that is much more readable IMHO. Alas, it is still as hard to make sure such code is correct, since you still have to follow every possible execution path, so it doesn't make the writer's life better.

  44. Re:Strange, I've been arguing about this all day . by spongman · · Score: 2, Insightful
    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. Using the typedefs you will always know that a DWORD is an unsigned 4-byte value and a LPSTR is a pointer to signed bytes.

  45. Re:Strange, I've been arguing about by Anonymous Coward · · Score: 0

    Red Alert: To anyone reading Piers Haken aka Spongman's posts.

    He is a liar who claims to have worked at Microsoft (he thins this justifies his blind Microsoft zealotry). The loser who never really worked there.

    He now works as a low end grunt at a dead .com pontificating bullshit and misinformation on Slashdot.

    He is basically your run of the mill Iraqi Information Minister Muhammed Saeed al-Sahaf of programming, minus any interesting humor and a bunch of IQ.

  46. Re:useless - useless explains piers haken by Anonymous Coward · · Score: 0

    Red Alert: To anyone reading Piers Haken aka Spongman's posts.

    He is a liar who claims to have worked at Microsoft (he thins this justifies his blind Microsoft zealotry). The loser who never really worked there.

    He now works as a low end grunt at a dead .com pontificating bullshit and misinformation on Slashdot.

    He is basically your run of the mill Iraqi Information Minister Muhammed Saeed al-Sahaf of programming, minus any interesting humor and a bunch of IQ.

  47. Re:Strange, I've been arguing about this all day . by Anonymous Coward · · Score: 0

    You are a fucking god damn cum guzzling fucking queer. Not a normal homosexual, but a smelly dog-raping boi-loving sociopathic fucker. Man, you make me sick. For those of us who know of you, we know about your little nightly soirees with married men at various turns off in the Bay Area. You are a fucking anal madman. But people are going to find out you are a bug donator, giving disease not only to bug-chasers but innocent gays, women and other helpless beings.

    Now you come here, and plausibly deny your true Hydian self with this facade, the charade, this act. You, a programmer for a dead .com and a former Microsoft droid.

    The entire summation of your existence is nothing. You have a hard time accepting this. You are a blip. A genetic mistake. A poster child for birth control and legal abortions. You are the reason that the death penalty isn't easily abolished.

    We see at the DNA lounge. We know you are there, seeding hepatitis on toilet seats.

  48. Re:Strange, I've been arguing about this all day . by varjag · · Score: 1

    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.

    --
    Lisp is the Tengwar of programming languages.
  49. Re:Strange, I've been arguing about this all day . by FroMan · · Score: 1

    Please re-read the original post I was replying to and the one I wrote. Thanks.

    I personally do like the macro capability of C. I think it is a useful tool for putting common code in places where a function is overkill. Like doing a bitwise operation, such as in fcntl.h (if memory serves) for checking read/write permissions on files.

    --
    Norris/Palin 2012
    Fact: We deserve leaders who can kick your ass and field dress your carcass.
  50. 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).

  51. Re:Strange, I've been arguing about this all day . by varjag · · Score: 1

    Please re-read the original post I was replying to and the one I wrote. Thanks.

    I was browsing at +4, and the direct parent didn't make it through. Sorry for the way-off reply.

    --
    Lisp is the Tengwar of programming languages.
  52. Re:Strange, I've been arguing about this all day . by FroMan · · Score: 1

    No problem... try at +2 or +3. And set to ignore karma bonuses. Usually the s/n ratio is adequate at that level.

    --
    Norris/Palin 2012
    Fact: We deserve leaders who can kick your ass and field dress your carcass.
  53. Re:Strange, I've been arguing about this all day . by Anonymous Coward · · Score: 0

    Functions were only "overkill" when compilers weren't smart enough to inline them.

  54. Re:Strange, I've been arguing about this all day . by Anonymous Coward · · Score: 0
    "int" is at least 16 bits, and "char" may or may not be signed. Focusing on whatever the compiler you're currently using does is wrongheaded.

    Strictly-sized typedefs have value for defining file formats or wire protocols, but it's better to use native types everywhere else. But Microsoft's are pretty lame--they implicitly claim "word" means 16 bits when in fact it's the machine's word size (usually 32 bits today), and LPSTR is pointlessly obscure (if it's always "char *", what's wrong with writing "char *"?).

  55. Re:Strange, I've been arguing about this all day . by FroMan · · Score: 1

    #define IS_EXECUTABLE(x) x&0x01

    Do you really think that is worth creating a function? I don't think so. Especially if you are going to document it. /*
    * And input against executable bit mask.
    * x is an input bitfield
    * returns non zero if input is executable
    */
    int is_executable(int x)
    {
    return x & 0x01;
    }

    Nope, not worth it in my book. You cannot rely on your compiler to optimize it out. It'd be nice to assume every compiler will, but you simpley cannot know for sure it will. Some embeded compilers are not upto snuff with icc or gcc. Sure, you can specify "inline" however just as with the "register" keyword it is only a hint to the compiler.

    --
    Norris/Palin 2012
    Fact: We deserve leaders who can kick your ass and field dress your carcass.
  56. Re:Higher-order functions mostly make macros obsol by Anonymous Coward · · Score: 0

    What makes you think the heap is slower? A copying collector (unlike malloc/free) can allocate memory by bumping one pointer. And you don't have to copy an object to allow it to live beyond the current funcall. And you get continuations for free.

  57. Re:Strange, I've been arguing about this all day . by Anonymous Coward · · Score: 0

    I'd go for the function, no question. It requires no more documentation than the macro. It's typesafe and never re-evals its arguments. The debugger can step through it. In C++ it's confined to a namespace (things don't blow up randomly if someone wants to name anything else IS_EXECUTABLE), can be overloaded for your own types, and passed to higher-order functions ("how many objects in this collection are executable?"). If your code generator sucks, the extra funcall is the least of your worries.

    And macros are error-prone. For instance, yours should be ((x) & 0x1) so that complex expressions inside or around it are parsed correctly.

  58. Re:Strange, I've been arguing about this all day . by Eponymous+Coward · · Score: 1

    add an #include and you get much of that.

  59. Re:Strange, I've been arguing about this all day . by spongman · · Score: 1
    well I'll agree with you that "word" is overloaded here, but Microsoft's definition of "WORD" is constant.

    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.

  60. Re:Higher-order functions mostly make macros obsol by ArmorFiend · · Score: 1
    What makes you think the heap is slower?

    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 spam became important used a "mark & sweep" GC algorithm. In our case it wasn't the allocation time that was killing us, but the frequency & expense of the GC getting too high.
  61. Re:Strange, I've been arguing about this all day . by be-fan · · Score: 1

    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 sizes because of range issues, then you're supposed to use the standardized limits headers. Microsoft's tendency to redefine standard features like this is just one of the reasons why Win32 sucks so badly compared to POSIX.

    --
    A deep unwavering belief is a sure sign you're missing something...
  62. Re:Strange, I've been arguing about this all day . by Anonymous Coward · · Score: 0
    I've never seen any documentation specifying that LPSTR shall always be signed or unsigned. In fact, my copy of says "typedef char CHAR;" and "typedef CHAR *LPSTR, *PSTR;", so it depends entirely on CFLAGS.

    And somehow I don't think they meant to use a nonstandard meaning of "word". They just started using it in a short-sighted way and then had to declare it incorrectly (memorializing their ignorance) for Win32 and Win16 to be compatible. Probably the same people who think a "byte" is always eight bits instead of using "octet".

  63. Re:Strange, I've been arguing about this all day . by spongman · · Score: 1
    I've never seen any documentation specifying that LPSTR shall always be signed or unsigned. In fact, my copy of says "typedef char CHAR;" and "typedef CHAR *LPSTR, *PSTR;", so it depends entirely on CFLAGS.
    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?
    And somehow I don't think they meant to use a nonstandard meaning of "word". They just started using it in a short-sighted way and then had to declare it incorrectly (memorializing their ignorance) for Win32 and Win16 to be compatible. Probably the same people who think a "byte" is always eight bits instead of using "octet".
    I'm sorry, what was I thinking. I must have forgotten for a second that everything Microsoft does is complete trash and everyone that works there are complete fools. How very un-slashdot of me.
  64. Re:Strange, I've been arguing about this all day . by Anonymous Coward · · Score: 0

    If your point is "LPSTR is always signed", as far as I can tell you're mistaken. I never believed that or even heard anyone claim it until today, the docs don't say so, and <winnt.h> from the Platform SDK doesn't try to make sure it is (neither do the Visual Studio 6 headers, and Visual C++ can go either way depending on the /J option). Can you substantiate this at all?

    Where do you get "everyone at MS is complete fools" out of what I said? I know people there, and they aren't. "Byte" and "word" date back to, what, the 50s? Ignorance about them is widespread, and it only took one sloppy maintainer to codify a mistake that really can't be fixed.

  65. JCP? by MrBlack · · Score: 1

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

    1. Re:JCP? by truth_revealed · · Score: 1

      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.

  66. if you really want macros by f00zbll · · Score: 1
    write one! anyone can go download JavaCC or any of the free compiler compilers out there to generate a macro language and distribute it freely. Quit your yapping and just do it already. My biased feeling is, prove it is worth including first and then show it's value with real-world examples. Look at the new expression language support in JSP2.0 spec. It came out of the need for an easy way to write simple dynamic pages. People can bitch all you want about how bad the JCP is, but Sun has generally been fair about adding specs and standards when there's a clear demand from the community.

    Things that appear to be on the fringe, Sun ignores it. Is that bad? Ask yourself this "do I have time to follow every thought and request of my customers every minute?" The answer is probably going to be "no, I have limited time and resources."

    Only thing whiners achieve is noise. Do something about it and become part of the JCP, write a reference implementation and get other developers to support it. What's so hard to understand about the process? It's call process because it takes time and effort, otherwise it would be called "java magic lamp" and anyone could just make a wish.

  67. Re:If this is what Jabba does, then Jabba will los by Anonymous Coward · · Score: 0

    I think you've confused C macros with
    Lisp macros (hygenic and non-hygenic).

    The two are quite different. C macros are
    extremely simple; kinda like comparing ed
    to emacs.

  68. Re:If this is what Jabba does, then Jabba will los by ArmorFiend · · Score: 1

    The article, and my post, are talking about Lisp macros. Well the article is more talking about scheme macros, while I'm more talking about (wacky, dangerous) Common Lisp macros. The reason the CL macs are wacky and dangerous is because novices often write macs that do unintentional variable captures and unintentional muliple evaluations of the same form.

  69. Bourne shell source by js7a · · Score: 1
    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.

  70. Re:Strange, I've been arguing about this all day . by Anonymous Coward · · Score: 0

    you know, haken, he nails your fucking ass in the following arguments.

    anyone with any technical acumen does.

    you are a liar, farud jack of all trades master of none fucking fool. your fucking bullshit is not needed here. you fucking liar. fraud. what a stupid motherfucker. i nailed your ass. i nailed it. i fucking nailed you in lies and nailed you in your fucking flawed thinking. i love watching you get bitch slapped by others, too. FUCKING FOOL.

  71. Macros can be a godsend by NFNNMIDATA · · Score: 1

    Macros are great if you have a lot of repetitive code that you can't get around doing (i.e., you can't just create and call a method/function to do xyz for whatever reason). This doesn't happen in Java much, at least not that I have found. But I used to have to do data processing in this obscure, unmentionable scripting language, and once I taught myself the macro syntax I was able work faster and make the QA dept's life a lot easier.

  72. OOP vs. Procedural by Anonymous Coward · · Score: 0

    I'd be willing to bet a good bit of money that you have little or no significant real-world programming experience.

  73. Re:Strange, I've been arguing about this all day . by mysidia · · Score: 1
    1. Since the macros represent copy and paste, they are no use. It's more effective to simply do ==, &&, ||, etc, then is, and, and or. There is no benefit to the programmer.
    2. The macros can have unexpected results: now perfectly syntactically valid structures such as int is = 1; will generate syntax errors in your program, because int || = 1; is agrammatical in C, but since they are not reserved words, int is = 1; should be perfectly ok. There are conventions for the names of macros, and #define is ... does not follow them, and in particular lowercase is is quite possibly the name of a function parameter or local variant.
    3. Those macros are not part of the C programming language and as such may cause confusion whenever a C programmer reads the program. For instance, raising questions like, is your or macro a C logical or or a comparison or ? What is is realy be: comparison or assignment ? The C operators; however, are well-defined and anyone who purports to be a C programmer is not really one unless they know them all very clearly.
    4. The order of operations for your macros may not be clear, or it may be unexpected. Consider that in C, && has a higher precedence than ||, and so will your and have over or, but when a programmer reads the long-hand names, the property is quite possibly counterintuitive.
    5. The macros are an idiosyncracy of whatever programs uses them.
  74. Re:Perl is the language for smart people?! by Anonymous Coward · · Score: 0

    No, but please go ahead. Declare PERL the language of choice for under-ego'd nerds with thier heads up thier own buts, a desire to overcomplicate everything and prove themselves by coding unmaintainable line-noise in as 'clever' a mannner as possible and no appreciation of Martin Fowler's comment that "any fool can write a program that a computer can understand. The difficult thing is to write code that other people can understand"

  75. Re:Strange, I've been arguing about this all day . by torpor · · Score: 1


    The order of operations for your macros may not be clear, or it may be unexpected. Consider that in C, && has a higher precedence than ||, and so will your and have over or, but when a programmer reads the long-hand names, the property is quite possibly counterintuitive


    That sir, is a very good point and I thank you for pointing it out in this argument ... which has long since been beaten into the dust and forgotten about on the other forum I was discussing it, but I will remember this particular bit of intel for future use ... Ta! :)

    --
    ; -- the corruption of government starts with its secrets. a truly free people keep no secrets. --
  76. Re:if you really want a syntax extension by bjsyd70 · · Score: 1

    You can do what iContract, sqlj, and jsp did and invent one from scratch.

    If you are Sun you can add to the language. Some kind of "for each" is being added to JDK 1.5.

    The two views that I vacilate between are:

    1. Java sux and should be dumped for Lisp, Python or Ruby

    2. Java is widely used and macros will help it evolve