Naming generic type parameters: Dictionary or Dictionary


There is a good debate going on over in the Whidbey product feedback site.  I encourage you to go and chime in one way or another… The team is watching the thread there and looking for feedback.  On the surface this looks like a simple issue (more letters==more clarity), but I believe the issues are more subtle.  


 


Love to have your feedback.


 

Comments (25)

  1. Jeff Atwood says:

    I belive the issue are more subtle too. It can not be more subtle.

    😉

  2. Mike Dunn says:

    MORE letters please. The tradition of writing a C++ template example like this:

    template class Foo<T, U, bar> { … }

    is a bad one because it just makes the template harder to read and understand.

  3. Dictionary<A,B> obviously.

    parametric polymorphism allows a user to substitute their own types for the parameters. The parameters are pretty meaningless and can be subtably represented with something like:

    Dictionary<1,2>

    A suitable scheme is to start with A and the continue through the alphabet. If you hit more than 26… well, that’s interesting 🙂

  4. Mario Goebbels says:

    Well, I prefer the single letter versions. It would be nice though if Intellisense would work on these parameters, in case someone starts using random letters for the parameters.

  5. Darren Oakey says:

    I like this "On the surface this looks like a simple issue (more letters==more clarity)"..

    well… I don’t see any depth here. What it comes down to is Dictionary<KeyType, ValueType> is more quickly understood than Dictionary<A,B>, and really, that should be the be all and end all of it.

    It’s not like you get browny points for shorter code or anything! There are 0 (count em) possible advantages of using a non-descriptive variable name at any point – (forgetting about the original basic where you would incur a performance penalty) and hundreds of reasons why having a meaningful parameter may one day help someone understand something.

  6. Making provision for more letters will satisfy both camps… my 5 cents 😉

    How (non)trivial this change might be in the CLR, I don’t know.

  7. Mitch Denny says:

    I personally prefer the single letter versions. Just caus’

  8. Philip Rieck says:

    No matter what the subtleties are in this, you don’t have

    public object this[object k] { …}

    in the current hashtable class. Instead, we have

    public object this[object key] {…}

    Why would we have

    public T this[K key]{…}

    instead of

    public ItemType this[KeyType key] { …}

    The only justification I can see that doesn’t also apply to shortened parameter names (do you really want that?) is that of differentiating between using a type that was used to construct this generic, or using a type simply defined elsewhere (as in, is KeyType a separate class, or one used to construct this generic).

    I’m willing to live with that minor ambiguity (especially since the sematics are the same as far as the generic implementation is concerned) In order to not have to guess what T,U,V,W mean every time I construct a type.

  9. Brad Abrams says:

    Just to respond to Ernst’s point… the CLR does allow any number of letters in type paramaters… This is just a question of what we do in the Framework and suggest in the API Design Guidelines.

  10. Chance Gillespie says:

    I just happened upon all this while checking the blog for some other thread. In an interesting coincidence I was fiddling with this myself today trying to find something that worked for me since <T, U> was just not going to cut it for my own code. I do my best to stick with the conventions laid out by MS (for .Net of course, I used to vomit any time I saw any Hungarian Notation 🙂 ) but this is one where I just couldn’t do it. I can’t grasp how anyone can argue in favor of the cryptic naming convention currently in use. A key point that needs to be achieved is to differentiate generic parameter types from normal types (as they will be used in more places than between the <> ), but I don’t see the logic in an approach that says “OK, here, this is our convention, and you know it’s a generic parameter when you look at it, but we aren’t going to tell you what it’s actually used for or means.”. The solution requires both… It must indicate it’s a generic parameter and it must also be ‘intended use’ descriptive. There have been quite a few suggestions (TKey, KeyT, GKey, KEY) .. we can argue till we are blue in the face on which alternate method is best, but I believe that ANY of them are better than the single capital letter we have at the moment.

    Please, please PLEASE step up the plate on this one MS. You’re still in BETA and there is time to change. Whatever you end up shipping will end up the standard and if what we have now becomes the standard we have a hell of a lot of hand obfuscated generic code to look forward to. Joy of Joys

  11. Ron says:

    I have to agree with Chance (as well as others). Descriptive names are far better, in terms that it provides a clearer meaning of the type, than single characters (no matter how intuitive these single characters may seem). I’ll use generics either way, but I can’t sit back and recommend the current single letter approach as a convention for custom generic classes. I’d certainly rather see the Framework and design standards more toward the full description names.

    As for the actual format, I see no problem with ItemT, KeyT, ValueT, etc.; but I think it could lead to the same issue where developers begin to question what the T really means.

  12. Staffan Gustafsson says:

    Count me in on Chance’s side 🙂

    He’s argument that a solution needs to accomodate both aspects is definitly valid. (i.e. both indicate a generic type, and it’s intended use).

    Don’t you have a similar situation with interfaces?

    And I like Ron’s suggestion on ItemT in favor of TItem. But both are better than single letter.

    Please don’t go down that path…

  13. damien morton says:

    Not wanting to hedge my bets, but…

    For one or two type paramaters, and where their meaning is crear, single letter type params are acceptable to me.

    Dictionary<K,V> is a case in point. Its clear what K and V mean, and consise to read and write.

    Collection<T> is another case in point; its also clear and consise.

    Foo<U,V,W> is consise, but not clear. It would be better to use more descriptive names; In this case, I like the *Type pattern.

  14. There is an I* standard for interfaces. Why not T*, like TKey and TValue, for type parameters?

  15. Damien: "Dictionary<K,V> is a case in point. Its clear what K and V mean, and consise to read and write. "

    Not to me it isn’t. Why K instead of A? If it were Key or KeyType it still wouldn’t help out at all.

    These are types we are talking about and in the end they’re substituted by the user for somthing else.

    take a fictional method example:

    public interface IDictionary<KeyType,ValueType>

    {

    ValueType GetAt(KeyType key);

    }

    Why is KeyType necessary? We know it’s a "key" because the name of the variable is "key". So KeyType adds no extra information. When you end up using this you’ll have:

    IDictionary<int,string> and you’ll end up seeing:

    string GetAt(int key);

    In the end, it was "key" that told you what this was, not the type (Which is up to the user to provide).

    So i don’t see why K is any better than A and V is any better than B.

  16. Julien: Dont’ get me started on how much I hate that about interfaces 🙂

  17. I’m looking forward to prepending classes with C, delegates with D, and enums with E. There’s a certain beauty in the succession of those letts, C/D/E. Now we just need to something to start with F…

  18. damien morton says:

    Cyrus sais:

    public interface IDictionary<KeyType,ValueType>

    {

    ValueType GetAt(KeyType key);

    }

    Why is KeyType necessary? We know it’s a "key" because the name of the variable is "key".

    Damien sais:

    Ahh – but what about ValueType in that expression – we dont know what that is, until we look at the name of the generic type param.

    how about this pattern:

    public interface IDictionary<KEY,VALUE>

    {

    VALUE GetAt(KEY key);

    }

    I know evyerone will recoil at the use of all-caps, but its shorter and clearer than pre-pending a letter or appending the word "Type". Its a currently unused pattern, and its compatable with single-upper-case-letters for simple type params.

  19. Philip Rieck says:

    Damien – the only problem with VALUE is that many other languages (C# included, to some extent), use the all caps pattern to signify a constant, #define, or macro — In fact, it’s normally reserved for a value fixed at compile time.

    Also, I personally would be distracted by code such as this (completely nonsensical:)

    VALUE Process(OTHER key)

    {

    OTHER newKey = key.Next();

    foreach(VALUE value in values[key])

    {

    value = key.Get<VALUE>

    — you can see that the all-caps type specifiers can be littered in there quite a bit, and would distract a reader. The reader would be much more likely to care what the code does than to have the placement of type specifiers scream out at them

  20. damien morton says:

    Philip – your example has me recoiling – youre right – its ugly and distracting.

    How about this then:

    @Value Process(@Other key)

    {

    @Other newKey = key.Next();

    foreach (@Value value in values[key])

    {

    value = key.Get<@Value>

    }

    Perhaps this distinguishes type paramaters, without beeing to visually jarring. (shades of perl, but… type paramaters are special and you dont want to go an confuse them with actual types).

  21. Klaus says:

    Spell the type parameters out, please. So my vote is for the Dictionary<KeyType, ValueType>. I would read the use of <> and from that know that it should not be used as Dictionary<2,26>.

  22. I’ve flipped my position on this after a conversation with SteveJS. I’ll post something on it later 🙂

  23. Keith Patrick says:

    Key/Value (or whatever the class is supposed to be). It’s like getting rid of Hungarian notation: let the IDE tell you what something is to the compiler/runtime, not the name, so why use abbreviations to denote a template/generic? Also, the concept doesn’t really extend out beyond traditional templates. Sure, there’s K/V, and it’s well understood, but what woudl the standard be (and for that matter, the litmus) for when something is well-known enough to abbreviate?

  24. I think I am becomming a lazy person since I get hooked on the intellisense. I typically rely intellisense pop up the class method to look for the method and parameters instead of look it up from the menu/help (I really hate MSDN unless I have to). Hey I am not the only one—

    http://www.joelonsoftware.com/uibook/chapters/fog0000000062.htmlIf

    From that perspective, well, I learn my lesson of put the *long & descriptive* name in the type defination, xml comment on the beginning every public function that will benefit other teammate whoever to use it and vise versa.

    That is, if I have to choose to purchase a external templateize colletion from two companies one implement Dictionary<Key,Value>, the other implements Dictionary<K, V>, I will pick Dictionary<Key,Value> anyday.

    Yes, i am VS intelliense addict & I don’t *want to* read manual unless absolute necessary.

    -Ming