www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - auto in library functions

reply "Benjamin Thaut" <code benjamin-thaut.de> writes:
I just created my first pull request for druntime and there where 
multiple commonets to _not_ use auto. I don't quite understand 
why it shouldn't be used in library functions. If it should not 
be used why is it in the language in the first place?

Kind Regards
Benjamin Thaut
Dec 23 2012
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 12/23/12, Benjamin Thaut <code benjamin-thaut.de> wrote:
 I just created my first pull request for druntime and there where
 multiple commonets to _not_ use auto. I don't quite understand
 why it shouldn't be used in library functions. If it should not
 be used why is it in the language in the first place?

 Kind Regards
 Benjamin Thaut

auto is mainly useful for complex return types or for nested types which you can't otherwise declare (called voldemort types), e.g.: auto x = joiner([""], "xyz"); writeln(typeid(x)); // => std.algorithm.joiner!(string[], string).joiner.Result When the type is simple you should use the name of the type instead of auto because it serves as useful documentation, especially in library functions where you might later have to fix a bug. It's really useful to know exactly what type each variable is without having to waste time e.g. looking at function declarations to figure out the return type.
Dec 23 2012
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, December 23, 2012 23:05:28 Andrej Mitrovic wrote:
 On 12/23/12, Benjamin Thaut <code benjamin-thaut.de> wrote:
 I just created my first pull request for druntime and there where
 multiple commonets to _not_ use auto. I don't quite understand
 why it shouldn't be used in library functions. If it should not
 be used why is it in the language in the first place?
 
 Kind Regards
 Benjamin Thaut

auto is mainly useful for complex return types or for nested types which you can't otherwise declare (called voldemort types), e.g.: auto x = joiner([""], "xyz"); writeln(typeid(x)); // => std.algorithm.joiner!(string[], string).joiner.Result When the type is simple you should use the name of the type instead of auto because it serves as useful documentation, especially in library functions where you might later have to fix a bug. It's really useful to know exactly what type each variable is without having to waste time e.g. looking at function declarations to figure out the return type.

Yeah. I don't know what they were complaining about in the pull request, but I think that Andrej has it right. Basically, when declaring the return type, if you need type inference, use auto, but if you don't, then put the explicit type so that it's clearer in the documentation. druntime is unlikely to need type inference, as its functions generally return simple, explicit types rather than depending on the types passed to them like happens often in Phobos. And they don't usually return types which are heavily templatized, which is where auto return types really shine. Using auto for local variables, however, is completely differente. There, it's frequently best to use it unless you need to declare a variable as a specific type (e.g. size_t i = 0; instead of auto i = 0; when you need size_t). It makes refactoring the code easier and reduces code breakage when types change. But with return types, it affects the documentation and people's ability to figure out what a function does, so as useful as auto return types can be, they come with a definite cost and should be avoided if they're not needed. - Jonathan M Davis
Dec 23 2012
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/23/12 9:13 PM, Peter Alexander wrote:
 On Sunday, 23 December 2012 at 22:41:56 UTC, Andrej Mitrovic wrote:
 You say auto helps with refactoring. I say not using it helps with
 catching bugs. It comes down to a question of what you value more,
 your time while coding, or your time while debugging.

Or even just reading code, which is what programmers spend most of their time doing. When reading code, you want things to be both clear and succinct. With long (or inexpressible) type names, using auto makes the code more succinct, but for simple types like int, bool, or structs/classes with short names, it's far more clear to just use the type name. I don't buy the refactoring argument. Refactoring is rare.

In the words of Dwight Schrute: false. Andrei
Dec 23 2012
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2012-12-23 23:16, Jonathan M Davis wrote:

 But with return types, it affects the documentation and people's ability to
 figure out what a function does, so as useful as auto return types can be, they
 come with a definite cost and should be avoided if they're not needed.

The compiler should be able to replace "auto" with the actual type when generating documentation. -- /Jacob Carlborg
Dec 24 2012
parent Jacob Carlborg <doob me.com> writes:
On 2012-12-24 16:09, Jonathan M Davis wrote:

 That would be horrible. Do you remember what std.algorithm looked like before
 we were able to put auto in the documentation? It scared most everyone who
 looked at it. We don't _want_ the actual return type in the docs. auto  return
 types makes std.algorithm digestible.

Right. This is what I still don't like about ranges, there is no type/interface to name them. It would be so nice if a struct could implement an interface or similar.
 And with some functions, they literally
 return completely different types depending on their arguments, making it
 impossible for the compiler to pick anything for the return type.

Hmm, right, that can be a problem. -- /Jacob Carlborg
Dec 24 2012
prev sibling next sibling parent "Benjamin Thaut" <code benjamin-thaut.de> writes:
On Sunday, 23 December 2012 at 22:16:54 UTC, Jonathan M Davis 
wrote:
 Yeah. I don't know what they were complaining about in the pull 
 request, but I
 think that Andrej has it right. Basically, when declaring the 
 return type, if
 you need type inference, use auto, but if you don't, then put 
 the explicit
 type so that it's clearer in the documentation. druntime is 
 unlikely to need
 type inference, as its functions generally return simple, 
 explicit types
 rather than depending on the types passed to them like happens 
 often in
 Phobos. And they don't usually return types which are heavily 
 templatized,
 which is where auto return types really shine.

 Using auto for local variables, however, is completely 
 differente. There, it's
 frequently best to use it unless you need to declare a variable 
 as a specific
 type (e.g. size_t i = 0; instead of auto i = 0; when you need 
 size_t). It
 makes refactoring the code easier and reduces code breakage 
 when types change.
 But with return types, it affects the documentation and 
 people's ability to
 figure out what a function does, so as useful as auto return 
 types can be, they
 come with a definite cost and should be avoided if they're not 
 needed.

 - Jonathan M Davis

It's always about local variables. Kind Regards Benjamin Thaut
Dec 23 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, December 23, 2012 14:16:02 Jonathan M Davis wrote:
 On Sunday, December 23, 2012 23:05:28 Andrej Mitrovic wrote:
 On 12/23/12, Benjamin Thaut <code benjamin-thaut.de> wrote:
 I just created my first pull request for druntime and there where
 multiple commonets to _not_ use auto. I don't quite understand
 why it shouldn't be used in library functions. If it should not
 be used why is it in the language in the first place?
 
 Kind Regards
 Benjamin Thaut

auto is mainly useful for complex return types or for nested types which you can't otherwise declare (called voldemort types), e.g.: auto x = joiner([""], "xyz"); writeln(typeid(x)); // => std.algorithm.joiner!(string[], string).joiner.Result When the type is simple you should use the name of the type instead of auto because it serves as useful documentation, especially in library functions where you might later have to fix a bug. It's really useful to know exactly what type each variable is without having to waste time e.g. looking at function declarations to figure out the return type.

Yeah. I don't know what they were complaining about in the pull request, but I think that Andrej has it right.

It looks like I misunderstood what was being said here when I said that I agree with Andrej. I thought that we were talking explicitly about the return type on a function. I agree that using auto on function return types should be restricted, but I do _not_ agree that using auto for local variables should be restricted. Quite the opposite. I think that auto should be used very heavily for local variables and that explicit types on local variables should only be used when they're required. It's much easier to refactor code that way and reduces the risk of code breakage due to type changes. - Jonathan M Davis
Dec 23 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, December 23, 2012 23:21:19 Benjamin Thaut wrote:
 It's always about local variables.

Then I don't agree with Andrej at all. For local variables, in general, I think that auto should be used unless you actually need to explicitly give the type. It makes refactoring the code much easier and reduces code breakage due to type changes. If it really helps to understand the code if you give the type, then it might make sense to give the type explicitly, but the combination of functions being called, variable names used, and what the code itself is doing usually makes it so that isn't really an issue. - Jonathan M Davis
Dec 23 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 12/23/12, Jonathan M Davis <jmdavisProg gmx.com> wrote:
 It makes refactoring the code much easier and reduces code breakage
 due to type changes.

I don't buy that. If a type of a variable changes don't you want to *know* the new type of the variable? If between two commits you have: auto x = z; and then: auto x = z; How will you know that x has become something completely different? You would have to know what 'z' is, and it's hard to know that if you're using auto inference everywhere. I personally only use auto when necessary, and that's when: 1) using templates, 2) using voldemort types and 3) for quick hash lookups via "if (auto x = key in hash) { }". Furthermore not using auto helps you visually detect signed/unsigned bugs. If you have: auto x = z; if (x < 0) { } You better declare a type for x because if you leave it unsigned you'll never notice if something is wrong. Btw Walter denied a pull for comparing `unsigned < 0`, so you're left on your own to care about these issues, the compiler wont help out. You say auto helps with refactoring. I say not using it helps with catching bugs. It comes down to a question of what you value more, your time while coding, or your time while debugging.
Dec 23 2012
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/23/12 4:54 PM, Benjamin Thaut wrote:
 I just created my first pull request for druntime and there where
 multiple commonets to _not_ use auto. I don't quite understand why it
 shouldn't be used in library functions. If it should not be used why is
 it in the language in the first place?

Is this it? https://github.com/D-Programming-Language/druntime/pull/368 As a general rule, there should be justification for cases where auto is not to be used. Auto should be reached for by default. Andrei
Dec 23 2012
prev sibling next sibling parent "Benjamin Thaut" <code benjamin-thaut.de> writes:
On Sunday, 23 December 2012 at 22:49:16 UTC, Andrei Alexandrescu 
wrote:
 Is this it?

 https://github.com/D-Programming-Language/druntime/pull/368

 As a general rule, there should be justification for cases 
 where auto is not to be used. Auto should be reached for by 
 default.


 Andrei

Yes this is it. So should I know go in and change everything back to auto? Kind Regards Benjamin Thaut
Dec 23 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 00:12:47 Benjamin Thaut wrote:
 Yes this is it. So should I know go in and change everything back
 to auto?

Feel free to do so. - Jonathan M Davis
Dec 23 2012
prev sibling next sibling parent "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Sunday, 23 December 2012 at 22:41:56 UTC, Andrej Mitrovic 
wrote:
 You say auto helps with refactoring. I say not using it helps 
 with
 catching bugs. It comes down to a question of what you value 
 more,
 your time while coding, or your time while debugging.

Or even just reading code, which is what programmers spend most of their time doing. When reading code, you want things to be both clear and succinct. With long (or inexpressible) type names, using auto makes the code more succinct, but for simple types like int, bool, or structs/classes with short names, it's far more clear to just use the type name. I don't buy the refactoring argument. Refactoring is rare. Refactoring gains are not worth compromising readability.
Dec 23 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
 If a type of a variable changes don't you want to *know* the 
 new type of the variable?

Actually, not at all. Consider this C++ code as an example: std::vector<int> foo; template<class T> void process(T &data) { ... } int test() { auto copy = foo; process(copy); if (copy.size() == foo.size()) foo = copy; return copy.size(); } The word 'auto' protects against changes to the type of 'foo' (say, for example, if it was alter changed into std::deque). No need to explicitly state the type of 'copy' anywhere.
Dec 23 2012
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 12:07:53 Jacob Carlborg wrote:
 On 2012-12-23 23:16, Jonathan M Davis wrote:
 But with return types, it affects the documentation and people's ability
 to
 figure out what a function does, so as useful as auto return types can be,
 they come with a definite cost and should be avoided if they're not
 needed.

generating documentation.

That would be horrible. Do you remember what std.algorithm looked like before we were able to put auto in the documentation? It scared most everyone who looked at it. We don't _want_ the actual return type in the docs. auto return types makes std.algorithm digestible. And with some functions, they literally return completely different types depending on their arguments, making it impossible for the compiler to pick anything for the return type. - Jonathan M Davis
Dec 24 2012