Article Discussion
Generics in C#, Java, and C++
Summary: Anders Hejlsberg, the lead C# architect, talks with Bruce Eckel and Bill Venners about C# and Java generics, C++ templates, constraints, and the weak-strong typing dial.
19 posts.
The ability to add new comments in this discussion is temporarily disabled.
Most recent reply: December 13, 2007 5:12 AM by Michiel
    Bill
     
    Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
    Generics in C#, Java, and C++
    January 25, 2004 9:00 PM      
    Anders Hejlsberg, the lead C# architect, talks with Bruce Eckel and Bill Venners about C# and Java generics, C++ templates, constraints, and
    the weak-strong typing dial.

    Read this Artima.com interview with the creator of C#:

    http://www.artima.com/intv/generics.html

    What do you think of Anders' comments?
    • Richard
       
      Posts: 5 / Nickname: richardd / Registered: April 30, 2003 3:23 AM
      Re: Generics in C#, Java, and C++
      January 26, 2004 8:22 AM      
      > Issue number two, and I think this is probably
      > an even bigger issue, is that because Java's
      > generics implementation relies on erasure of
      > the type parameter, when you get to runtime,
      > you don't actually have a faithful representation
      > of what you had at compile time.

      While Java's generics use erasure, the specification (available from http://www.jcp.org/aboutJava/communityprocess/review/jsr014/index.html) states that there is attribute added to the bytecode to enable reflection to work without breaking compatibility with existing VMs.

      Regards,
      Richard
    • Isaac
       
      Posts: 51 / Nickname: igouy / Registered: July 10, 2003 7:42 AM
      Re: Generics in C#, Java, and C++
      January 26, 2004 8:43 AM      
      > Anders Hejlsberg, the lead C# architect, talks with Bruce
      > Eckel and Bill Venners about C# and Java generics, C++
      > templates, constraints, and
      > the weak-strong typing dial.

      "A Comparative Study of Language Support for Generic Programming"

      This paper reports on a comprehensive comparison of generics in six programming languages: C++, Standard ML, Haskell, Eiffel, Java (with its proposed generics extension), and Generic C#.

      http://www.osl.iu.edu/publications/pubs/2003/comparing_generic_programming03.pdf
    • Joost de
       
      Posts: 15 / Nickname: yoozd / Registered: May 15, 2003 4:13 AM
      Type inferencing in C#?
      January 26, 2004 11:52 AM      
      I was quite impressed with the research language Xen. As mentioned a.o. at http://www.theserverside.net/news/thread.aspx?thread_id=23460
      because it features some scale of type-inferencing. A feauture that I only know of languages like Ocaml. Maybe that will bring something new to the age-old debate between dynamic- and static typing. :-) If it will ever make it into a major MS supported programming language of course: I remember my excitement over the MS Research project Intentional Programming that suddenly disappeared of the face of the internet as if it contained some secrets of state.
      Another interesting feature is ofcourse the way it handles relational- and xml-data.

      groetjes,
      Joost de Vries
      • Isaac
         
        Posts: 51 / Nickname: igouy / Registered: July 10, 2003 7:42 AM
        Re: Type inferencing in C#?
        January 26, 2004 0:56 PM      
        some scale of type-inferencing

        Local type inference is also a feature of open source languages targeting the JVM (and inter-operating with Java) like:

        Nice http://nice.sourceforge.net/index.html
        Scala http://scala.epfl.ch/index.html

        Maybe that will bring something new to the age-old debate between dynamic- and static typing
        We can hope ;-)
        • Joost de
           
          Posts: 15 / Nickname: yoozd / Registered: May 15, 2003 4:13 AM
          Re: Type inferencing in C#?
          January 26, 2004 11:42 PM      
          Scala and Nice look interesting. I'm a bit sceptic though about Nice's capability to prevent nullpointerexceptions in the case where data is originated from external sources like the user or a database. So that will be interesting to try out.
          But then there are a lot of interesting features in Academic languages. The point where it gets exciting to me is where these cross over into the mainstream of languages that are used in the enterprises. Since then I can actually use it in everyday development.
          But there's hope: it seems that one of the people behind Scala, Martin Odersky, was also behind the Pizza generics compiler. So maybe this will be of influence too. I seem to recall that James Gosling expressed some interest in type-inferencing. So, let's see, how long did it take for generics to make it into Java? Hm........
          • Isaac
             
            Posts: 51 / Nickname: igouy / Registered: July 10, 2003 7:42 AM
            Re: Type inferencing in C#?
            January 27, 2004 7:42 AM      
            Nice's capability to prevent nullpointerexceptions in the case where data is originated from external sources like the user or a database

            It's called Nice - not Magic ;-)

            The programmer prevents NullPointerExceptions in these (and all other cases). Nice just provides a way to isolate the situations in which values may be null.

            In Nice, the type String does not include null values - the type check will fail if we try to assign null to a String variable. The type ?String does include null - so we can bring in data as ?String, check that it isn't null and from then on use it as String.


            But then there are a lot of interesting features in Academic languages
            Yes, and in research languages generally - as you pointed out, there's plenty of language research taking place within Microsoft and other companies. It's wonderful that so many of those implementations are openly available.

            cross over into the mainstream of languages
            Sure, it just takes soooo long.

            Which is a reason to be interested in the language implementations that target jvm and clr (and interoperate with Java & C#) even though the implementations may suffer from limitations in those VMs - we can sometimes pretend to be using the mainstream language.
    • Slobodan
       
      Posts: 1 / Nickname: topce / Registered: January 27, 2004 3:41 AM
      Re: Generics in C#, Java, and C++
      January 27, 2004 8:47 AM      
      Guy is genius.
      I like ruby, I think they (C# team “steal” a lot from Ruby)
      , but compare with c++ and java
      c# generic implementation is superiors.
      • reyhcc
         
        Posts: 1 / Nickname: reyhcc / Registered: January 27, 2004 5:46 AM
        Re: Generics in C#, Java, and C++
        January 27, 2004 11:36 AM      
        nothing compare with C++ Templates when you are developing computational geomitric applications or math algorithms , see CGAL or Blitz++ libraries as an example.

        "a programming language is a tool for a especific porpouse", said stroustrup in The C++ Programming language... or something like this ;-)

        and c# generics could be god in the more comun types of aplications but not in all of them

        what about??: metaprograming, active libraries, traits tecniques, compile-time expansions, function objects ...
        and some other atractives c++ templates aspects

        anyway c# is a new good language with many interesting things, but i was expecting more of C# exception and templates mechanism
    • andrew
       
      Posts: 2 / Nickname: queisser / Registered: October 22, 2003 7:02 AM
      Re: Generics in C#, Java, and C++
      January 27, 2004 0:22 PM      
      I can totally understand the design decisions the C# designers took and overall really like C#'s generics but, coming from C++ templates, there's a lot of stuff you cannot do with generics that you can do with templates. I'm thinking of generic algorithms a la STL, expression templates, pretty much any of Alexandrescu's stuff. Of course there are many people who will argue that that's a good thing.

      It'll be interesting to see what kind of generics-based libraries will surface for C#.

      Andrew
    • Chris
       
      Posts: 6 / Nickname: mouse / Registered: December 3, 2002 8:33 AM
      Re: Generics in C#, Java, and C++
      January 27, 2004 6:28 PM      
      Generics has not been released in final form for etiher C# or Java, right?

      Regarding the distinctions he made between C# and Java ...

      I agree that there will potentially be a runtime disadvantage, but depending on how they implemented the extra information in the class file, it may not be bad. C# is at an advantage being able to design the CLR with generics in mind. However, I think it doesn't make a whole lot of difference to the programmer (for compile-time issues, at least).

      For the second issue, when you get to runtime, you don't actually have a faithful representation of what you had at compile time, I'm not sure how often this will be a cause for problems for programmers. I guess the question is how much benefit do you get from compile time checking, and then how much additional benefit do you get from run time checking?
      • Richard
         
        Posts: 5 / Nickname: richardd / Registered: April 30, 2003 3:23 AM
        Re: Generics in C#, Java, and C++
        January 28, 2004 1:21 AM      
        > Generics has not been released in final form for etiher C#
        > or Java, right?

        The spec has been out now for over 2 years for Java templates - changes could still occur at this stage but I imagine that they wouldn't be major.

        >
        > Regarding the distinctions he made between C# and Java
        > ...
        >
        > I agree that there will potentially be a runtime
        > disadvantage, but depending on how they implemented the
        > extra information in the class file, it may not be bad.

        According to the Java spec, runtime information on templates is added to the class file using named attributes. This is a backward compatible mechanism.

        > For the second issue, when you get to runtime, you
        > don't actually have a faithful representation of what you
        > had at compile time
        , I'm not sure how often this will
        > be a cause for problems for programmers. I guess the
        > question is how much benefit do you get from compile time
        > checking, and then how much additional benefit do you get
        > from run time checking?

        As I mentioned in my post above, this statement by Anders is incorrect (unless he knows something that is not in the public spec). Attributes are added and the classes involved in relfection have been modified to take advantage of this information.

        Regards,
        Richard
    • Paul
       
      Posts: 1 / Nickname: pmg101 / Registered: July 23, 2003 4:03 AM
      Re: Generics in C#, Java, and C++
      January 26, 2004 5:57 AM      
      > The thing you realize about typing is that it's a dial. The higher you place the dial, the more painful the programmer's
      > life becomes, but the safer it becomes too. But you can turn that dial too far in either direction.

      Does the dial go from weak to strong, or from static to dynamic?

      I have personal experience of the pain of representing certain designs in C++, a strongly- and statically-typed language, so would agree with that. And once the compiler had bludgeoned me for half an hour, I suppose that the code was safe in certain limited respects.

      And turning the dial in the other direction, in languages such as Python, Ruby, or Smalltalk, I agree I was amazed at how /little/ pain was involved in clearly representing concepts in the code.

      But were they 'less safe'? I for one don't think so. I tend to agree with Bruce Eckel's position (at http://mindview.net/WebLog/log-0025) that strong and static typing are both missteps towards unit-tested code. The sorts of assurances that typing can give you are really not that useful compared to unit-tests which check that a method's semantics are correct.
      • Isaac
         
        Posts: 51 / Nickname: igouy / Registered: July 10, 2003 7:42 AM
        Re: Generics in C#, Java, and C++
        January 26, 2004 8:38 AM      
        Does the dial go from weak to strong, or from static to dynamic?

        'So what is “strong typing”? As best as we can tell, this is a meaningless phrase, and people often use it in a nonsensical fashion. To some it seems to mean “The language has a type checker”. To others it means “The language is sound” (that is, the type checker and run-time system are related). To most, it seems to just mean, “A language like Pascal, C or Java, related in a way I can’t quite make precise”. For amusement, when someone mentions the phrase “strongly typed” at a cocktail party, ask them to define it, then sit back and watch them squirm. And please, don’t use the term yourself unless you want to sound poorly-trained and ignorant. Use the terminology of this course instead.'

        Chapter 24 Type Soundness p205
        Programming Languages: Application and Interpretation
        http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/PDF/all.pdf


        > I have personal experience of the pain of representing
        > certain designs in C++, a strongly- and statically-typed
        > language

        "C and C++ do not have sound type systems. That is, the type system may define certain abstractions, but the run time system does not honor and protect these." p205


        > And turning the dial in the other direction, in languages
        > such as Python, Ruby, or Smalltalk, I agree I was amazed
        > at how /little/ pain was involved in clearly representing
        > concepts in the code.

        I've used Smalltalk for over 10 years and like it.

        However, there are expressive statically checked languages: ML, Haskell, Nice http://nice.sourceforge.net/index.html, Scala http://scala.epfl.ch/index.html ...


        > But were they 'less safe'? I for one don't think so. I
        > tend to agree with Bruce Eckel's position (at
        > http://mindview.net/WebLog/log-0025) that strong and
        > static typing are both missteps towards unit-tested code.
        > The sorts of assurances that typing can give you are
        > really not that useful compared to unit-tests which check
        > that a method's semantics are correct.

        It seems that folk experienced with expressive statically checked languages have a different programming style - they write code to actively use the type system to find errors, to them the type checker is another tool they can use to make their program better.
        • Daniel
           
          Posts: 5 / Nickname: dyokomiso / Registered: September 17, 2002 2:50 PM
          Re: Generics in C#, Java, and C++
          January 28, 2004 3:57 AM      
          > Does the dial go from weak to strong, or from static to
          > dynamic?

          >
          > 'So what is “strong typing”? As best as we can tell, this
          > is a meaningless phrase, and people often use it in a
          > nonsensical fashion. To some it seems to mean “The
          > language has a type checker”. To others it means “The
          > language is sound” (that is, the type checker and run-time
          > system are related). To most, it seems to just mean, “A
          > language like Pascal, C or Java, related in a way I can’t
          > quite make precise”. For amusement, when someone mentions
          > the phrase “strongly typed” at a cocktail party, ask them
          > to define it, then sit back and watch them squirm. And
          > please, don’t use the term yourself unless you want to
          > sound poorly-trained and ignorant. Use the terminology of
          > this course instead.'
          >
          > Chapter 24 Type Soundness p205
          > Programming Languages: Application and Interpretation

          'Hence, typeful programming advocates static typing, as much as possible, and dynamic typing when necessary; the strict observance of either or both of these techniques leads to strong typing, intended as the absence of unchecked run-time type errors.'
          (emphasis is mine)

          Typeful Programming, p3
          Luca Cardelli

          BTW I'm in the static typing camp but I find amusing that people usually ignore this definition.
    • Travis
       
      Posts: 1 / Nickname: deuce / Registered: February 27, 2004 2:24 AM
      Re: Generics in C#, Java, and C++
      February 27, 2004 7:48 AM      
      Likely a little late ... but, hopefully, someone's listening.

      I'll just cut to the chase ...

      It APPEARS that C# does not allow me to override the virtual default property of ArrayList in an attempt to return a specific type (ex. Fred). It also APPEARS that I can have no "indexed" property other than the default (but, I admit, I haven't looked into this thoroughly).

      I was barely able to follow along with the discussion of "List<T>" ... I've tried various syntax in C# (as the MSDN doc does not necessarily, accurately, reflect the product) as well as MSDN searches. Based on the fonts used, I presumed it was actual C# syntax. Is this merely theoretical ... or vaporware ... or what? Regardless, aside from the early type-checking, I'm not sure that's what I want anyway.

      I'm used to VB6 (keep the laughter down) and coding things like a Person class and a Persons class. Of course, I couldn't inherit Persons from Collection. So, I dragged around the same basic code everywhere and basically just changed the type of what was contained. I started doing the same thing in C# when I realized "hey, wait a minute, I can just inherit from ArrayList". But, that did me no good 'cause, MOSTLY, what I wanted (and this might seem stupid to a lot of you, but, I don't see why I'm not permitted to have it) is to have the default, or any, "indexed" property return the type I want (ex. Person). Of course, by simply overriding Add and Insert (not sure about constructors just yet), I could be relatively assured that only Person will be in the list (which is mostly what the article discussed), but, I'm more about un-cluttered, ridiculously readable, code. And, having a default "indexed" property which returns MY type AND, for that matter, having the Add and Insert methods also return the object typed as MY type (don't ask), helps me do that.

      As it is, I've created the AL class which has a private member of ArrayList which it uses to perform all the same methods and properties of ArrayList ... with ONE exception (no, not that kind of exception) ... there is NO default property. As such, I can create a class (ex. Persons) inherited from AL and then simply ADD a default "indexed" property which returns the appropriate type (ex. Person).

      Sorry for being so detailed ... more often than not, when I'm not, I'm simply misunderstood.

      Just out of curiosity, can I, ever, overload the default property? I presume that, if I could've (presuming that a different return type is a change to the signature), that I wouldn't have noticed any problem when I tried removing "override" to my attempt to override, and, consequently, overload, the default property.

      Thanks.
    • jdnicolet
       
      Posts: 6 / Nickname: jdnicolet / Registered: October 27, 2003 7:58 PM
      Re: Generics in C#, Java, and C++
      January 29, 2004 8:55 AM      
      I would like to express some remarks and complements about the above article.

      - I find the implementation strategy chosen by C# quite good, given the goal aimed at, i.e. basically a good way of defining strong typed containers (and other similar parameterized classes). The presented arguments sounds convincing, and show that the decisions were made on purpose. It reinforces my believing that "C# is Java done right".

      - Some remarks about the comparison with C++. It's true that the mechanism is natively "blind" and gives cryptic error messages. But the mere fact that it gives an error message, however cryptic, is just the proof that it does indeed type check the generic parameters, hence doing strong typing.

      - Although the constraint mechanism is not offered natively in the language, we have today excellent libraries (at least one: BOOST (www.boost.org)) allowing to do it, both with clearer error messages and with a granularity sufficient to allow any constraint checking, and this without requiring to some artificial factory just to be able to check for the presence of an arithmetic operator.

      - I dislike comparing generics with macros, and thus in any programming language whatsoever. Macros are by definition lexical substitution patterns, while generics (or templates in the C++ case) are of a syntactic nature, thus they are acting at a higher level. This is why templates allow much more powerful constructs than macros, at least in C++. True, for offering just parameterized containers, macros would be sufficient. The former Tools.h++ library, a now antic fundamental library by Rogue Wave offered a full range of generic collections implemented with macros, more than ten years ago, when templates were not fully stabilized and widespread among C++ compilers. A little reflection shows that macros are sufficient to just insert an automatic cast in front of a generic (Object based) implementation.

      - The whole purpose of templates in C++ is much, much broader. It goes today in the direction of so-called generative programming, where it is possible to design optimized classes tailored to specific choices made by the programmer when instantiating the template. The goal is to selectively construct a class by assembling tidbits of code and keeping only the necessary parts. In order to be efficient, this mechanism has to be performed at compile time, precisely to be able to suppress unnecessary code generation. Doing it with a run-time mechanism would be highly inefficient, from the memory footprint point of view. A classical example in this direction is the first achievement in the generative programming field, the computation of prime numbers at compile time. Computing a moderately large number may lead to the recursive instantiation of tens of thousands of templates that completely disappear afterwards (due to constant folding requirements imposed on the C++ compiler), leading to a vanishingly small amount of generated code, namely the sole computation result.

      - The piecewise construction of a user-tailored class using generics needs some powerful support from the generic mechanism, among them at least the possibility of recursive substitution. This implies that a way must be offered to stop the recursion, and this is achieved in C++ by the so-called partial template specialization mechanism. Most programming languages supporting generics don't go that far, because this is roughly equivalent to integrate a substitution engine like Mathematica within the compiler, a knowingly complex task, explaining why the number of conforming compilers is still less than a dozen, after serveral years of standard's availability. By the way, the Microsoft C++ compiler, which has striking quality in the code optimization field, lags years behind the C++ standard, and is basically unusable to devise serious generative programming libraries.
    • Kojo
       
      Posts: 1 / Nickname: kojo / Registered: March 26, 2006 4:13 AM
      Re: Generics in C#, Java, and C++
      March 26, 2006 9:44 AM      

      > Difference number two is C# does strong type checking when you
      > compile the generic type. For an unconstrained type parameter,
      > like List<T>, the only methods available on values of type T
      > are those that are found on type Object, because those are the
      > only methods we can generally guarantee will exist. So in C#
      > generics, we guarantee that any operation you do on a type
      > parameter will succeed.
      >
      > C++ is the opposite. In C++, you can do anything you damn well
      > please on a variable of a type parameter type. But then once
      > you instantiate it, it may not work, and you'll get some
      > cryptic error messages.


      This is actually somewhat misleading. In C++, instantiation happens at compile time, which means "anything you damn well please" is checked at compile time, not at runtime like the above quote suggests (IMO). So in C++ any template instantiation error messages are seen at compile time, which is way better than in C#.

      Also, the fact that C++ template instantiation error messages are cryptic is mostly due to the compiler writers having to focus (IMO) on supporting templates to meet the Standard, rather than any limitation of the language. This is changing with each new compiler versions coming out.

      It goes even further than this: in C++ you can only do on the template type parameter what the type parameter allows you to do, so it's actually safer than in C#. C++ enforces the full type's actual interface.

      This is probably why C# has the concept of constraints and C++ doesn't: C++ doesn't need it (in some ways, it's already there), whereas they are needed in C# due to the weakness of having to go through Object when instantiating templates.
    • Michiel
       
      Posts: 1 / Nickname: michiel / Registered: December 12, 2007 10:49 PM
      Re: Generics in C#, Java, and C++
      December 13, 2007 5:12 AM      
      Great article!

      However, I was a bit disappointed to learn that it is not possible to use operators (such as operator+) as a generic constraint. And indeed, since it is not possible to add static methods in a constraint, the natural consequence is that operators cannot be used as a constraint. You propose to use a Calculator<T> as a "man-in-the-middle" solution. I have a few questions about this:

      - Why aren't static functions just allowed in interfaces?
      - Is it not possible to use concepts such as proposed for the new C++ standard: special interfaces used to hold the constraints for a generic (including static functions)?
      - Another solution: use "interface extensions" (in accordance to type extensions in 3.0): one could define an interface to an existing class or valuetype containing the functions you want to use as a constraint. Like this, you could define an interface extension, having the operator+ and adding it to the list of constraints of your generic.
      - Isn't the overhead of having a wrapper class Calculator<T> giving C# the same disadvantage as the implementation of generics in Java? After all, in Java, int's are being boxed as you point out, but with a Calculator wrapper, as a developer I'm obliged to box my int as well, just to overcome a problem that could be easily tackled with syntactic sugar. Where am I missing something?

      Nevertheless, I like C# a lot (almost as much as C++). Keep up the good work.