www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.dtl - Minor gripe with template programming...

reply Berin Loritsch <bloritsch d-haven.org> writes:
This is something that has always been a gripe of mine with most
examples of template/generic programming: why do people insist on
using just one character for the type?  Take for example your
typical map:

Map!(K key, V value)

or worse:

Map!(K k, V v)

To me this is not really understandable.  Sure its generic, but
generic programming does support more than one character for
your type information.

Do you think it would be reasonable to use a type name that described
the role of the type in the template?  It really goes a long way into
making it more readable.  The Map would be written more like this:

Map!(KEY k, VALUE v)

or something like that.  I do like to make it clear that the types
are template types by the all caps or some other mechanism like this:

Map!(key_t key, value_t value)

However it feels most comfortable.

I am just sick of seeing functions, classes, etc. that just use one
letter for a generic type.  This is the greatest disservice that C++
STL has foisted on the poor unsuspecting developer.

For example, what is this function supposed to do?:

doSomething(T val, A!(T) acc, Map!(A!(T), T) map);


The name used for the type provides semantic clues to help understand
the code.  There should be no reason to write obfuscated code for D's
libraries.  At least, I hope I can influence DTL while it is still
young...
Jul 30 2004
next sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
sure. sounds reasonable. I'll change my Map types to Key and Value and the
List type from T to ...hmmm... Value. Now that you mention it it does seem
wierd to have T in List and V in Map.

"Berin Loritsch" <bloritsch d-haven.org> wrote in message
news:cedkrk$2lu2$1 digitaldaemon.com...
 This is something that has always been a gripe of mine with most
 examples of template/generic programming: why do people insist on
 using just one character for the type?  Take for example your
 typical map:

 Map!(K key, V value)

 or worse:

 Map!(K k, V v)

 To me this is not really understandable.  Sure its generic, but
 generic programming does support more than one character for
 your type information.

 Do you think it would be reasonable to use a type name that described
 the role of the type in the template?  It really goes a long way into
 making it more readable.  The Map would be written more like this:

 Map!(KEY k, VALUE v)

 or something like that.  I do like to make it clear that the types
 are template types by the all caps or some other mechanism like this:

 Map!(key_t key, value_t value)

 However it feels most comfortable.

 I am just sick of seeing functions, classes, etc. that just use one
 letter for a generic type.  This is the greatest disservice that C++
 STL has foisted on the poor unsuspecting developer.

 For example, what is this function supposed to do?:

 doSomething(T val, A!(T) acc, Map!(A!(T), T) map);


 The name used for the type provides semantic clues to help understand
 the code.  There should be no reason to write obfuscated code for D's
 libraries.  At least, I hope I can influence DTL while it is still
 young...

Jul 30 2004
next sibling parent reply Berin Loritsch <bloritsch d-haven.org> writes:
Ben Hinkle wrote:
 sure. sounds reasonable. I'll change my Map types to Key and Value and the
 List type from T to ...hmmm... Value. Now that you mention it it does seem
 wierd to have T in List and V in Map.
 

It could be Element for the List/Vector elements. It just seems that T is the substitute if there is only one type that needed declaration, and it is counterintuitive in most cases.
Jul 30 2004
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Berin Loritsch" <bloritsch d-haven.org> wrote in message
news:cednq6$2ni0$1 digitaldaemon.com...
 Ben Hinkle wrote:
 sure. sounds reasonable. I'll change my Map types to Key and Value and


 List type from T to ...hmmm... Value. Now that you mention it it does


 wierd to have T in List and V in Map.

It could be Element for the List/Vector elements. It just seems that T is the substitute if there is only one type that needed declaration, and it is counterintuitive in most cases.

I would prefer Value for List since it makes the signatures more uniform. For example, the signatures for opIndex for List and Map, respectively, are Value opIndex(int n) and Value opIndex(Key key)
Jul 30 2004
next sibling parent Berin Loritsch <bloritsch d-haven.org> writes:
Ben Hinkle wrote:

 "Berin Loritsch" <bloritsch d-haven.org> wrote in message
 news:cednq6$2ni0$1 digitaldaemon.com...
 
Ben Hinkle wrote:

sure. sounds reasonable. I'll change my Map types to Key and Value and


the
List type from T to ...hmmm... Value. Now that you mention it it does


seem
wierd to have T in List and V in Map.

It could be Element for the List/Vector elements. It just seems that T is the substitute if there is only one type that needed declaration, and it is counterintuitive in most cases.

I would prefer Value for List since it makes the signatures more uniform. For example, the signatures for opIndex for List and Map, respectively, are Value opIndex(int n) and Value opIndex(Key key)

Sounds good to me. I like this better than K,V,T,A, or whatever other nonesense I have run accross.
Jul 30 2004
prev sibling parent Sean Kelly <sean f4.ca> writes:
In article <cedp0u$2o8v$1 digitaldaemon.com>, Ben Hinkle says...
"Berin Loritsch" <bloritsch d-haven.org> wrote in message
news:cednq6$2ni0$1 digitaldaemon.com...
 Ben Hinkle wrote:
 sure. sounds reasonable. I'll change my Map types to Key and Value and


 List type from T to ...hmmm... Value. Now that you mention it it does


 wierd to have T in List and V in Map.

It could be Element for the List/Vector elements. It just seems that T is the substitute if there is only one type that needed declaration, and it is counterintuitive in most cases.

I would prefer Value for List since it makes the signatures more uniform. For example, the signatures for opIndex for List and Map, respectively, are Value opIndex(int n) and Value opIndex(Key key)

See my iterator/list example at http://home.f4.ca/sean/d/iterator.d That's exactly the convention I use there as the trailing "Type" bit that C++ tends to like just seems redundant since the D convention is that leading uppercase signals a type name anyway. Sean
Jul 30 2004
prev sibling parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
Please don't! Having mixed case identifiers would be the worst of all
possibilities, since they could look like type (or
function) names

"Ben Hinkle" <bhinkle mathworks.com> wrote in message
news:cedn96$2n8b$1 digitaldaemon.com...
 sure. sounds reasonable. I'll change my Map types to Key and Value and the
 List type from T to ...hmmm... Value. Now that you mention it it does seem
 wierd to have T in List and V in Map.

 "Berin Loritsch" <bloritsch d-haven.org> wrote in message
 news:cedkrk$2lu2$1 digitaldaemon.com...
 This is something that has always been a gripe of mine with most
 examples of template/generic programming: why do people insist on
 using just one character for the type?  Take for example your
 typical map:

 Map!(K key, V value)

 or worse:

 Map!(K k, V v)

 To me this is not really understandable.  Sure its generic, but
 generic programming does support more than one character for
 your type information.

 Do you think it would be reasonable to use a type name that described
 the role of the type in the template?  It really goes a long way into
 making it more readable.  The Map would be written more like this:

 Map!(KEY k, VALUE v)

 or something like that.  I do like to make it clear that the types
 are template types by the all caps or some other mechanism like this:

 Map!(key_t key, value_t value)

 However it feels most comfortable.

 I am just sick of seeing functions, classes, etc. that just use one
 letter for a generic type.  This is the greatest disservice that C++
 STL has foisted on the poor unsuspecting developer.

 For example, what is this function supposed to do?:

 doSomething(T val, A!(T) acc, Map!(A!(T), T) map);


 The name used for the type provides semantic clues to help understand
 the code.  There should be no reason to write obfuscated code for D's
 libraries.  At least, I hope I can influence DTL while it is still
 young...


Jul 30 2004
next sibling parent Sean Kelly <sean f4.ca> writes:
In C++ my rule was:

- lowercase for types, variables, functions, etc.
- uppercase for preprocessor stuff
- mixed case for template parameters

but the D naming convention kind of tosses that out the window.  I've since
slipped and now use template casing that corresponds to whatever I expect the
thing to be.  So my template parameters are mostly mixed case now, with leading
lowercase for aliases I expect to be functions.  Not ideal, but as D is less
confusing as far as template readability is concerned I don't feel quite so evil
doing this.


Sean
Jul 30 2004
prev sibling parent reply Ben Hinkle <bhinkle4 juno.com> writes:
I tend to use mixed-case-first-letter-upper-case (eg FooBar) for types and
mixed-case-first-letter-lower-case (eg fooBar) for functions. I think the
"D style guide" has the same rules. And I can't think of a good reason why
template parameters should be treated any differently from anything else.
All-caps (eg FOOBAR) means const or preprocessor symbol.

Looking at my STL include headers on my RedHat 9 distro they use things like
 template<typename _InputIterator> ...
and
 template<typename _Key, typename _Val, ...>
so aside from milliions of _ floating around it is semi-readable.

Matthew wrote:

 Please don't! Having mixed case identifiers would be the worst of all
 possibilities, since they could look like type (or function) names
 
 "Ben Hinkle" <bhinkle mathworks.com> wrote in message
 news:cedn96$2n8b$1 digitaldaemon.com...
 sure. sounds reasonable. I'll change my Map types to Key and Value and
 the List type from T to ...hmmm... Value. Now that you mention it it does
 seem wierd to have T in List and V in Map.

 "Berin Loritsch" <bloritsch d-haven.org> wrote in message
 news:cedkrk$2lu2$1 digitaldaemon.com...
 This is something that has always been a gripe of mine with most
 examples of template/generic programming: why do people insist on
 using just one character for the type?  Take for example your
 typical map:

 Map!(K key, V value)

 or worse:

 Map!(K k, V v)

 To me this is not really understandable.  Sure its generic, but
 generic programming does support more than one character for
 your type information.

 Do you think it would be reasonable to use a type name that described
 the role of the type in the template?  It really goes a long way into
 making it more readable.  The Map would be written more like this:

 Map!(KEY k, VALUE v)

 or something like that.  I do like to make it clear that the types
 are template types by the all caps or some other mechanism like this:

 Map!(key_t key, value_t value)

 However it feels most comfortable.

 I am just sick of seeing functions, classes, etc. that just use one
 letter for a generic type.  This is the greatest disservice that C++
 STL has foisted on the poor unsuspecting developer.

 For example, what is this function supposed to do?:

 doSomething(T val, A!(T) acc, Map!(A!(T), T) map);


 The name used for the type provides semantic clues to help understand
 the code.  There should be no reason to write obfuscated code for D's
 libraries.  At least, I hope I can influence DTL while it is still
 young...



Jul 30 2004
parent Sean Kelly <sean f4.ca> writes:
Ben Hinkle wrote:
 
 Looking at my STL include headers on my RedHat 9 distro they use things like
  template<typename _InputIterator> ...
 and
  template<typename _Key, typename _Val, ...>
 so aside from milliions of _ floating around it is semi-readable.

And for the STL the leading underscore and initial capital are pretty much required. I've come around to the meaningful template parameter idea. It's really not so bad. Sean
Jul 30 2004
prev sibling next sibling parent "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
If I see something like KEY, then I think of a global constant, or an enum
member

I tend to use one, or at most two, letters for template params, and I don't see
me changing. Sorry.

"Berin Loritsch" <bloritsch d-haven.org> wrote in message
news:cedkrk$2lu2$1 digitaldaemon.com...
 This is something that has always been a gripe of mine with most
 examples of template/generic programming: why do people insist on
 using just one character for the type?  Take for example your
 typical map:

 Map!(K key, V value)

 or worse:

 Map!(K k, V v)

 To me this is not really understandable.  Sure its generic, but
 generic programming does support more than one character for
 your type information.

 Do you think it would be reasonable to use a type name that described
 the role of the type in the template?  It really goes a long way into
 making it more readable.  The Map would be written more like this:

 Map!(KEY k, VALUE v)

 or something like that.  I do like to make it clear that the types
 are template types by the all caps or some other mechanism like this:

 Map!(key_t key, value_t value)

 However it feels most comfortable.

 I am just sick of seeing functions, classes, etc. that just use one
 letter for a generic type.  This is the greatest disservice that C++
 STL has foisted on the poor unsuspecting developer.

 For example, what is this function supposed to do?:

 doSomething(T val, A!(T) acc, Map!(A!(T), T) map);


 The name used for the type provides semantic clues to help understand
 the code.  There should be no reason to write obfuscated code for D's
 libraries.  At least, I hope I can influence DTL while it is still
 young...

Jul 30 2004
prev sibling parent reply Gold Dragon <dragonwing dragonu.net> writes:
I think that I will apply this to whatever I do from now on but one 
problem I can think of is what if you have a constant of the same name? 
Yeah, scope will come in to play but what if you want to use the 
constant and not the template member? Constants could be written as

#   const int iKTOMB = 1024;

That would make unsigned with a ui, uc, etc. structs with st(_) and so 
on. That would give some readability to the overall code would templates 
be referenced with a 't', followed by the name? Seems interesting 
concept that goes against the paradigm that has govern programming since 
when people didn't have the liberty to use more than 16-64 characters 
for variable names (I would know nothing of that time since I was a 
little baby).

I do believe some programmers absolutely hate it with a passion that 
would force the said programmer into a rage destroying whole villages 
and such. I think they are the minority but with a big voice.


Berin Loritsch wrote:
 This is something that has always been a gripe of mine with most
 examples of template/generic programming: why do people insist on
 using just one character for the type?  Take for example your
 typical map:
 
 Map!(K key, V value)
 
 or worse:
 
 Map!(K k, V v)
 
 To me this is not really understandable.  Sure its generic, but
 generic programming does support more than one character for
 your type information.
 
 Do you think it would be reasonable to use a type name that described
 the role of the type in the template?  It really goes a long way into
 making it more readable.  The Map would be written more like this:
 
 Map!(KEY k, VALUE v)
 
 or something like that.  I do like to make it clear that the types
 are template types by the all caps or some other mechanism like this:
 
 Map!(key_t key, value_t value)
 
 However it feels most comfortable.
 
 I am just sick of seeing functions, classes, etc. that just use one
 letter for a generic type.  This is the greatest disservice that C++
 STL has foisted on the poor unsuspecting developer.
 
 For example, what is this function supposed to do?:
 
 doSomething(T val, A!(T) acc, Map!(A!(T), T) map);
 
 
 The name used for the type provides semantic clues to help understand
 the code.  There should be no reason to write obfuscated code for D's
 libraries.  At least, I hope I can influence DTL while it is still
 young...

Jul 30 2004
next sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <ceeju2$8bp$1 digitaldaemon.com>, Gold Dragon says...
I think that I will apply this to whatever I do from now on but one 
problem I can think of is what if you have a constant of the same name? 
Yeah, scope will come in to play but what if you want to use the 
constant and not the template member? Constants could be written as

#   const int iKTOMB = 1024;

Dear God, please no hungarian notation.
I do believe some programmers absolutely hate it with a passion that 
would force the said programmer into a rage destroying whole villages 
and such. I think they are the minority but with a big voice.

Then consider me in that minority :) I've found that such things just lend to confusing variable names that are very brittle as the variable name needs to change if the underlying type changes. Really, the type of any variable should be pretty much self explanatory from the name and/or context without such conventions. Sean
Jul 30 2004
parent reply Gold Dragon <dragonwing dragonu.net> writes:
Sean Kelly wrote:
 In article <ceeju2$8bp$1 digitaldaemon.com>, Gold Dragon says...
 
I think that I will apply this to whatever I do from now on but one 
problem I can think of is what if you have a constant of the same name? 
Yeah, scope will come in to play but what if you want to use the 
constant and not the template member? Constants could be written as

#   const int iKTOMB = 1024;

Dear God, please no hungarian notation.
I do believe some programmers absolutely hate it with a passion that 
would force the said programmer into a rage destroying whole villages 
and such. I think they are the minority but with a big voice.

Then consider me in that minority :) I've found that such things just lend to confusing variable names that are very brittle as the variable name needs to change if the underlying type changes. Really, the type of any variable should be pretty much self explanatory from the name and/or context without such conventions. Sean

Well, is it better than having nothing to tell what type the variable is at all? My teachers have pounded it into my skull with a cast iron to name my variables as describtive as possible but I would still like to know what type I'm dealing with. The projects that I work with aren't that big. What do you use? I'm all for protocol and paradigm but damn, it does get old.
Jul 31 2004
parent Sean Kelly <sean f4.ca> writes:
Gold Dragon wrote:
 
 Well, is it better than having nothing to tell what type the variable is 
 at all? My teachers have pounded it into my skull with a cast iron to 
 name my variables as describtive as possible but I would still like to 
 know what type I'm dealing with. The projects that I work with aren't 
 that big.
 
 What do you use? I'm all for protocol and paradigm but damn, it does get 
 old.

In my experience, type is pretty easily determined by name and context. And that is in the rare cases where globals or other hard to find variables are concerned. If I'm still at a loss and knowing the type is really that important it's usually pretty easy to do a file search to find the declaration. The only convention I've used in the past is a leading m_ for non-public member variables and sm_ for non-public static member variables. This makes it easy (to me) to determine the scope of a variable I might be using, which is mostly what I've found useful as naming clashes between local function variables and class-level variables can be a confusing source of bugs. ie. # class X { # public: # void setX( int x ) { x = x; } # private: # int x; # } Simplistic example, but in the above, the assignment would have to be "this.x = x;" to work as intended. Some people prefer to always use the "this" specifier for class member stuff, which is another convention I've used from time to time. Sean
Jul 31 2004
prev sibling next sibling parent Ilya Minkov <minkov cs.tum.edu> writes:
Gold Dragon schrieb:
 I think that I will apply this to whatever I do from now on but one 
 problem I can think of is what if you have a constant of the same name? 
 Yeah, scope will come in to play but what if you want to use the 
 constant and not the template member? Constants could be written as

Why only constants? This applies to anything. Preprocessor and any header inclusion madness are lost, whetever is defined in a template library won't get overridden by a user-space constant or global or whatever. In my taste, there's no sense to make any visible distinction between constant and a variable as long as language can sort it out at least nearly as reliably.
 That would make unsigned with a ui, uc, etc. structs with st(_) and so 
 on. That would give some readability to the overall code would templates 
 be referenced with a 't', followed by the name? Seems interesting 

In my personal expierience it distracts and eats up all the readability that was left. More on that below.
 concept that goes against the paradigm that has govern programming since 
 when people didn't have the liberty to use more than 16-64 characters 
 for variable names (I would know nothing of that time since I was a 
 little baby).

It doesn't go against any paradigm of short names. It follows it, as well as a paradigm of most generic and senseless names, also popular at all times. If a programmer runs over a spot where he would name 2 things similarly, he has 2 choices: (a) he comes up with an imaginative, usually much longer names, which are more descriptive and show the difference in the sense these variables make; or (b) he appends a symbol or 2 to one or both of the names. Sometimes this can be an appropriate common case (like member variables etc.), but usually he will just notice that the variables which were supposed to have the same name (but different sense!) have somewhat different types, so he goes ahead and disambiguates them by adding some hungarian notation. Hurray, a few keystrokes saved at the cost of clarity! And one didn't even have to use the brain cells!
 I do believe some programmers absolutely hate it with a passion that 
 would force the said programmer into a rage destroying whole villages 
 and such. I think they are the minority but with a big voice.

Hungarian notation is not as helpful as generally considered in C++ and D, though it did make major sense in C imo, and it goes against some non-trivial common sense, as shown above. So you just going ahead and dissing the othrers as barbarians isn't nice either. "We are the bolshevik, we are more so we must be right, and can trample down the others"... pfft! BTW, you didn't even count the people who are for/against hungarian notation, so how can you just say that there are less of those against? And why do you think they have such a big voice? Perhaps because that are people who make sense to listen to? People writing major libraries, people who explore the edge of possible, leading magazine contributors, experts? -eye the photoallergic
Aug 02 2004
prev sibling parent Berin Loritsch <bloritsch d-haven.org> writes:
Gold Dragon wrote:
 I think that I will apply this to whatever I do from now on but one 
 problem I can think of is what if you have a constant of the same name? 
 Yeah, scope will come in to play but what if you want to use the 
 constant and not the template member? Constants could be written as
 
 #   const int iKTOMB = 1024;
 

I am not in favor of hungarian notation. I am only in favor of having a name represent the type rather than a single character. When you get when there is a compile error is some terse and unhelpful message that says type 'T' fails in some way. When all you see is 'T' as the type, it makes it seem quite unweildy. However you choose to distinguish between a Type and a variable/function is ok by me. I don't know about you, but when I look at the source code for templates, I get lost on exactly what is trying to be accomplished. THat is because you lose some semantic clues due to the type name being T instead of something more helpful.
Aug 03 2004