MACROS in Java

Programming, for all ages and all languages.
creichen

Re:MACROS in Java

Post by creichen »

Mystran,
mystran wrote: Let me first make it clear that I was completely ignoring all implementation issues, and as such I didn't quite realize that if someone WOULD consider implementation, then some of my choices for terms might have meaning, and a mess would result. Sorry about that. :)
Ah... different interpretations of the same terms... everyone's faviourite conflict generator raises its head again ;-)
In that case, I also apologise, for I should've tried to look for potential misunderstandings as well.

mystran wrote: But you notice that C++ templates and Java generics are equivalent in terms of compile-time checkability. Only when we consider separate compilation (which is overrated anyway) are they different (in terms of compile-time chekability, that is).
They're not equivalently type-checkable if we also allow value parameters to types (recall that type checking in this case can be reduced to the halting problem). So let's restrict templates to type parameters beforehand. In this case, as I've tried to outline in my last mail, there is still the significant difference that Java's (so-called F-bounded) polymorphism allows type parameters to be constrained by a given type; C++ does not allow this (and, instead, uses implicit constraints which solely depend on whichever methods you may happen to wind up calling).

This means that in C++ you produce a type error here if your actual type parameter doesn't meet the requirements of the formal type parameter if and only if some method you happen to call winds up using a method not defined on this type, whereas in Java you produce a type error at the point where you pass the type parameter if you do not meet the requirements of the parametric type. So, first of all, Java constraints are placed explicitly "up-front", whereas C++'s constraints are implicit. Second, Java constraints are checked at formal-type-parameter-passing time (analogously to Haskell and its type classes, by the way), whereas C++'s constraints are checked at method invocation time.

I would like to point out here that Java's approach has one significant software engineering benefit: If you know the requirements up front, you can verify not only that you export the neccessary methods, but also that they exhibit the desired semantics (for example, a common requirement is that the "+" operator should be associative for anyone defining it, but C++ does not-- and could not if it wanted to-- enforce this property): The library designer is forced to specify an interface that lists all methods (and hopefully defines their properties, though this cannot be checked) in Java, for otherwise the library will not compile, whereas in C++ it can't be compiled up front anyway, so the library designer can get away (even by accident) with using methods on the parametric types which haven't been specified in whichever documentation he may have elected to write.

On a final note, I disagree about separate compilation being overrated-- I rather appreciate not having to recompile my libc every time I compile my own piece of code, and would appreciate it if this property would extend to all other libraries I wind up using. Compilation is supposed to be approximately linear in the size of the program; without separate compilation, you have to include (for each unit of compilation) potentially all information from the other units of compilation, making compilation time quadratic on the size of the program. Considering that there seems to be little benefit in doing this as default behaviour (as opposed to, perhaps, a final optimising-by-cross-module-inlining stage (or whole-program optimisation, as in MLton) before shipping the resulting program), as most compiles tend to be for type checking and testing in the end, I personally don't see why this would make sense. Recall that most other languages seem to get away with modular compiling.


on RTTI:
mystran wrote: You might want that for GC though.
For what Microsoft called "Managed C++", yes. Full C++ has too many ugly features to admit proper gc, unfortunately (though there are conservative approximations to this which, however, are neither completely safe for the full language nor particularly efficient).

[...to be continued...]
creichen

Re:MACROS in Java

Post by creichen »

[...continuation...]
mystran wrote: That's my point. No type errors can occur at runtime. If you don't do downcasting (eg. from parent to child) in C++ or Java, then they are type-checkable in the same sense, and can hence be called "static with some loopholes".
That name makes sense, and I'd even apply it to C++/Java with downcasting (for both have a handful of loopholes; C++ (of course) more so).
mystran wrote:
IIRC, only lazy languages (such as Haskell), which need to potentially "force" their "thunks" in this case, implement it as such (but, as indicated, for a good reason).
I don't quite understand what you are trying to say here.
Yes, this was rather badly placed by me... technically, you don't need dynamic dispatch for values even here, but it turns out that if you often have to "force" chunks, you might as well represent all values (even computed ones) by function calls, pass a table with the jump adresses of all the cases you might want to dispatch to, and then have the value decide for itself whether it wants to compute itself or, rather, should proceed to any of the locations in the dispatch table.

(This is my recollection of how lazy languages implement this, but I haven't double-checked this. Feel free to flame me if I'm wrong here...)


Anyway, I think we're in general agreement about the technical stuff, with the only disagreement being on whether separate compilation is overrated or not (which is rather hard to come to a definitive statement about ;-)

-- Christoph
creichen

Re:MACROS in Java

Post by creichen »

Hi,
Solar wrote:
Ch. Reichenbach wrote: (1) You can compile programs with generics/parametric types in separation from programs with template type parameters; in particular, you can build libraries of them. Compare this to the C++ STL where typically most or all of the implementation is part of the header files.
"export" has been part of the C++ standard since 1998. It's only that compiler vendors so far haven't put much of an effort behind actually implementing it (except for the EDG compiler). With "export", template declaration and definition could be properly seperated, too.

Blame the vendors, not the language. ;)

Other than that, I'm not that much into Java internals, so I can't really comment.
Interesting, I didn't know that "exporting" templates had been seriously contemplated. Would you happen to have a reference to the appropriate part of the C++ '98 language definition, or to a description of how they implemented it? I would be very interested in learning more about this, because I can't come up (off the top of my head) with any mechanism that would implement something like the mechanism you suggested in a way that would truly allow separate compilation. Some inference mechanisms as for type classes might work, but this wouldn't work with value parameters in templates. The best I can come up with would be to export the intermediate representation of templates, but that's not really much better than reading in templates from header files... but I'm making up stuff here. Unfortunately, the only thing I could find on their web page was that the "export" keyword for templates is implemented ;-)

-- Christoph
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:MACROS in Java

Post by Colonel Kernel »

Ch. Reichenbach wrote:Java constraints are checked at formal-type-parameter-passing time (analogously to Haskell and its type classes, by the way), whereas C++'s constraints are checked at method invocation time.
Nope. C++'s constraints are checked at compile-time, not run-time. The difference from Java is that the constraints in C++ are purely syntactic in nature. Some efforts have been made to formalize these constraints a bit, and provide some infrastructure:

http://www.boost.org/libs/concept_check ... _check.htm
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
creichen

Re:MACROS in Java

Post by creichen »

Hi,
Candy wrote:
Joel (not logged in) wrote: Also, Java achieves this ability primarily through constraining...
Which is something C++ doesn't do and for which I very much prefer C++. Allow me to make the choices, I'm a software engineer for a good reason.
Apologies for the off-topic remark here, but since there appears to be some interest in people's personal preferences, please allow me a side note here: I personally rather like being able to constrain myself in ways that allow the type checker to catch many of my programming errors (which is why I'm rather unhappy with the limitations Java has when it comes to allowing people to restrict themselves).

I've noticed, however, that there seem to be two fundamentally different approaches to programming people take-- the "Genius" approach (think about it while you write it, let your intuition guide you) and the "Design by Restriction" approach (think about as much as possible first, design your signatures and functors (or modules or interfaces or whatever they're called in the language you're using) first, then only fill in what you've already decided upon). If there is interest in discussing this (very interesting, IMHO) topic, we should start a new thread, though.
Candy wrote:
... all its objects to be referenced by pointer and to be a subclass of an ultimate base-class (Object) in a single-inheritance hierarchy. Under the same constraints, you can expect to see similar abilities in C++.
Which means that c++ can already do what Java could do with those generics. And it can do more. Which part of it being able to do more don't you like?
Even though it wasn't my mail that the response was to, I would like to object to this rather provocative tone, though your question in itself is quite interesting.

Recall that no-one can do more than plain assembly with m4; expressivity is not an issue once we've agreed that all the languages we're working with are Turing complete. But expressivity is only one of the properties that make up a language-- safety is another, and (as I've tried to explain) Generics seem considerably safer to me than templates do in cases where the latter are used to simulate parametric polymorphism.

-- Christoph
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:MACROS in Java

Post by Colonel Kernel »

I should have been more specific... constraints in C++ are checked at template instantiation time. A little more specific than "compile-time"... it's a subtle but important point, especially when trying to make sense of nasty template-induced compiler errors.
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
creichen

Re:MACROS in Java

Post by creichen »

Hi,
Colonel Kernel wrote:
Ch. Reichenbach wrote:Java constraints are checked at formal-type-parameter-passing time (analogously to Haskell and its type classes, by the way), whereas C++'s constraints are checked at method invocation time.
Nope. C++'s constraints are checked at compile-time, not run-time.
Right, my apologies. I meant to say that these constraints are checked at compile time, but at the location of the method invocation (and only if the offending method is invoked).

Thanks for pointing out my mistake!

I also wasn't aware of the research on the topic of constraining template parameters you referenced, thanks for the link! Templates with this BCCL restriction language might be a rather different beast than the Templates we find in C++ today indeed. (The relevant publication seems to be at http://www.oonumerics.org/tmpw00/siek.pdf, by the way, if anyone else is interested).

-- Christoph
Joel (not logged in)

Re:MACROS in Java

Post by Joel (not logged in) »

Even if C++ templates can't be compiled up front, I'm not sure I see any reason why a compiler can't check for obvious type errors up-front. Naturally, this would require some different scanning rules from processing items whose types are all known ahead of time, but it seems like it should be possible.
Schol-R-LEA

Re:MACROS in Java

Post by Schol-R-LEA »

Ch. Reichenbach wrote: [...continuation...]
That can't be right - C++ doesn't support TCO... :)


(On a side note, there's a group lobbying Sun to add continuations to JVM. I find that a bit weird, but it could be interesting if they don't make it too complicated to be usable.)
mystran

Re:MACROS in Java

Post by mystran »

I guess most of us are trying to argue essentially the same points so I don't see a point in trying to flame anyone anymore. :)

Interesting discussion anyway.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:MACROS in Java

Post by Solar »

Ch. Reichenbach wrote: Would you happen to have a reference to the appropriate part of the C++ '98 language definition, or to a description of how they implemented it?
The Standard.

Or:

David Vandevoorde, Nicolai M. Josuttis
C++ Templates - The Complete Guide
Addison-Wesley, 2002
ISBN 0-201-73484-2
Every good solution is obvious once you've found it.
Post Reply