www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - 'Auto can only be used for template function arguments' what?

reply "Mehrdad" <wfunction hotmail.com> writes:
void test1(T)(auto ref T) { }
void test2() { int a = 5; test1!(int)(a); }

Is there any reason this should fail?
Jun 26 2012
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/26/2012 06:17 PM, Mehrdad wrote:
 void test1(T)(auto ref T) { }
 void test2() { int a = 5; test1!(int)(a); }

 Is there any reason this should fail?

There is not. I suppose the compiler completes instantiation without looking at the function parameter.
Jun 26 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
On Tuesday, 26 June 2012 at 16:37:30 UTC, Timon Gehr wrote:
 On 06/26/2012 06:17 PM, Mehrdad wrote:
 void test1(T)(auto ref T) { }
 void test2() { int a = 5; test1!(int)(a); }

 Is there any reason this should fail?

There is not. I suppose the compiler completes instantiation without looking at the function parameter.

Well the problem manifests itself in different ways, but would it be safe to say that void foo(auto ref int) { } should not cause problems either?
Jun 26 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, June 27, 2012 02:54:49 Mehrdad wrote:
 On Tuesday, 26 June 2012 at 16:37:30 UTC, Timon Gehr wrote:
 On 06/26/2012 06:17 PM, Mehrdad wrote:
 void test1(T)(auto ref T) { }
 void test2() { int a = 5; test1!(int)(a); }
 
 Is there any reason this should fail?

There is not. I suppose the compiler completes instantiation without looking at the function parameter.

Well the problem manifests itself in different ways, but would it be safe to say that void foo(auto ref int) { } should not cause problems either?

That isn't legal. auto ref can only be used with templated functions. - Jonathan M Davis
Jun 26 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
On Wednesday, 27 June 2012 at 03:54:12 UTC, Jonathan M Davis 
wrote:
 That isn't legal. auto ref can only be used with templated 
 functions.

 - Jonathan M Davis

The trouble is, distinguishing between when it should be illegal seems like a blur to me. Consider all the cases like: - <Regular method> - <Mixin method> - <Template method> - Lambdas (in all forms) - Template class, <regular method> - Template class, <template method> - Regular class, <template method> - Regular class, template method, <mixin method> - Regular class, regular method, <mixin method> - Template class, regular method, <mixin method> - <Templates inside mixins> - yada yada It becomes a *nightmare* to try to get everything right, when you're dealing with templates and mixins. And you run into bugs like this. Why not just allow 'auto ref' for every function type?
Jun 26 2012
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, June 27, 2012 06:03:12 Mehrdad wrote:
 On Wednesday, 27 June 2012 at 03:54:12 UTC, Jonathan M Davis
 
 wrote:
 That isn't legal. auto ref can only be used with templated
 functions.
 
 - Jonathan M Davis

The trouble is, distinguishing between when it should be illegal seems like a blur to me. Consider all the cases like: - <Regular method> - <Mixin method> - <Template method> - Lambdas (in all forms) - Template class, <regular method> - Template class, <template method> - Regular class, <template method> - Regular class, template method, <mixin method> - Regular class, regular method, <mixin method> - Template class, regular method, <mixin method> - <Templates inside mixins> - yada yada It becomes a *nightmare* to try to get everything right, when you're dealing with templates and mixins. And you run into bugs like this. Why not just allow 'auto ref' for every function type?

And how would that work? auto ref duplicates the function. If you pass it an lvalue, then it generates a ref version. If you pass it an rvalue, it generates a non-ref version. For it to work with a normal function, you would somehow have to make it work with only one version. The original idea was for it to work for all functions, but Walter said that it can't be done. So, it only works with templated functions. So, auto ref is pretty much a failure IMHO, since it was supposed to solve the problem of a single function being able to take both lvalues and rvalues efficiently. There has been some discussion of making it so that rvalues work with ref in order to fix that problem, but that hasn't been sorted out yet, since it has to be done in a way that avoids the problems that C++ has allowing const& to take lvalues. - Jonathan M Davis
Jun 26 2012
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 06/27/2012 07:27 AM, kenji hara wrote:
 2012/6/27 Jonathan M Davis<jmdavisProg gmx.com>:
 On Wednesday, June 27, 2012 07:02:28 Mehrdad wrote:
 On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis

 wrote:
 And how would that work? auto ref duplicates the function. If
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value?

That at least sounds like it would work. Walter may have a reason why it doesn't though, since he's the one that said that he didn't think that it was possible. Maybe he just didn't think of it, or maybe it causes some other problem that I can't think of.

After considering about 'auto ref', I was concluded that is an inconsistency of current language spec and we cannot fix it correctly. http://d.puremagic.com/issues/show_bug.cgi?id=8204 Therefore, I have created a thread to suggest new 'auto ref' recently. http://forum.dlang.org/thread/CAFDvkcvf6G8Mc01Tds6ydXqCZbfp1q-a-oeFVk6BGEtwCiUAqg mail.gmail.com Kenji Hara

How does it deal with this case? auto ref id(auto ref arg){ return arg; }
Jun 27 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 06/27/2012 01:12 PM, kenji hara wrote:
 2012/6/27 Timon Gehr<timon.gehr gmx.ch>:
 On 06/27/2012 07:27 AM, kenji hara wrote:
 2012/6/27 Jonathan M Davis<jmdavisProg gmx.com>:
 On Wednesday, June 27, 2012 07:02:28 Mehrdad wrote:

 On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis

 wrote:
 And how would that work? auto ref duplicates the function. If
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value?

That at least sounds like it would work. Walter may have a reason why it doesn't though, since he's the one that said that he didn't think that it was possible. Maybe he just didn't think of it, or maybe it causes some other problem that I can't think of.

After considering about 'auto ref', I was concluded that is an inconsistency of current language spec and we cannot fix it correctly. http://d.puremagic.com/issues/show_bug.cgi?id=8204 Therefore, I have created a thread to suggest new 'auto ref' recently. http://forum.dlang.org/thread/CAFDvkcvf6G8Mc01Tds6ydXqCZbfp1q-a-oeFVk6BGEtwCiUAqg mail.gmail.com Kenji Hara

How does it deal with this case? auto ref id(auto ref arg){ return arg; }

In this case, arg might bind rvalue allocated in the caller of id, so returning it with ref should be rejected statically. But it is yet not implemented in pull#1019. Kenji Hara

This is a quite severe limitation compared to how auto ref works today. As the return ref-ness is inferred and therefore the source code must be available, wouldn't it be a better option to decide lvalue/rvalue-ness at the call site? The compiler would just have to examine the first return statement in the function body.
Jun 27 2012
next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 06/27/12 17:38, Jonathan M Davis wrote:
 On Wednesday, June 27, 2012 13:33:10 Timon Gehr wrote:
 On 06/27/2012 01:12 PM, kenji hara wrote:
 2012/6/27 Timon Gehr<timon.gehr gmx.ch>:
 On 06/27/2012 07:27 AM, kenji hara wrote:
 2012/6/27 Jonathan M Davis<jmdavisProg gmx.com>:
 On Wednesday, June 27, 2012 07:02:28 Mehrdad wrote:
 On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis

 wrote:
 And how would that work? auto ref duplicates the function. If
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value?

That at least sounds like it would work. Walter may have a reason why it doesn't though, since he's the one that said that he didn't think that it was possible. Maybe he just didn't think of it, or maybe it causes some other problem that I can't think of.

After considering about 'auto ref', I was concluded that is an inconsistency of current language spec and we cannot fix it correctly. http://d.puremagic.com/issues/show_bug.cgi?id=8204 Therefore, I have created a thread to suggest new 'auto ref' recently. http://forum.dlang.org/thread/CAFDvkcvf6G8Mc01Tds6ydXqCZbfp1q-a-oeFVk6BG EtwCiUAqg mail.gmail.com Kenji Hara

How does it deal with this case? auto ref id(auto ref arg){ return arg; }

In this case, arg might bind rvalue allocated in the caller of id, so returning it with ref should be rejected statically. But it is yet not implemented in pull#1019. Kenji Hara

This is a quite severe limitation compared to how auto ref works today. As the return ref-ness is inferred and therefore the source code must be available, wouldn't it be a better option to decide lvalue/rvalue-ness at the call site? The compiler would just have to examine the first return statement in the function body.

Considering that if you said that a parameter is auto ref, you're basically saying that it's being passed by value except that you'd like the compiler to avoid the copy if it can, I don't see why it's restrictive at all to make

That's not what auto-ref does. We already had this discussion. auto-ref lets you eg wrap other ref-taking functions; it matters for things like templates and variadics, where ParameterTypeTuple can't be used. You can also check if an argument was passed by reference with traits(isRef) and handle it differently. artur
Jun 27 2012
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 06/27/12 18:04, Artur Skawina wrote:
 On 06/27/12 17:38, Jonathan M Davis wrote:
 On Wednesday, June 27, 2012 13:33:10 Timon Gehr wrote:
 saying that it's being passed by value except that you'd like the compiler to 
 avoid the copy if it can, I don't see why it's restrictive at all to make 

That's not what auto-ref does. We already had this discussion. auto-ref lets

To clarify - /avoiding a copy/ is not the only, or even the main, use of this feature. Copy avoidance mostly matters for structs, and these cases should eventually be handled in a better way - but even when that will be done, auto-ref will still remain useful. artur
Jun 27 2012
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 06/27/12 07:27, kenji hara wrote:
 2012/6/27 Jonathan M Davis <jmdavisProg gmx.com>:
 On Wednesday, June 27, 2012 07:02:28 Mehrdad wrote:
 On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis

 wrote:
 And how would that work? auto ref duplicates the function. If
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value?

That at least sounds like it would work. Walter may have a reason why it doesn't though, since he's the one that said that he didn't think that it was possible. Maybe he just didn't think of it, or maybe it causes some other problem that I can't think of.

After considering about 'auto ref', I was concluded that is an inconsistency of current language spec and we cannot fix it correctly. http://d.puremagic.com/issues/show_bug.cgi?id=8204 Therefore, I have created a thread to suggest new 'auto ref' recently. http://forum.dlang.org/thread/CAFDvkcvf6G8Mc01Tds6ydXqCZbfp1q-a-oeFVk6BGEtwCiUAqg mail.gmail.com

Please do not remove useful functionality in order to fix unrelated problems. "auto ref" isn't perfect, but it works well for some cases. A new "override ref" could work like you describe. artur
Jun 27 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis 
wrote:
 And how would that work? auto ref duplicates the function. If 
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value? - Treat it as though it were a templated parameter. Why does it make any difference here?
Jun 26 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, June 27, 2012 07:02:28 Mehrdad wrote:
 On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis
 
 wrote:
 And how would that work? auto ref duplicates the function. If
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value?

That at least sounds like it would work. Walter may have a reason why it doesn't though, since he's the one that said that he didn't think that it was possible. Maybe he just didn't think of it, or maybe it causes some other problem that I can't think of.
 - Treat it as though it were a templated parameter. Why does it
 make any difference here?

You can't just templatize functions. There are places where templated functions _can't_ be used. For instance, templated functions can't be virtual. And a templated function _can_ be used, then the programmer can just templatize it themselves, avoiding any possible issues caused by functions be automatically templatized. - Jonathan M Davis
Jun 26 2012
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
2012/6/27 Jonathan M Davis <jmdavisProg gmx.com>:
 On Wednesday, June 27, 2012 07:02:28 Mehrdad wrote:
 On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis

 wrote:
 And how would that work? auto ref duplicates the function. If
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value?

That at least sounds like it would work. Walter may have a reason why it doesn't though, since he's the one that said that he didn't think that it was possible. Maybe he just didn't think of it, or maybe it causes some other problem that I can't think of.

After considering about 'auto ref', I was concluded that is an inconsistency of current language spec and we cannot fix it correctly. http://d.puremagic.com/issues/show_bug.cgi?id=8204 Therefore, I have created a thread to suggest new 'auto ref' recently. http://forum.dlang.org/thread/CAFDvkcvf6G8Mc01Tds6ydXqCZbfp1q-a-oeFVk6BGEtwCiUAqg mail.gmail.com Kenji Hara
 - Treat it as though it were a templated parameter. Why does it
 make any difference here?

You can't just templatize functions. There are places where templated functions _can't_ be used. For instance, templated functions can't be virtual. And a templated function _can_ be used, then the programmer can just templatize it themselves, avoiding any possible issues caused by functions be automatically templatized. - Jonathan M Davis

Jun 26 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, June 27, 2012 14:27:08 kenji hara wrote:
 2012/6/27 Jonathan M Davis <jmdavisProg gmx.com>:
 On Wednesday, June 27, 2012 07:02:28 Mehrdad wrote:
 On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis
 
 wrote:
 And how would that work? auto ref duplicates the function. If
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value?

That at least sounds like it would work. Walter may have a reason why it doesn't though, since he's the one that said that he didn't think that it was possible. Maybe he just didn't think of it, or maybe it causes some other problem that I can't think of.

After considering about 'auto ref', I was concluded that is an inconsistency of current language spec and we cannot fix it correctly. http://d.puremagic.com/issues/show_bug.cgi?id=8204 Therefore, I have created a thread to suggest new 'auto ref' recently. http://forum.dlang.org/thread/CAFDvkcvf6G8Mc01Tds6ydXqCZbfp1q-a-oeFVk6BGEtwC iUAqg mail.gmail.com

If it can be done, I'm all for it. We really need a solution to this problem, and conceptually, auto ref was a good idea, it just hasn't worked thus far. - Jonathan M Davis
Jun 26 2012
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
2012/6/27 Timon Gehr <timon.gehr gmx.ch>:
 On 06/27/2012 07:27 AM, kenji hara wrote:
 2012/6/27 Jonathan M Davis<jmdavisProg gmx.com>:
 On Wednesday, June 27, 2012 07:02:28 Mehrdad wrote:

 On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis

 wrote:
 And how would that work? auto ref duplicates the function. If
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value?

That at least sounds like it would work. Walter may have a reason why it doesn't though, since he's the one that said that he didn't think that it was possible. Maybe he just didn't think of it, or maybe it causes some other problem that I can't think of.

After considering about 'auto ref', I was concluded that is an inconsistency of current language spec and we cannot fix it correctly. http://d.puremagic.com/issues/show_bug.cgi?id=8204 Therefore, I have created a thread to suggest new 'auto ref' recently. http://forum.dlang.org/thread/CAFDvkcvf6G8Mc01Tds6ydXqCZbfp1q-a-oeFVk6BGEtwCiUAqg mail.gmail.com Kenji Hara

How does it deal with this case? auto ref id(auto ref arg){ return arg; }

In this case, arg might bind rvalue allocated in the caller of id, so returning it with ref should be rejected statically. But it is yet not implemented in pull#1019. Kenji Hara
Jun 27 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Artur Skawina:

 A new "override ref" could work like you describe.

Introducing yet more modifiers and complexity should be done only if they are very useful. Bye, bearophile
Jun 27 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, June 27, 2012 13:33:10 Timon Gehr wrote:
 On 06/27/2012 01:12 PM, kenji hara wrote:
 2012/6/27 Timon Gehr<timon.gehr gmx.ch>:
 On 06/27/2012 07:27 AM, kenji hara wrote:
 2012/6/27 Jonathan M Davis<jmdavisProg gmx.com>:
 On Wednesday, June 27, 2012 07:02:28 Mehrdad wrote:
 On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis
 
 wrote:
 And how would that work? auto ref duplicates the function. If
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value?

That at least sounds like it would work. Walter may have a reason why it doesn't though, since he's the one that said that he didn't think that it was possible. Maybe he just didn't think of it, or maybe it causes some other problem that I can't think of.

After considering about 'auto ref', I was concluded that is an inconsistency of current language spec and we cannot fix it correctly. http://d.puremagic.com/issues/show_bug.cgi?id=8204 Therefore, I have created a thread to suggest new 'auto ref' recently. http://forum.dlang.org/thread/CAFDvkcvf6G8Mc01Tds6ydXqCZbfp1q-a-oeFVk6BG EtwCiUAqg mail.gmail.com Kenji Hara

How does it deal with this case? auto ref id(auto ref arg){ return arg; }

In this case, arg might bind rvalue allocated in the caller of id, so returning it with ref should be rejected statically. But it is yet not implemented in pull#1019. Kenji Hara

This is a quite severe limitation compared to how auto ref works today. As the return ref-ness is inferred and therefore the source code must be available, wouldn't it be a better option to decide lvalue/rvalue-ness at the call site? The compiler would just have to examine the first return statement in the function body.

Considering that if you said that a parameter is auto ref, you're basically saying that it's being passed by value except that you'd like the compiler to avoid the copy if it can, I don't see why it's restrictive at all to make returning a ref to the parameter illegal. It would be like if you wanted to return a & to a const& parameter in C++, which would be a very bad idea. - Jonathan M Davis
Jun 27 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, June 27, 2012 16:39:12 Artur Skawina wrote:
 On 06/27/12 07:27, kenji hara wrote:
 2012/6/27 Jonathan M Davis <jmdavisProg gmx.com>:
 On Wednesday, June 27, 2012 07:02:28 Mehrdad wrote:
 On Wednesday, 27 June 2012 at 04:26:08 UTC, Jonathan M Davis
 
 wrote:
 And how would that work? auto ref duplicates the function. If
 you pass it an lvalue, then it generates a ref version.

Two solutions: - Turn 'auto ref' into 'ref', but simply have the compiler generate a copy for the caller if he wants to pass by value?

That at least sounds like it would work. Walter may have a reason why it doesn't though, since he's the one that said that he didn't think that it was possible. Maybe he just didn't think of it, or maybe it causes some other problem that I can't think of.

After considering about 'auto ref', I was concluded that is an inconsistency of current language spec and we cannot fix it correctly. http://d.puremagic.com/issues/show_bug.cgi?id=8204 Therefore, I have created a thread to suggest new 'auto ref' recently. http://forum.dlang.org/thread/CAFDvkcvf6G8Mc01Tds6ydXqCZbfp1q-a-oeFVk6BGEt wCiUAqg mail.gmail.com

problems. "auto ref" isn't perfect, but it works well for some cases. A new "override ref" could work like you describe.

What functionality are you talking about? What would you lose? - Jonathan M Davis
Jun 27 2012
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, June 27, 2012 18:13:24 Artur Skawina wrote:
 On 06/27/12 18:04, Artur Skawina wrote:
 On 06/27/12 17:38, Jonathan M Davis wrote:
 On Wednesday, June 27, 2012 13:33:10 Timon Gehr wrote:
 saying that it's being passed by value except that you'd like the
 compiler to avoid the copy if it can, I don't see why it's restrictive
 at all to make> 

lets

this feature. Copy avoidance mostly matters for structs, and these cases should eventually be handled in a better way - but even when that will be done, auto-ref will still remain useful.

The _entire_ reason that auto ref on parameters was introduced in the first place was to have something comparable to C++'s const& which took both lvalues and rvalues efficiently without having to care which it was. That is the purpose of the feature. That's it. It may be that you've found other uses for it, but that's why it exists. The fact that it's implemented the way it is with templates is entirely an artifact of Walter having misunderstand what Andrei intended (which was for auto ref to somehow take both lvalues and rvalues with a single function definition while avoiding copying the lvalues). So, you may have an argument for why auto ref shouldn't be change, but if so, you're arguing for something that auto ref was never intended for. - Jonathan M Davis
Jun 27 2012