digitalmars.D - Template functions, can we make it more simple?
- SteveGuo (19/19) Aug 02 2013 I'm not an expert on programming language, if I made a naive
- monarch_dodra (8/27) Aug 02 2013 Types can be deduced automatically, so you can simply write:
- SteveGuo (10/42) Aug 02 2013 Thanks for reply!
- Tommi (14/22) Aug 02 2013 I think it could get pretty confusing. I.e.:
- SteveGuo (5/18) Aug 02 2013 We know that normal function parameter declaration is the form of
- Timon Gehr (2/27) Aug 02 2013 Note that currently this is parsed as having _only_ PARAMTYPE.
- SteveGuo (5/6) Aug 02 2013 I just tested _only_
-
monarch_dodra
(6/12)
Aug 02 2013
- SteveGuo (8/12) Aug 02 2013 Thanks for pointing out my misunderstanding.
- monarch_dodra (5/19) Aug 02 2013 No difference.
- SteveGuo (1/4) Aug 02 2013 But we can make a compiler which think its illegal.
- SteveGuo (3/3) Aug 02 2013 void foo(int); // function declaration
- Dicebot (3/5) Aug 02 2013 Wrong. Specifying only types was perfectly legal in C and remains
- SteveGuo (6/8) Aug 02 2013 auto Add(a, b) {}
- Andrei Alexandrescu (10/16) Aug 02 2013 One variant discussed was:
- Andrej Mitrovic (6/10) Aug 02 2013 You'd still have to use typeof(x) and typeof(y) to extract the types,
- Timon Gehr (2/12) Aug 02 2013 bool compare(a,b) if(__traits(compiles,a
- Andrei Alexandrescu (5/18) Aug 02 2013 Direct use of __traits is unrecommended outside the stdlib. I had this
- Timon Gehr (19/38) Aug 02 2013 The language is not expressive enough to wrap __traits(compiles,a
- H. S. Teoh (18/38) Aug 02 2013 [...]
- SteveGuo (7/26) Aug 02 2013 If these syntax is feasible to template functions, is it possible
- H. S. Teoh (16/48) Aug 02 2013 I think that's a bad idea. It's too ambiguous. What will you do with
- SteveGuo (14/19) Aug 02 2013 class A
- H. S. Teoh (19/43) Aug 02 2013 How would you translate this to the new syntax:
- SteveGuo (34/34) Aug 02 2013 class A
- H. S. Teoh (9/25) Aug 03 2013 [...]
- Dicebot (3/9) Aug 02 2013 Question is "should we"? It creates syntax ambiguity (a and b can
- Walter Bright (7/18) Aug 02 2013 The trouble with this is that sometimes people will use a type without a...
- SteveGuo (4/11) Aug 02 2013 I know there is no perfect things in the world, But I hope that D
- F i L (15/15) Aug 02 2013 I've brought this up on here awhile ago, and many people seemed
- Andrei Alexandrescu (7/25) Aug 02 2013 The converse question is who's hand-writing a bunch of functions that
- John Colvin (7/33) Aug 03 2013 The existence of template restrictions and the swathes of
- Suliman (1/9) Aug 02 2013 I like it!
- monarch_dodra (10/25) Aug 03 2013 Regardless of the existing merits, that would be a (massive)
- F i L (6/16) Aug 03 2013 Sure, but not if you do it like my second example:
- monarch_dodra (11/18) Aug 03 2013 I'm not sure auto is the best choice of keywords, given potential
- F i L (5/16) Aug 03 2013 Okay, so I mostly agree with this. I guess adding this change
- Flamaros (10/29) Aug 03 2013 I prefer the current template syntax, it's nice to want to reduce
I'm not an expert on programming language, if I made a naive issue, just forgive me:p Can we declare a template function like this? auto Add(a, b) // Note a, b do not have type, that means a and b use template type { return a + b; } auto Sub(a, int b) // a uses template type, b is fixed to int { return a - b; } When we call the function, Add(1, 2); // deduced to be Add(int, int); Add(1.5, 2.3); // deduced to be Add(double, double); Add(1.5, "Hello"); // compiler error! Sub(1.5, 1); // deduced to be Add(double, int); Sub(1, 1.1); // deduced to be Add(int, int); compiler error, double can not converted to int automatically
Aug 02 2013
On Friday, 2 August 2013 at 20:34:04 UTC, SteveGuo wrote:I'm not an expert on programming language, if I made a naive issue, just forgive me:pYes, this would have been better asked in .learn, but no matter.Can we declare a template function like this? auto Add(a, b) // Note a, b do not have type, that means a and b use template type { return a + b; } auto Sub(a, int b) // a uses template type, b is fixed to int { return a - b; } When we call the function, Add(1, 2); // deduced to be Add(int, int); Add(1.5, 2.3); // deduced to be Add(double, double); Add(1.5, "Hello"); // compiler error! Sub(1.5, 1); // deduced to be Add(double, int); Sub(1, 1.1); // deduced to be Add(int, int); compiler error, double can not converted to int automaticallyTypes can be deduced automatically, so you can simply write: auto Add(A, B)(A a, B b); The type is explicit in the *declaration*, but when you call "add(1, 2)", the compiler will *deduce* A and B to be int. Ditto for sub: auto Sub(A a)(A a, int b);
Aug 02 2013
On Friday, 2 August 2013 at 20:37:55 UTC, monarch_dodra wrote:On Friday, 2 August 2013 at 20:34:04 UTC, SteveGuo wrote:Thanks for reply! auto Add(A, B)(A a, B b); // Yes, this is the template function declaration of D manner But I mean if the syntax can be more simple? auto Add(A, B)(A a, B b); // type A, B appears twice // Can we just make it more simple? auto Add(a, b) { }I'm not an expert on programming language, if I made a naive issue, just forgive me:pYes, this would have been better asked in .learn, but no matter.Can we declare a template function like this? auto Add(a, b) // Note a, b do not have type, that means a and b use template type { return a + b; } auto Sub(a, int b) // a uses template type, b is fixed to int { return a - b; } When we call the function, Add(1, 2); // deduced to be Add(int, int); Add(1.5, 2.3); // deduced to be Add(double, double); Add(1.5, "Hello"); // compiler error! Sub(1.5, 1); // deduced to be Add(double, int); Sub(1, 1.1); // deduced to be Add(int, int); compiler error, double can not converted to int automaticallyTypes can be deduced automatically, so you can simply write: auto Add(A, B)(A a, B b); The type is explicit in the *declaration*, but when you call "add(1, 2)", the compiler will *deduce* A and B to be int. Ditto for sub: auto Sub(A a)(A a, int b);
Aug 02 2013
On Friday, 2 August 2013 at 20:50:00 UTC, SteveGuo wrote:auto Add(A, B)(A a, B b); // Yes, this is the template function declaration of D manner But I mean if the syntax can be more simple? auto Add(A, B)(A a, B b); // type A, B appears twice // Can we just make it more simple? auto Add(a, b) { }I think it could get pretty confusing. I.e.: module foo; struct a { } struct b { } ---- module bar; import foo; auto Add(a, b) { } // [1] ---- [1] Here the unsuspecting programmer thinks he's writing a template function, not knowing that one module he's importing actually specifies 'a' and 'b' as types, which makes his Add a regular function taking unnamed variables of types 'a' and 'b'.
Aug 02 2013
I think it could get pretty confusing. I.e.: module foo; struct a { } struct b { } ---- module bar; import foo; auto Add(a, b) { } // [1] ---- [1] Here the unsuspecting programmer thinks he's writing a template function, not knowing that one module he's importing actually specifies 'a' and 'b' as types, which makes his Add a regular function taking unnamed variables of types 'a' and 'b'.We know that normal function parameter declaration is the form of "PARAMTYPE param" but in this declaration "auto Add(a, b) { }" the parameter do not have PARAMTYPE, compiler can detect this issue, so, the compiler knows a or b is not a type, it treats them as template
Aug 02 2013
On 08/02/2013 11:20 PM, SteveGuo wrote:Note that currently this is parsed as having _only_ PARAMTYPE.I think it could get pretty confusing. I.e.: module foo; struct a { } struct b { } ---- module bar; import foo; auto Add(a, b) { } // [1] ---- [1] Here the unsuspecting programmer thinks he's writing a template function, not knowing that one module he's importing actually specifies 'a' and 'b' as types, which makes his Add a regular function taking unnamed variables of types 'a' and 'b'.We know that normal function parameter declaration is the form of "PARAMTYPE param" but in this declaration "auto Add(a, b) { }" the parameter do not have PARAMTYPE, compiler can detect this issue, so, the compiler knows a or b is not a type, it treats them as template
Aug 02 2013
Note that currently this is parsed as having _only_ PARAMTYPE.I just tested _only_ void foo(_only_ a) { } but the compiler complaints "undefined identifier _only_"
Aug 02 2013
On Friday, 2 August 2013 at 21:36:38 UTC, SteveGuo wrote:<facepalm /> He meant that when you only have a single token it is parsed as PARAMTYPE and not varname. EG: void foo(int);Note that currently this is parsed as having _only_ PARAMTYPE.I just tested _only_ void foo(_only_ a) { } but the compiler complaints "undefined identifier _only_"
Aug 02 2013
He meant that when you only have a single token it is parsed as PARAMTYPE and not varname. EG: void foo(int);Thanks for pointing out my misunderstanding. But we can make a compiler which can "understand" what we want it understand. void foo(int); // this is just a declaration, not a definition auto foo(a) // this is a definition, with a function body, they are different { }
Aug 02 2013
On Friday, 2 August 2013 at 22:00:44 UTC, SteveGuo wrote:No difference. void foo(int) {} Is perfectly legal.He meant that when you only have a single token it is parsed as PARAMTYPE and not varname. EG: void foo(int);Thanks for pointing out my misunderstanding. But we can make a compiler which can "understand" what we want it understand. void foo(int); // this is just a declaration, not a definition auto foo(a) // this is a definition, with a function body, they are different { }
Aug 02 2013
void foo(int) {} Is perfectly legal.But we can make a compiler which think its illegal.
Aug 02 2013
void foo(int) {} Is perfectly legal.We could change the language definition, make things like "void foo(int) {}" illegal
Aug 02 2013
On Friday, 2 August 2013 at 22:12:29 UTC, SteveGuo wrote:No. Useless breaking change.void foo(int) {} Is perfectly legal.We could change the language definition, make things like "void foo(int) {}" illegal
Aug 02 2013
void foo(int); // function declaration void foo(int a) {} // function definition auto foo(a) {} // template function definition
Aug 02 2013
On Friday, 2 August 2013 at 21:20:55 UTC, SteveGuo wrote:We know that normal function parameter declaration is the form of "PARAMTYPE param"Wrong. Specifying only types was perfectly legal in C and remains so in D. It would have been a major breaking change.
Aug 02 2013
Wrong. Specifying only types was perfectly legal in C and remains so in D. It would have been a major breaking change.auto Add(a, b) {} Is it feasible? "Specifying only types was perfectly legal in C and emains so in D" Why don't we change our thinking way? Why we couldn't eliminate "PARAMTYPE _only_", make "auto Add(a, b) {} " works?
Aug 02 2013
On 2013-08-02 21:30:20 +0000, Dicebot said:On Friday, 2 August 2013 at 21:20:55 UTC, SteveGuo wrote:One variant discussed was: auto fun(auto x, auto y) { … } We concluded that's poor style anyway because most function should have constraints on types. Truth be told, at the time of that decision parameter names (viz. x and y) could not be used in template constraints. Now they could, so in a way that reopens the question. Either way, this is not enabling something we couldn't do, so it's not high on the priority list. AndreiWe know that normal function parameter declaration is the form of "PARAMTYPE param"Wrong. Specifying only types was perfectly legal in C and remains so in D. It would have been a major breaking change.
Aug 02 2013
On 8/2/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:auto fun(auto x, auto y) { =85 } Truth be told, at the time of that decision parameter names (viz. x and y) could not be used in template constraints. Now they could, so in a way that reopens the question.You'd still have to use typeof(x) and typeof(y) to extract the types, so even though you end up making the template declaration simpler you also make the constraint more complicated. Anyway after one uses templates for a longer while it becomes apparent that they're rather easy to use in D.
Aug 02 2013
On 08/03/2013 12:06 AM, Andrej Mitrovic wrote:On 8/2/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:bool compare(a,b) if(__traits(compiles,a<b)) { return a<b; }auto fun(auto x, auto y) { … } Truth be told, at the time of that decision parameter names (viz. x and y) could not be used in template constraints. Now they could, so in a way that reopens the question.You'd still have to use typeof(x) and typeof(y) to extract the types, so even though you end up making the template declaration simpler you also make the constraint more complicated. ...
Aug 02 2013
On 8/2/13 3:17 PM, Timon Gehr wrote:On 08/03/2013 12:06 AM, Andrej Mitrovic wrote:Direct use of __traits is unrecommended outside the stdlib. I had this pattern in mind: bool compare(auto a, auto b) if (is(typeof(a < b) : bool)) { ... } AndreiOn 8/2/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:bool compare(a,b) if(__traits(compiles,a<b)) { return a<b; }auto fun(auto x, auto y) { … } Truth be told, at the time of that decision parameter names (viz. x and y) could not be used in template constraints. Now they could, so in a way that reopens the question.You'd still have to use typeof(x) and typeof(y) to extract the types, so even though you end up making the template declaration simpler you also make the constraint more complicated. ...
Aug 02 2013
On 08/03/2013 12:19 AM, Andrei Alexandrescu wrote:On 8/2/13 3:17 PM, Timon Gehr wrote:The language is not expressive enough to wrap __traits(compiles,a<b) in the stdlib.On 08/03/2013 12:06 AM, Andrej Mitrovic wrote:Direct use of __traits is unrecommended outside the stdlib.On 8/2/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:bool compare(a,b) if(__traits(compiles,a<b)) { return a<b; }auto fun(auto x, auto y) { … } Truth be told, at the time of that decision parameter names (viz. x and y) could not be used in template constraints. Now they could, so in a way that reopens the question.You'd still have to use typeof(x) and typeof(y) to extract the types, so even though you end up making the template declaration simpler you also make the constraint more complicated. ...I had this pattern in mind: bool compare(auto a, auto b) if (is(typeof(a < b) : bool)) { ... } ...Checking for implicit conversion to bool is redundant due to how operator overloading is handled for '<'. Furthermore, this constraint is not sufficient. bool compare(A,B)(A a,B b) if (is(typeof(a < b) : bool)){ return a<b; } void main(){ int o(T)(T r){ return 0; } static struct S{ alias o opCmp; } compare(S(),S()); // causes error in template body } DMD's implementation of __traits(compiles,...) currently shares this issue; this is a compiler bug as far as I can tell. The above behaviour is to be expected for is(typeof(.)) though.
Aug 02 2013
On Fri, Aug 02, 2013 at 03:19:33PM -0700, Andrei Alexandrescu wrote:On 8/2/13 3:17 PM, Timon Gehr wrote:[...] I like this syntax. I'm worried, though, about how it will interact with explicit template parameters. E.g., how would you express this: bool func(R,T,U)(T t, U u) { ... } in the new syntax? bool func(R)(auto t, auto u) { ... } ? What if we have variadics on either side? I'm still on the fence as to whether we should add the new syntax, nice as it is. The current syntax is far more unambiguous, and allows you to specify signature constraints on the input types directly, as well as use it in the return type spec, without needing to say typeof(t) or typeof(u). T -- "The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." -- Bertrand Russell. "How come he didn't put 'I think' at the end of it?" -- AnonymousOn 08/03/2013 12:06 AM, Andrej Mitrovic wrote:Direct use of __traits is unrecommended outside the stdlib. I had this pattern in mind: bool compare(auto a, auto b) if (is(typeof(a < b) : bool)) { ... }On 8/2/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:bool compare(a,b) if(__traits(compiles,a<b)) { return a<b; }auto fun(auto x, auto y) { … } Truth be told, at the time of that decision parameter names (viz. x and y) could not be used in template constraints. Now they could, so in a way that reopens the question.You'd still have to use typeof(x) and typeof(y) to extract the types, so even though you end up making the template declaration simpler you also make the constraint more complicated. ...
Aug 02 2013
I like this syntax. I'm worried, though, about how it will interact with explicit template parameters. E.g., how would you express this: bool func(R,T,U)(T t, U u) { ... } in the new syntax? bool func(R)(auto t, auto u) { ... } ? What if we have variadics on either side? I'm still on the fence as to whether we should add the new syntax, nice as it is. The current syntax is far more unambiguous, and allows you to specify signature constraints on the input types directly, as well as use it in the return type spec, without needing to say typeof(t) or typeof(u). TIf these syntax is feasible to template functions, is it possible to apply it to class template? class A { int a; // normal member auto b; // template member? }
Aug 02 2013
On Sat, Aug 03, 2013 at 01:03:36AM +0200, SteveGuo wrote:I think that's a bad idea. It's too ambiguous. What will you do with template member functions? class A { auto b(auto c) { ... } } What are the template parameters of A? I still think the current syntax is better. It's a little more verbose in some cases, but I think that's not a big deal. After having used D templates for a while now, the syntax is actually very comfortable to use. I think this kind of cosmetic change is not worth the effort (and potential breakage) at this point in time. T -- A computer doesn't mind if its programs are put to purposes that don't match their names. -- D. KnuthI like this syntax. I'm worried, though, about how it will interact with explicit template parameters. E.g., how would you express this: bool func(R,T,U)(T t, U u) { ... } in the new syntax? bool func(R)(auto t, auto u) { ... } ? What if we have variadics on either side? I'm still on the fence as to whether we should add the new syntax, nice as it is. The current syntax is far more unambiguous, and allows you to specify signature constraints on the input types directly, as well as use it in the return type spec, without needing to say typeof(t) or typeof(u). TIf these syntax is feasible to template functions, is it possible to apply it to class template? class A { int a; // normal member auto b; // template member? }
Aug 02 2013
class A { auto b(auto c) { ... } } What are the template parameters of A?class A { void foo(auto x) { ... } } int main() { scope a = new A; a.foo(1); // this means A has a member function "void foo(int x) {...}" a.foo(1.1); // this means A has another member function "void foo(double x) {...}" // compiler will automatically build two versions of function "foo" }
Aug 02 2013
On Sat, Aug 03, 2013 at 01:20:02AM +0200, SteveGuo wrote:How would you translate this to the new syntax: class A(T,U) { T fun1(U x) { ... } U fun2(T x) { ... } V fun3(V)(V x) { ... } auto fun4(T)(T x) { ... } auto fun5(V)(T x, V y) { ... } const(T) fun6(T x) { ... } T p; T q; U r; U s; } ? T -- The easy way is the wrong way, and the hard way is the stupid way. Pick one.class A { auto b(auto c) { ... } } What are the template parameters of A?class A { void foo(auto x) { ... } } int main() { scope a = new A; a.foo(1); // this means A has a member function "void foo(int x) {...}" a.foo(1.1); // this means A has another member function "void foo(double x) {...}" // compiler will automatically build two versions of function "foo" }
Aug 02 2013
class A { auto n; void foo(auto x) { ... } } int main() { scope a = new A; scope b = new A; a.foo(1); // this means A has a member function "void foo(int x) {...}" a.foo(1.1); // this means A has another member function "void foo(double x) {...}" // compiler will automatically build two versions of function "foo" b.foo("Hello"); // this means A has a third "foo" member function with parameter "string []" a.n = 1.3; // class A(type 1), which has a data member double n; b.n = 1 // class A(type 2), which has a data member int n; /* So there are two class type A1 and A2 class A1 { double n; void foo(int x) { ... } } class A2 { int n; void foo(double x) { ... } } */ }
Aug 02 2013
On Fri, Aug 02, 2013 at 04:29:39PM -0700, H. S. Teoh wrote: [...]How would you translate this to the new syntax: class A(T,U) { T fun1(U x) { ... } U fun2(T x) { ... } V fun3(V)(V x) { ... } auto fun4(T)(T x) { ... } auto fun5(V)(T x, V y) { ... } const(T) fun6(T x) { ... } T p; T q; U r; U s; }[...] Since no good answer is forthcoming, I'm forced to conclude that the new syntax is only marginally useful, and doesn't handle all the cases the current syntax can. So I don't think this change is worth the effort. T -- The computer is only a tool. Unfortunately, so is the user. -- Armaphine, K5
Aug 03 2013
On Friday, 2 August 2013 at 20:50:00 UTC, SteveGuo wrote:But I mean if the syntax can be more simple? auto Add(A, B)(A a, B b); // type A, B appears twice // Can we just make it more simple? auto Add(a, b) { }Question is "should we"? It creates syntax ambiguity (a and b can be already existing types) and does not really improve language.
Aug 02 2013
Question is "should we"? It creates syntax ambiguity (a and b can be already existing types) and does not really improve language.Sorry for my pool English:p I think compiler can detect the difference. auto Add(a, b) {} // Compiler can detect "there is nothing in front of a and b, so a and b is template, not types defined in other modules"
Aug 02 2013
On Friday, 2 August 2013 at 21:29:12 UTC, SteveGuo wrote:auto Add(auto a, auto b) would be unambigious imo. I don't see a need for that language change though. My favourite colour of a bikeshed is blue.Question is "should we"? It creates syntax ambiguity (a and b can be already existing types) and does not really improve language.Sorry for my pool English:p I think compiler can detect the difference. auto Add(a, b) {} // Compiler can detect "there is nothing in front of a and b, so a and b is template, not types defined in other modules"
Aug 02 2013
On 8/2/2013 1:34 PM, SteveGuo wrote:I'm not an expert on programming language, if I made a naive issue, just forgive me:pWe never forgive, and the internet never forgets! :-)Can we declare a template function like this? auto Add(a, b) // Note a, b do not have type, that means a and b use template type { return a + b; } auto Sub(a, int b) // a uses template type, b is fixed to int { return a - b; }The trouble with this is that sometimes people will use a type without an identifier in order to indicate that the parameter is not used: auto Foo(int, unsigned x) But also note that for lambdas, D does allow the form you suggest, as there weren't backwards compatibility issues with it.
Aug 02 2013
The trouble with this is that sometimes people will use a type without an identifier in order to indicate that the parameter is not used: auto Foo(int, unsigned x) But also note that for lambdas, D does allow the form you suggest, as there weren't backwards compatibility issues with it.I know there is no perfect things in the world, But I hope that D can approach the perfect, Because I really love this language! Thanks for inventing this beautiful language:)
Aug 02 2013
I've brought this up on here awhile ago, and many people seemed to be against it. Which I don't agree with, since the ambiguities it creates are easily addressed (from a design perspective at least) and only exist so that C-style code is usable within D. It could work like: auto func(a, b) // auto func(A, B)(A a, B b) auto func(int a, b) // auto func(B)(int a, B b) auto func(int ?) // C-style: auto func(int) Or... auto func(auto a, auto b) // like C++14 I mean honestly, who's hand-writing a bunch of functions with nameless params in real D code? Sure it's used for linking to C, which is semi-common, but I think having the much cleaner syntax available to "actual" D code makes more sense that not having it solely for linking-to-C-in-familiar-C-style reasons.
Aug 02 2013
On 2013-08-03 00:51:19 +0000, F i L said:I've brought this up on here awhile ago, and many people seemed to be against it. Which I don't agree with, since the ambiguities it creates are easily addressed (from a design perspective at least) and only exist so that C-style code is usable within D. It could work like: auto func(a, b) // auto func(A, B)(A a, B b) auto func(int a, b) // auto func(B)(int a, B b) auto func(int ?) // C-style: auto func(int) Or... auto func(auto a, auto b) // like C++14 I mean honestly, who's hand-writing a bunch of functions with nameless params in real D code? Sure it's used for linking to C, which is semi-common, but I think having the much cleaner syntax available to "actual" D code makes more sense that not having it solely for linking-to-C-in-familiar-C-style reasons.The converse question is who's hand-writing a bunch of functions that don't need their arguments' types in any way (for constraints or otherwise). There are very few functions that really apply to all types. It's possible that by allowing auto parameter types we encourage a sloppy style. Andrei
Aug 02 2013
On Saturday, 3 August 2013 at 01:15:48 UTC, Andrei Alexandrescu wrote:On 2013-08-03 00:51:19 +0000, F i L said:The existence of template restrictions and the swathes of different things in std.traits and elsewhere really persuaded me to think about the requirements of my templates. Having to spell it out a bit is a good thing. In short: I agree.I've brought this up on here awhile ago, and many people seemed to be against it. Which I don't agree with, since the ambiguities it creates are easily addressed (from a design perspective at least) and only exist so that C-style code is usable within D. It could work like: auto func(a, b) // auto func(A, B)(A a, B b) auto func(int a, b) // auto func(B)(int a, B b) auto func(int ?) // C-style: auto func(int) Or... auto func(auto a, auto b) // like C++14 I mean honestly, who's hand-writing a bunch of functions with nameless params in real D code? Sure it's used for linking to C, which is semi-common, but I think having the much cleaner syntax available to "actual" D code makes more sense that not having it solely for linking-to-C-in-familiar-C-style reasons.The converse question is who's hand-writing a bunch of functions that don't need their arguments' types in any way (for constraints or otherwise). There are very few functions that really apply to all types. It's possible that by allowing auto parameter types we encourage a sloppy style. Andrei
Aug 03 2013
I've brought this up on here awhile ago, and many people seemed to be against it. Which I don't agree with, since the ambiguities it creates are easily addressed (from a design perspective at least) and only exist so that C-style code is usable within D. It could work like: auto func(a, b) // auto func(A, B)(A a, B b) auto func(int a, b) // auto func(B)(int a, B b) auto func(int ?) // C-style: auto func(int)I like it!
Aug 02 2013
On Saturday, 3 August 2013 at 00:51:21 UTC, F i L wrote:I've brought this up on here awhile ago, and many people seemed to be against it. Which I don't agree with, since the ambiguities it creates are easily addressed (from a design perspective at least) and only exist so that C-style code is usable within D. It could work like: auto func(a, b) // auto func(A, B)(A a, B b) auto func(int a, b) // auto func(B)(int a, B b) auto func(int ?) // C-style: auto func(int)Regardless of the existing merits, that would be a (massive) breaking change, and as mentioned, it brings nothing we couldn't do before...Or... auto func(auto a, auto b) // like C++14 I mean honestly, who's hand-writing a bunch of functions with nameless params in real D code? Sure it's used for linking to C, which is semi-common, but I think having the much cleaner syntax available to "actual" D code makes more sense that not having it solely for linking-to-C-in-familiar-C-style reasons.Anytime I write the body of a function that doesn't use one of its args, I keep the arg name empty. This implicitly documents that the arg is unused. Many people do this in C++ too, since msvc will flag you for not doing it anyways. So your answer your question: "who's hand-writing a bunch of functions with nameless params in real D code": Lot's of people, including in Phobos.
Aug 03 2013
monarch_dodra wrote:Regardless of the existing merits, that would be a (massive) breaking change, and as mentioned, it brings nothing we couldn't do before...Sure, but not if you do it like my second example: auto func(auto a, auto b) // like C++14 That doesn't break anything, right?Anytime I write the body of a function that doesn't use one of its args, I keep the arg name empty. This implicitly documents that the arg is unused. Many people do this in C++ too, since msvc will flag you for not doing it anyways. So your answer your question: "who's hand-writing a bunch of functions with nameless params in real D code": Lot's of people, including in Phobos.Fair enough. However, using 'auto' like above would allow cleaner syntax without getting in your way I think.
Aug 03 2013
On Saturday, 3 August 2013 at 08:59:41 UTC, F i L wrote:monarch_dodra wrote:I'm not sure auto is the best choice of keywords, given potential clashes with auto ref: What if you want to pass a by ref? auto func(auto ref a, auto ref b) ? auto func(ref auto a, ref auto b) ? What if you want to pass them by *auto* ref? auto func(auto auto ref a, auto auto ref b) ? auto func(auto ref auto a, auto ref auto b) ? At this point, I'd really prefer just seeing classic template syntax...Regardless of the existing merits, that would be a (massive) breaking change, and as mentioned, it brings nothing we couldn't do before...Sure, but not if you do it like my second example: auto func(auto a, auto b) // like C++14 That doesn't break anything, right?
Aug 03 2013
monarch_dodra wrote:I'm not sure auto is the best choice of keywords, given potential clashes with auto ref: What if you want to pass a by ref? auto func(auto ref a, auto ref b) ? auto func(ref auto a, ref auto b) ? What if you want to pass them by *auto* ref? auto func(auto auto ref a, auto auto ref b) ? auto func(auto ref auto a, auto ref auto b) ? At this point, I'd really prefer just seeing classic template syntax...Okay, so I mostly agree with this. I guess adding this change would mostly likely require a breaking change elsewhere, and I can see the merits of not doing anything like that for good while. Thanks for being so convincing.
Aug 03 2013
On Friday, 2 August 2013 at 20:34:04 UTC, SteveGuo wrote:I'm not an expert on programming language, if I made a naive issue, just forgive me:p Can we declare a template function like this? auto Add(a, b) // Note a, b do not have type, that means a and b use template type { return a + b; } auto Sub(a, int b) // a uses template type, b is fixed to int { return a - b; } When we call the function, Add(1, 2); // deduced to be Add(int, int); Add(1.5, 2.3); // deduced to be Add(double, double); Add(1.5, "Hello"); // compiler error! Sub(1.5, 1); // deduced to be Add(double, int); Sub(1, 1.1); // deduced to be Add(int, int); compiler error, double can not converted to int automaticallyI prefer the current template syntax, it's nice to want to reduce the number of keywords/syntax, but generally to understand the code it's better for productivity to have something really explicit. When you read an old code or something written by someone else it's really important to see at the first sight what the code is intended to do. auto keyword hide too much how variables are used, is it ref? const?,...
Aug 03 2013