www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How about "auto" parameters?

reply Mehrdad <wfunction hotmail.com> writes:
I just thought of something:

The patterns

	auto foo1(T)(T arg) { /+ ... +/ }
	auto foo2(T...)(T args) { /+ ... +/ }

are very common.


Why not just supporting the syntax

	auto foo1(auto arg) { /+ ... +/ }
	auto foo2(auto args...) { /+ ... +/ }

to make things easier?

People can still say typeof(arg), typeof(args[0]), etc., just like
before, but it's a lot easier (and cooler!) to have a code with all
inferred types, rather than explicitly typed templates.

Any ideas?
Jun 02 2011
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-02 20:16, Mehrdad wrote:
 I just thought of something:
 
 The patterns
 
 	auto foo1(T)(T arg) { /+ ... +/ }
 	auto foo2(T...)(T args) { /+ ... +/ }
 
 are very common.
 
 
 Why not just supporting the syntax
 
 	auto foo1(auto arg) { /+ ... +/ }
 	auto foo2(auto args...) { /+ ... +/ }
 
 to make things easier?
 
 People can still say typeof(arg), typeof(args[0]), etc., just like
 before, but it's a lot easier (and cooler!) to have a code with all
 inferred types, rather than explicitly typed templates.
 
 Any ideas?

And what benefit would that really be? Using auto like that would have to be converted to a template anyway. It's not like a function can magically take any type for a parameter. The type must be known. Templates do that by generating a new version of the function for every new set of template parameters. auto couldn't do it without being turned into a template. And then you're just covering up the template syntax with some potentially confusing syntactic sugar. You wouldn't have any template constraints, which would mean that the error messages would be horrible. You _can't_ explicitly instantiate the template anymore if you need to, and it doesn't give you any more type inference than you do with templates. It's not even any less typing! In fact, it's exactly the same number of characters. All such a feature would do would be to hide the fact that templates were being used, and since you need to understand templates to use D properly - especially when dealing with Phobos - that doesn't help at all. I see no advantages with this idea and quite a few disadvantages. This proposal adds absolutely nothing. - Jonathan M Davis
Jun 02 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
== Quote from Jonathan M Davis (jmdavisProg gmx.com)'s article
 On 2011-06-02 20:16, Mehrdad wrote:
 I just thought of something:

 The patterns

 	auto foo1(T)(T arg) { /+ ... +/ }
 	auto foo2(T...)(T args) { /+ ... +/ }

 are very common.


 Why not just supporting the syntax

 	auto foo1(auto arg) { /+ ... +/ }
 	auto foo2(auto args...) { /+ ... +/ }

 to make things easier?

 People can still say typeof(arg), typeof(args[0]), etc., just


 before, but it's a lot easier (and cooler!) to have a code with


 inferred types, rather than explicitly typed templates.

 Any ideas?


 converted to a template anyway. It's not like a function can

 any type for a parameter. The type must be known. Templates do

 generating a new version of the function for every new set of

 parameters. auto couldn't do it without being turned into a

 you're just covering up the template syntax with some potentially

 syntactic sugar. You wouldn't have any template constraints, which

 that the error messages would be horrible. You _can't_ explicitly

 the template anymore if you need to, and it doesn't give you any

 inference than you do with templates. It's not even any less

 it's exactly the same number of characters. All such a feature

 be to hide the fact that templates were being used, and since you

 understand templates to use D properly - especially when dealing

 that doesn't help at all.
 I see no advantages with this idea and quite a few disadvantages.

 proposal adds absolutely nothing.
 - Jonathan M Davis

o__o way to bash the proposal, it actually convinced me lol...
Jun 02 2011
parent reply Matthew Ong <ongbp yahoo.com> writes:
On 6/3/2011 11:47 AM, Mehrdad wrote:
 == Quote from Jonathan M Davis (jmdavisProg gmx.com)'s article

 understand templates to use D properly - especially when dealing

 that doesn't help at all.
 I see no advantages with this idea and quite a few disadvantages.

 proposal adds absolutely nothing.
 - Jonathan M Davis

o__o way to bash the proposal, it actually convinced me lol...

 proposal adds absolutely nothing.


development. Welcome to D forum, where new idea are squashed and maybe re-discussed later. Look up my name as Matthew Ong. Avoid asking the same questions. http://www.digitalmars.com/d/ Notice: We *welcome feedback about the D compiler or language*, Not so true. Or out right should warn people as: Notice: Take it the way how we like it here, we are Not Burger K*ng. Please see: d.D.learn AND MAKE sure you read this d.D.NoSuchUselessSuggestion What do you think D forum people, at least new people here are for warn. Add a bit of humor into that. I do see a pattern here. Just joined D forum less than 4 weeks ago. Got a week off to clear my head. I think now I understand why D is still such a small community in the forum. -- Matthew Ong
Jun 03 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/3/11 10:19 AM, Matthew Ong wrote:
 On 6/3/2011 11:47 AM, Mehrdad wrote:
 == Quote from Jonathan M Davis (jmdavisProg gmx.com)'s article

 understand templates to use D properly - especially when dealing

 that doesn't help at all.
 I see no advantages with this idea and quite a few disadvantages.

 proposal adds absolutely nothing.
 - Jonathan M Davis

o__o way to bash the proposal, it actually convinced me lol...

>> proposal adds absolutely nothing. You will get this frequently. Especially if you identify with Java development. Welcome to D forum, where new idea are squashed and maybe re-discussed later. Look up my name as Matthew Ong. Avoid asking the same questions. http://www.digitalmars.com/d/ Notice: We *welcome feedback about the D compiler or language*, Not so true. Or out right should warn people as: Notice: Take it the way how we like it here, we are Not Burger K*ng. Please see: d.D.learn AND MAKE sure you read this d.D.NoSuchUselessSuggestion What do you think D forum people, at least new people here are for warn. Add a bit of humor into that. I do see a pattern here. Just joined D forum less than 4 weeks ago. Got a week off to clear my head. I think now I understand why D is still such a small community in the forum.

I understand how you find that an attractive conclusion to reach, but probably a more rational hypothesis is that some of your proposals have been of poor quality. That doesn't reflect poorly on your abilities, it just suggests that you have not yet accumulated sufficient expertise with D. As an example, look at the activity of a current poster who proposed very strongly a change in a way the intervals are handled. It was arguably a very poor proposal for D, and people did their best to explain why. That poster was outwitted by competent people with clear and solid arguments. Yet that poster's way to solve that cognitive dissonance - the low road if you ask me - was to conclude that the value of his proposal is high in spite of all logic and reasoning, and that everyone else is wrong. I suggest you don't fall for the same pattern, though clearly I understand how attractive it is. It slows down learning. Andrei
Jun 03 2011
parent reply Ary Manzana <ary esperanto.org.ar> writes:
On 6/3/11 11:25 PM, Andrei Alexandrescu wrote:
 On 6/3/11 10:19 AM, Matthew Ong wrote:
 On 6/3/2011 11:47 AM, Mehrdad wrote:
 == Quote from Jonathan M Davis (jmdavisProg gmx.com)'s article

 understand templates to use D properly - especially when dealing

 that doesn't help at all.
 I see no advantages with this idea and quite a few disadvantages.

 proposal adds absolutely nothing.
 - Jonathan M Davis

o__o way to bash the proposal, it actually convinced me lol...

 proposal adds absolutely nothing.


development. Welcome to D forum, where new idea are squashed and maybe re-discussed later. Look up my name as Matthew Ong. Avoid asking the same questions. http://www.digitalmars.com/d/ Notice: We *welcome feedback about the D compiler or language*, Not so true. Or out right should warn people as: Notice: Take it the way how we like it here, we are Not Burger K*ng. Please see: d.D.learn AND MAKE sure you read this d.D.NoSuchUselessSuggestion What do you think D forum people, at least new people here are for warn. Add a bit of humor into that. I do see a pattern here. Just joined D forum less than 4 weeks ago. Got a week off to clear my head. I think now I understand why D is still such a small community in the forum.

I understand how you find that an attractive conclusion to reach, but probably a more rational hypothesis is that some of your proposals have been of poor quality. That doesn't reflect poorly on your abilities, it just suggests that you have not yet accumulated sufficient expertise with D. As an example, look at the activity of a current poster who proposed very strongly a change in a way the intervals are handled. It was arguably a very poor proposal for D, and people did their best to explain why. That poster was outwitted by competent people with clear and solid arguments. Yet that poster's way to solve that cognitive dissonance - the low road if you ask me - was to conclude that the value of his proposal is high in spite of all logic and reasoning, and that everyone else is wrong. I suggest you don't fall for the same pattern, though clearly I understand how attractive it is. It slows down learning. Andrei

Well, in Ruby every parameter type is auto. And it works pretty well. :-) When you invoke a method and something goes wrong, like the auto parameter doesn't have a method, it gives a sensible error message. So: void foo(auto parameter) { return parameter * 2; } could just be the same as void foo(T)(T parameter) { return parameter * 2; } just with a nicer syntax (but I understand it doesn't add much). I think a reply like: "this is the same as a template" is better than "your proposals are of poor quality". It doesn't give a nice look to D, specially coming from one of its main leaders.
Jun 07 2011
next sibling parent reply foobar <foo bar.com> writes:
Ary Manzana Wrote:

 On 6/3/11 11:25 PM, Andrei Alexandrescu wrote:
 On 6/3/11 10:19 AM, Matthew Ong wrote:
 On 6/3/2011 11:47 AM, Mehrdad wrote:
 == Quote from Jonathan M Davis (jmdavisProg gmx.com)'s article

 understand templates to use D properly - especially when dealing

 that doesn't help at all.
 I see no advantages with this idea and quite a few disadvantages.

 proposal adds absolutely nothing.
 - Jonathan M Davis

o__o way to bash the proposal, it actually convinced me lol...

 proposal adds absolutely nothing.


development. Welcome to D forum, where new idea are squashed and maybe re-discussed later. Look up my name as Matthew Ong. Avoid asking the same questions. http://www.digitalmars.com/d/ Notice: We *welcome feedback about the D compiler or language*, Not so true. Or out right should warn people as: Notice: Take it the way how we like it here, we are Not Burger K*ng. Please see: d.D.learn AND MAKE sure you read this d.D.NoSuchUselessSuggestion What do you think D forum people, at least new people here are for warn. Add a bit of humor into that. I do see a pattern here. Just joined D forum less than 4 weeks ago. Got a week off to clear my head. I think now I understand why D is still such a small community in the forum.

I understand how you find that an attractive conclusion to reach, but probably a more rational hypothesis is that some of your proposals have been of poor quality. That doesn't reflect poorly on your abilities, it just suggests that you have not yet accumulated sufficient expertise with D. As an example, look at the activity of a current poster who proposed very strongly a change in a way the intervals are handled. It was arguably a very poor proposal for D, and people did their best to explain why. That poster was outwitted by competent people with clear and solid arguments. Yet that poster's way to solve that cognitive dissonance - the low road if you ask me - was to conclude that the value of his proposal is high in spite of all logic and reasoning, and that everyone else is wrong. I suggest you don't fall for the same pattern, though clearly I understand how attractive it is. It slows down learning. Andrei

Well, in Ruby every parameter type is auto. And it works pretty well. :-) When you invoke a method and something goes wrong, like the auto parameter doesn't have a method, it gives a sensible error message. So: void foo(auto parameter) { return parameter * 2; } could just be the same as void foo(T)(T parameter) { return parameter * 2; } just with a nicer syntax (but I understand it doesn't add much). I think a reply like: "this is the same as a template" is better than "your proposals are of poor quality". It doesn't give a nice look to D, specially coming from one of its main leaders.

I agree with Ary above and would also like to add that in the ML family of languages all the variables are also default auto typed: E.g.: fun add a b = a + b 'add' would have the type ('a, 'a) -> 'a and the type inference engine will also infer that 'a must provide the + operator. I feel that this is more natural than having a dedicated function template syntax. Better yet, instead of auto parameters, just make parameter types optional (as in ML) and let the compiler generate the template. foo(a, b) { return a + b; } // will be lowered to: T foo(T) (T a, T b) { return a + b; } Types are already inferred for delegate literals so why not extend this to regular functions too?
Jun 07 2011
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Jun 7, 11 20:11, foobar wrote:
 I agree with Ary above and would also like to add that in the ML family of
languages all the variables are also default auto typed:
 E.g.:
 fun add a b = a + b

 'add' would have the type ('a, 'a) ->  'a and the type inference engine will
also infer that 'a must provide the + operator.
 I feel that this is more natural than having a dedicated function template
syntax.
 Better yet, instead of auto parameters, just make parameter types optional (as
in ML) and let the compiler generate the template.

I don't think HM type inference (ML, Haskell) support implicit cast, i.e. you can't write { int a; double b; a + b; } anymore.
 foo(a, b) { return a + b; } // will be lowered to:
 T foo(T) (T a, T b) { return a + b; }

 Types are already inferred for delegate literals so why not extend this to
regular functions too?

There is no type inference in delegate literal as powerful as HM, it's just "I call this function with parameters 'int' and 'float', so instantiate a new function with 'int' and 'float'." Also, type inference only work in template parameters struct F(alias f) { ... } alias F!((a,b){return a+b;}) G; but not regular delegate literals auto c = (a,b){return a+b;}; /* Error: undefined identifier a, b */
Jun 07 2011
parent reply foobar <foo bar.com> writes:
KennyTM~ Wrote:

 On Jun 7, 11 20:11, foobar wrote:
 I agree with Ary above and would also like to add that in the ML family of
languages all the variables are also default auto typed:
 E.g.:
 fun add a b = a + b

 'add' would have the type ('a, 'a) ->  'a and the type inference engine will
also infer that 'a must provide the + operator.
 I feel that this is more natural than having a dedicated function template
syntax.
 Better yet, instead of auto parameters, just make parameter types optional (as
in ML) and let the compiler generate the template.

I don't think HM type inference (ML, Haskell) support implicit cast, i.e. you can't write { int a; double b; a + b; } anymore.

As I've answered to Andrei, this is a good thing(tm) - it's a feature. I don't know if it has anything to do with the HM algorithm itself, but it is one of ML core principals. ML is strictly typed unlike C (glorified assembly).
 
 foo(a, b) { return a + b; } // will be lowered to:
 T foo(T) (T a, T b) { return a + b; }

 Types are already inferred for delegate literals so why not extend this to
regular functions too?

There is no type inference in delegate literal as powerful as HM, it's just "I call this function with parameters 'int' and 'float', so instantiate a new function with 'int' and 'float'." Also, type inference only work in template parameters struct F(alias f) { ... } alias F!((a,b){return a+b;}) G; but not regular delegate literals auto c = (a,b){return a+b;}; /* Error: undefined identifier a, b */

Jun 07 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
foobar wrote:
 KennyTM~ Wrote:

 On Jun 7, 11 20:11, foobar wrote:
 I agree with Ary above and would also like to add that in the ML family of



 E.g.:
 fun add a b = a + b

 'add' would have the type ('a, 'a) ->  'a and the type inference engine will



 I feel that this is more natural than having a dedicated function template



 Better yet, instead of auto parameters, just make parameter types optional




I don't think HM type inference (ML, Haskell) support implicit cast, i.e. you can't write { int a; double b; a + b; } anymore.

As I've answered to Andrei, this is a good thing(tm) - it's a feature. I don't know if it has anything to do with the HM algorithm itself, but it is

 [snip.]

Assembly does not have implicit conversions ;). I wonder how much code would get broken if D changed to strict typing. I seldom rely on implicit casts. Timon
Jun 07 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/7/11 7:11 AM, foobar wrote:
 I agree with Ary above and would also like to add that in the ML family of
languages all the variables are also default auto typed:
 E.g.:
 fun add a b = a + b

 'add' would have the type ('a, 'a) ->  'a and the type inference engine will
also infer that 'a must provide the + operator.
 I feel that this is more natural than having a dedicated function template
syntax.

I agree it would be nice to further simplify generic function syntax. One problem with the example above is that the type deduction didn't go all that well - it forces both parameter types to be the same so it won't work with adding values of different types (different widths, mixed floating point and integrals, user-defined +). In a language without overloading, like ML, things are a fair amount easier.
 Better yet, instead of auto parameters, just make parameter types optional (as
in ML) and let the compiler generate the template.

 foo(a, b) { return a + b; } // will be lowered to:
 T foo(T) (T a, T b) { return a + b; }

 Types are already inferred for delegate literals so why not extend this to
regular functions too?

There are multiple issues. One is we don't have Hindley-Milner polymorphism. The D compiler doesn't really "infer" types as "propagate" them. Another is, such inference would make separate compilation difficult. Andrei
Jun 07 2011
next sibling parent reply foobar <foo bar.com> writes:
Andrei Alexandrescu Wrote:

 On 6/7/11 7:11 AM, foobar wrote:
 I agree with Ary above and would also like to add that in the ML family of
languages all the variables are also default auto typed:
 E.g.:
 fun add a b = a + b

 'add' would have the type ('a, 'a) ->  'a and the type inference engine will
also infer that 'a must provide the + operator.
 I feel that this is more natural than having a dedicated function template
syntax.

I agree it would be nice to further simplify generic function syntax. One problem with the example above is that the type deduction didn't go all that well - it forces both parameter types to be the same so it won't work with adding values of different types (different widths, mixed floating point and integrals, user-defined +). In a language without overloading, like ML, things are a fair amount easier.

ML is strictly typed unlike C-like languages. This is a *good* thing and is a feature. While C's implicit casts are a horrible hole in the language. Also ML has only two types: integers and floating point. There is no short vs long problems. Yes, both arguments will have the same type but this is the correct default. When adding a floating point and an integral the user should be required to specify what kind of operation is being made, either the double is converted to an integral (how? floor, round, etc? ) or the integral is converted to a floating point which can cause a loss of precision. Although overloading complicates things it doesn't mean it's impossible. ML is explicit but only in the correct places. C-like languages have shortcuts but those are in the wrong places where it hurts and it's verbose in other places. I prefer to let the compiler infer types for me but require me to be explicit about coercion which is type safe vs. the reverse which is both more verbose and less safe.
 Better yet, instead of auto parameters, just make parameter types optional (as
in ML) and let the compiler generate the template.

 foo(a, b) { return a + b; } // will be lowered to:
 T foo(T) (T a, T b) { return a + b; }

 Types are already inferred for delegate literals so why not extend this to
regular functions too?

There are multiple issues. One is we don't have Hindley-Milner polymorphism. The D compiler doesn't really "infer" types as "propagate" them. Another is, such inference would make separate compilation difficult. Andrei

We don't Hindley-Miler _yet_. I can hope, can't I? Again, difficult != impossible. AFAIK it is working in Nemerle, isn't it?
Jun 07 2011
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
Jonathan M Davis wrote:
 ...
 And while D might arguably allow too many implicit conversions, it allows
 fewer than C or C++. I actually would expect that bugs due to implicit
 conversions would be fairly rare in D. And requiring more conversions to be
 explicit might actually make things worse, because it would become more
 frequently necessary to use casts, which tend to hide various types of bugs.
 So, while it might be better to require casting in a few more places than D
 currently does, on the whole it works quite well. And certainly expecting a
 major paradigm shift at this point is unrealistic. Minor improvements may be
 added to the language, and perhaps major backwards-compatible features may be
 added, but for the most part, D is currently in the mode of stabilizing and
 completing the implementation of its existing feature set. It's _far_ too late
 in the game to introduce something like Hindley-Milner type inference,
 regardless of whether it would have been a good idea in the beginning (and
 honestly, given D's C and C++ roots, I very much doubt that it ever would have
 been a good idea to have Hindley-Milner type inference in it - that would have
 made for a _very_ different sort of language, which definitely wouldn't be D).

 - Jonathan M Davis

Widening implicit casts are very convenient. What I think is annoying is that D allows implicit conversions that are narrowing. Eg: int -> float long -> double real -> double double -> float Especially questionable is the real -> double -> float chain. This and implicitly casting an integer value to a floating point type whose mantissa is too small should imho be disallowed. BTW: You can have safe 'casts'. I think std.conv.to does/will allow only type conversions that are safe. Timon
Jun 07 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/7/11 12:20 PM, Timon Gehr wrote:
 Jonathan M Davis wrote:
 ...
 And while D might arguably allow too many implicit conversions, it allows
 fewer than C or C++. I actually would expect that bugs due to implicit
 conversions would be fairly rare in D. And requiring more conversions to be
 explicit might actually make things worse, because it would become more
 frequently necessary to use casts, which tend to hide various types of bugs.
 So, while it might be better to require casting in a few more places than D
 currently does, on the whole it works quite well. And certainly expecting a
 major paradigm shift at this point is unrealistic. Minor improvements may be
 added to the language, and perhaps major backwards-compatible features may be
 added, but for the most part, D is currently in the mode of stabilizing and
 completing the implementation of its existing feature set. It's _far_ too late
 in the game to introduce something like Hindley-Milner type inference,
 regardless of whether it would have been a good idea in the beginning (and
 honestly, given D's C and C++ roots, I very much doubt that it ever would have
 been a good idea to have Hindley-Milner type inference in it - that would have
 made for a _very_ different sort of language, which definitely wouldn't be D).

 - Jonathan M Davis

Widening implicit casts are very convenient. What I think is annoying is that D allows implicit conversions that are narrowing. Eg: int -> float long -> double

I'm a bit weary about these too.
 real ->  double
 double ->  float

 Especially questionable is the real ->  double ->  float chain. This and
implicitly
 casting an integer value to a floating point type whose mantissa is too small
 should imho be disallowed.

I used to think the same but Walter convinced me otherwise. Automatic floating point conversions allow the compiler and libraries to store intermediate results at the optimal precision without impacting user code.
 BTW: You can have safe 'casts'. I think std.conv.to does/will allow only type
 conversions that are safe.

Currently to!T for implicitly-convertible types does not get in the way. Andrei
Jun 07 2011
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/7/2011 9:01 AM, foobar wrote:
 Also ML has only two types: integers and floating point.

That changes everything. C has 11 integer types and 3 floating point types, which makes it ugly (and surprisingly buggy) to be forced to explicitly cast when doing mixed type expressions.
Jun 07 2011
parent reply foobar <foo bar.com> writes:
Walter Bright Wrote:

 On 6/7/2011 9:01 AM, foobar wrote:
 Also ML has only two types: integers and floating point.

That changes everything. C has 11 integer types and 3 floating point types, which makes it ugly (and surprisingly buggy) to be forced to explicitly cast when doing mixed type expressions.

Personally I think that all those types are redundant but regardless I don't think that int -> long is the same as int -> double. you can leave the size promotion rules untouched (implicit) since it's equivalent to upcasting. integral -> floating can however cause loss of precision and hence should be IMO explicit. E.g. in pseudo D: auto add (a, b) { return a + b; } int a = ...; long b = ...; auto c = add (a, b); // type for both parameters and return type is long double d = ...; auto e = add (a, d); // IMO, compile time error
Jun 07 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
Andrei Alexandrescu wrote:
 On 6/7/11 12:20 PM, Timon Gehr wrote:
 Jonathan M Davis wrote:
 ...
 And while D might arguably allow too many implicit conversions, it allows
 fewer than C or C++. I actually would expect that bugs due to implicit
 conversions would be fairly rare in D. And requiring more conversions to be
 explicit might actually make things worse, because it would become more
 frequently necessary to use casts, which tend to hide various types of bugs.
 So, while it might be better to require casting in a few more places than D
 currently does, on the whole it works quite well. And certainly expecting a
 major paradigm shift at this point is unrealistic. Minor improvements may be
 added to the language, and perhaps major backwards-compatible features may be
 added, but for the most part, D is currently in the mode of stabilizing and
 completing the implementation of its existing feature set. It's _far_ too late
 in the game to introduce something like Hindley-Milner type inference,
 regardless of whether it would have been a good idea in the beginning (and
 honestly, given D's C and C++ roots, I very much doubt that it ever would have
 been a good idea to have Hindley-Milner type inference in it - that would have
 made for a _very_ different sort of language, which definitely wouldn't be D).

 - Jonathan M Davis

Widening implicit casts are very convenient. What I think is annoying is that D allows implicit conversions that are narrowing. Eg: int -> float long -> double

I'm a bit weary about these too.
 real ->  double
 double ->  float

 Especially questionable is the real ->  double ->  float chain. This and
implicitly
 casting an integer value to a floating point type whose mantissa is too small
 should imho be disallowed.

I used to think the same but Walter convinced me otherwise. Automatic floating point conversions allow the compiler and libraries to store intermediate results at the optimal precision without impacting user code. [snip.]

Hm ok. But compiler: The compiler could just as well insert explicit casts (I think thats how it deals with implicit casts during semantic analysis anyways.), or am I missing something? Libraries: True, the libraries internal precision does not impact user code. But if the user stores intermediate results in a type that is too coarse, user code might inadvertently impact library code in a crippling way. This then reflects badly on user code. (float a=LibraryFunctionTakingAndReturningReal(123.2); float c=Ditto(a); // now c is less precise than the library could offer) Timon
Jun 07 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei:

 There are multiple issues. One is we don't have Hindley-Milner 
 polymorphism. The D compiler doesn't really "infer" types as "propagate" 
 them.

- Even Scala, that has a very powerful type system (far more complex than D) doesn't use H-M, I think because they prefer type inference inside methods, but explicit specification of interfaces. - H-M is good but it's not perfect. Haskell is fighting since years against the limitations imposed by H-M. There are many extensions to Haskell, but they often overflow the inferencing capabilities of H-M. - I am not expert but I think H-M doesn't work well with C++-style polymorphism. Haskell use type classes. - My experience with Haskell is limited still, but while I like its type inference, I generally prefer to give some kind of types to functions. Even in Haskell code written by expert people I see several explicit type signatures. In the end I don't feel a need for full program type inferencing in D. - I don't remember what ATS language uses, if it performs whole program type inference. I doubt it.
 Another is, such inference would make separate compilation difficult.

I think there are ways to solve this problem, introducing more powerful module interfaces. But such modules are not easy to use (see ML). ------------------------------- foobar:
 We don't Hindley-Miler _yet_. I can hope, can't I? 

I don't think you will see H-M in D, I think it goes against D templates. Bye, bearophile
Jun 07 2011
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-06-07 09:01, foobar wrote:
 Andrei Alexandrescu Wrote:
 On 6/7/11 7:11 AM, foobar wrote:
 I agree with Ary above and would also like to add that in the ML family
 of languages all the variables are also default auto typed: E.g.:
 fun add a b = a + b
 
 'add' would have the type ('a, 'a) -> 'a and the type inference engine
 will also infer that 'a must provide the + operator. I feel that this
 is more natural than having a dedicated function template syntax.

I agree it would be nice to further simplify generic function syntax. One problem with the example above is that the type deduction didn't go all that well - it forces both parameter types to be the same so it won't work with adding values of different types (different widths, mixed floating point and integrals, user-defined +). In a language without overloading, like ML, things are a fair amount easier.

ML is strictly typed unlike C-like languages. This is a *good* thing and is a feature. While C's implicit casts are a horrible hole in the language. Also ML has only two types: integers and floating point. There is no short vs long problems. Yes, both arguments will have the same type but this is the correct default. When adding a floating point and an integral the user should be required to specify what kind of operation is being made, either the double is converted to an integral (how? floor, round, etc? ) or the integral is converted to a floating point which can cause a loss of precision. Although overloading complicates things it doesn't mean it's impossible. ML is explicit but only in the correct places. C-like languages have shortcuts but those are in the wrong places where it hurts and it's verbose in other places. I prefer to let the compiler infer types for me but require me to be explicit about coercion which is type safe vs. the reverse which is both more verbose and less safe.
 Better yet, instead of auto parameters, just make parameter types
 optional (as in ML) and let the compiler generate the template.
 
 foo(a, b) { return a + b; } // will be lowered to:
 T foo(T) (T a, T b) { return a + b; }
 
 Types are already inferred for delegate literals so why not extend this
 to regular functions too?

There are multiple issues. One is we don't have Hindley-Milner polymorphism. The D compiler doesn't really "infer" types as "propagate" them. Another is, such inference would make separate compilation difficult. Andrei

We don't Hindley-Miler _yet_. I can hope, can't I? Again, difficult != impossible. AFAIK it is working in Nemerle, isn't it?

I don't think that it generally makes sense to _add_ Hindley-Milner type inference to a language. That's the sort of design decision you make when you initially create the language. It has _huge_ repercussions on how the language works. And D didn't go that route. That sort of choice is more typical of a functional language. And while D might arguably allow too many implicit conversions, it allows fewer than C or C++. I actually would expect that bugs due to implicit conversions would be fairly rare in D. And requiring more conversions to be explicit might actually make things worse, because it would become more frequently necessary to use casts, which tend to hide various types of bugs. So, while it might be better to require casting in a few more places than D currently does, on the whole it works quite well. And certainly expecting a major paradigm shift at this point is unrealistic. Minor improvements may be added to the language, and perhaps major backwards-compatible features may be added, but for the most part, D is currently in the mode of stabilizing and completing the implementation of its existing feature set. It's _far_ too late in the game to introduce something like Hindley-Milner type inference, regardless of whether it would have been a good idea in the beginning (and honestly, given D's C and C++ roots, I very much doubt that it ever would have been a good idea to have Hindley-Milner type inference in it - that would have made for a _very_ different sort of language, which definitely wouldn't be D). - Jonathan M Davis
Jun 07 2011
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/7/2011 5:11 AM, foobar wrote:
 Types are already inferred for delegate literals so why not extend this to
regular functions too?

Because of this: int foo(T1 a, T2) { ... do something with a ... } which is a common idiom for the second parameter existing but not being used in the function body. In other words, existing practice holds that identifier T2 is presumed to be a type name, not a parameter name.
Jun 07 2011
prev sibling parent Mehrdad <wfunction hotmail.com> writes:
== Quote from Andrej Mitrovic (andrej.mitrovich gmail.com)'s article
 ...
 So now I have to force my code to use std.algorithm by importing via:
 import std.algorithm : min, max;
 or alternatively:
 import std.algorithm;
 alias std.algorithm.min min;
 alias std.algorithm.max max;
 Pain in the ass.

You can say that again... I have the same issue with lots of other things being declared everywhere, like read, write, Stream/File (<-- very annoying, since they're both in std.file and std.stream), indexOf, toString, and lots of other things I can't remember right now. Also, I'm not sure if this bug has been fixed in DMD 2.53, but in older versions if you said something like: module foo1; import bar: baz; and then in another file said: module foo2; import foo1; import bar; and then used baz() in foo2, it would detect a collision, when in fact they were the same thing. It wouldn't happen if baz() wasn't explicitly declared. It was really annoying to track down.
Jun 07 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/7/11 5:35 AM, Ary Manzana wrote:
 Well, in Ruby every parameter type is auto. And it works pretty well. :-)

 When you invoke a method and something goes wrong, like the auto
 parameter doesn't have a method, it gives a sensible error message.

It does, just at run time. The way dynamic languages and static languages set up computation is very different and as such difficult to compare something as core as function call resolution as equals for equals.
 So:

 void foo(auto parameter) {
 return parameter * 2;
 }

 could just be the same as

 void foo(T)(T parameter) {
 return parameter * 2;
 }

 just with a nicer syntax (but I understand it doesn't add much).

The counterpoint is that you seldom want to write foo() as written above. You want to clarify what family of types it is intended for.
 I think a reply like: "this is the same as a template" is better than
 "your proposals are of poor quality". It doesn't give a nice look to D,
 specially coming from one of its main leaders.

This criticism is inappropriate, but I'm sure it comes from a confusion in reading the thread. I made clear that the proposal you mention is sensible (although it has equally sensible counterarguments, which I also mentioned). My comment was referring to other proposals following an insistence of a poster that it's narrow-mindedness of the community, not the quality of his proposals, that renders them rejected. Andrei
Jun 07 2011
next sibling parent reply Ary Manzana <ary esperanto.org.ar> writes:
On 6/7/11 9:50 PM, Andrei Alexandrescu wrote:
 On 6/7/11 5:35 AM, Ary Manzana wrote:
 Well, in Ruby every parameter type is auto. And it works pretty well. :-)

 When you invoke a method and something goes wrong, like the auto
 parameter doesn't have a method, it gives a sensible error message.

It does, just at run time. The way dynamic languages and static languages set up computation is very different and as such difficult to compare something as core as function call resolution as equals for equals.
 So:

 void foo(auto parameter) {
 return parameter * 2;
 }

 could just be the same as

 void foo(T)(T parameter) {
 return parameter * 2;
 }

 just with a nicer syntax (but I understand it doesn't add much).

The counterpoint is that you seldom want to write foo() as written above. You want to clarify what family of types it is intended for.

Why? Note that in Ruby you *NEVER* say the family of types, and that is a huge bennefit. Good tests and good documentation are better than restricting the time. Look at this: ====================================================== import std.stdio; // This is Ruby :-) auto foo(T)(T param) { return param * 2; } class MyClass { int value; this(int value) { this.value = value; } int opBinary(string op)(int other) if (op == "*") { return value * other; } } int main() { auto x = foo(3); auto y = foo(6L); auto z = foo(new MyClass(10)); writefln("%s", x); writefln("%s", y); writefln("%s", z); return 0; } ====================================================== This function: auto foo(T)(T param) { return param * 2; } Could be just as well: auto foo(auto param) { return param * 2; } Yes, in Ruby it is checked on runtime, on D it is checked on compile-time. What's cool about "auto param"? I have written a function once and it will work for everything that can be multiplied and it will be compiled efficiently for every type that I pass that complies to the function. Why you find it useless? Why do I have to restrict the type? I can restrict the type just for the operations being performed on it and then my function is open to any param that accepts those operations. I know, I know. This is the same as just a template, but with a different syntax. I just don't understand why you think you will almost always would like to restrict the type you pass to the function. If you do, you limit your code. If you don't, you open your code and you have to write less code.
Jun 08 2011
parent reply Ary Manzana <ary esperanto.org.ar> writes:
On 6/8/11 11:56 PM, Jonathan M Davis wrote:
 On 2011-06-08 02:20, Ary Manzana wrote:
 On 6/7/11 9:50 PM, Andrei Alexandrescu wrote:
 On 6/7/11 5:35 AM, Ary Manzana wrote:
 Well, in Ruby every parameter type is auto. And it works pretty well.
 :-)

 When you invoke a method and something goes wrong, like the auto
 parameter doesn't have a method, it gives a sensible error message.

It does, just at run time. The way dynamic languages and static languages set up computation is very different and as such difficult to compare something as core as function call resolution as equals for equals.
 So:

 void foo(auto parameter) {
 return parameter * 2;
 }

 could just be the same as

 void foo(T)(T parameter) {
 return parameter * 2;
 }

 just with a nicer syntax (but I understand it doesn't add much).

The counterpoint is that you seldom want to write foo() as written above. You want to clarify what family of types it is intended for.

Why? Note that in Ruby you *NEVER* say the family of types, and that is a huge bennefit. Good tests and good documentation are better than restricting the time. Look at this: ====================================================== import std.stdio; // This is Ruby :-) auto foo(T)(T param) { return param * 2; } class MyClass { int value; this(int value) { this.value = value; } int opBinary(string op)(int other) if (op == "*") { return value * other; } } int main() { auto x = foo(3); auto y = foo(6L); auto z = foo(new MyClass(10)); writefln("%s", x); writefln("%s", y); writefln("%s", z); return 0; } ====================================================== This function: auto foo(T)(T param) { return param * 2; } Could be just as well: auto foo(auto param) { return param * 2; } Yes, in Ruby it is checked on runtime, on D it is checked on compile-time. What's cool about "auto param"? I have written a function once and it will work for everything that can be multiplied and it will be compiled efficiently for every type that I pass that complies to the function. Why you find it useless? Why do I have to restrict the type? I can restrict the type just for the operations being performed on it and then my function is open to any param that accepts those operations. I know, I know. This is the same as just a template, but with a different syntax. I just don't understand why you think you will almost always would like to restrict the type you pass to the function. If you do, you limit your code. If you don't, you open your code and you have to write less code.

You want to restrict it for several reasons, including the fact that if you don't, you get hideous error messages when you use a type with a template that it doesn't work with.

That's not the reason I shouldn't be using it. The compiler should give precise error messages. For instance, first I wrote this code: void foo(T)(T param) { return param * 2; } I got these messages back: main.d(4): Error: * has no effect in expression (param * 2) main.d(20): Error: template instance main.foo!(int) error instantiating main.d(20): Error: variable main.main.x voids have no value main.d(20): Error: expression foo(3) is void and has no value Umm... can't it just tell me "foo's return type is void and you are trying to return an int"?
Jun 08 2011
parent reply Ary Manzana <ary esperanto.org.ar> writes:
On 6/9/11 9:56 AM, Jonathan M Davis wrote:

 I don't think that there's any question that template error messages could be
 improved, and they likely will be, but by their very nature, reporting
 template-related errors seems to be a difficult task to adequately solve. It's
 one of the things that many people complain about with C++. Template
 constraints improve the situation considerably.

I don't think the problem is with templates. If I try to compile this: === void foo(int param) { return param * 2; } void main() { foo(3); } === it says: main.d(2): Error: * has no effect in expression (param * 2) WTF? Don't make me think. I just really want to know that I'm returning from a void function and I can't do that. Let's assign foo(3) to something: === void foo(int param) { return param * 2; } void main() { auto x = foo(3); } === It says: main.d(2): Error: * has no effect in expression (param * 2) main.d(6): Error: variable main.main.x voids have no value main.d(6): Error: expression foo(3) is void and has no value Really? Voids have no value? That's good to know, I didn't know that voids have no value. Mmm... those are messages to be read by the compiler, not by the user. The compiler is expecting something that's not void and it is getting a void thing. The message it generates is "Voids has no value". The problem are not templates or templates messages. The problem is that the very basic compiler error messages are targeted at the compiler, not the developer. And then this: === void main() { const x = 1; x = 3; } === main.d(3): Error: variable main.main.x cannot modify const What do you mean when you say that the variable x cannot modify const? Wait, I desguise myself as Tarzan and now I understand. It should be "Error: trying to modify const variable main.main.x". There is an excellent book called "Don't make me think". When I see "variable main.main.x cannot modify const" I have to think a little to understand that that means "variable main.main.x is const and cannot be modified". Don't make me think. :-)
Jun 09 2011
parent KennyTM~ <kennytm gmail.com> writes:
On Jun 9, 11 15:54, Jonathan M Davis wrote:
 Template error messages_do_  tend to be hideous. But that doesn't mean that
 normal errors are the best either. And as I said, templates often end up
 reporting exactly the same errors that you'd get if you wrote the code by
 hand, it's just that the errors are then in the template and generally harder
 to understand, because there's a good chance that it's not the code that you
 write.

 But regardless, none of these error messages are intended to be "read by the
 compiler." They're all intended to be read by humans. It's just that you don't
 find the choice of wording to be particularly understandable. However,
 everything that it's saying is correct. If you find particular error messages
 to be bad - particularly if you can think of better alternatives - then create
 enhancement requests for them in bugzilla. Then perhaps we'll get better error
 messages. But remember that the compiler doesn't know what you're trying to
 do. It only knows what you told it to do, so its messages tend to be targetted
 at telling you that what you're doing isn't working rather than telling you
 what you should be doing instead. So, error messages are often not that great
 simply because the compiler is not a mind-reader. Still, if you have
 suggestions for improvements to error messages, please submit them to bugzilla
 so that the error messages can be improved.

 - Jonathan M Davis

Actually, this is an old bug. http://d.puremagic.com/issues/show_bug.cgi?id=3922
Jun 09 2011
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-06-08 02:20, Ary Manzana wrote:
 On 6/7/11 9:50 PM, Andrei Alexandrescu wrote:
 On 6/7/11 5:35 AM, Ary Manzana wrote:
 Well, in Ruby every parameter type is auto. And it works pretty well.
 :-)
 
 When you invoke a method and something goes wrong, like the auto
 parameter doesn't have a method, it gives a sensible error message.

It does, just at run time. The way dynamic languages and static languages set up computation is very different and as such difficult to compare something as core as function call resolution as equals for equals.
 So:
 
 void foo(auto parameter) {
 return parameter * 2;
 }
 
 could just be the same as
 
 void foo(T)(T parameter) {
 return parameter * 2;
 }
 
 just with a nicer syntax (but I understand it doesn't add much).

The counterpoint is that you seldom want to write foo() as written above. You want to clarify what family of types it is intended for.

Why? Note that in Ruby you *NEVER* say the family of types, and that is a huge bennefit. Good tests and good documentation are better than restricting the time. Look at this: ====================================================== import std.stdio; // This is Ruby :-) auto foo(T)(T param) { return param * 2; } class MyClass { int value; this(int value) { this.value = value; } int opBinary(string op)(int other) if (op == "*") { return value * other; } } int main() { auto x = foo(3); auto y = foo(6L); auto z = foo(new MyClass(10)); writefln("%s", x); writefln("%s", y); writefln("%s", z); return 0; } ====================================================== This function: auto foo(T)(T param) { return param * 2; } Could be just as well: auto foo(auto param) { return param * 2; } Yes, in Ruby it is checked on runtime, on D it is checked on compile-time. What's cool about "auto param"? I have written a function once and it will work for everything that can be multiplied and it will be compiled efficiently for every type that I pass that complies to the function. Why you find it useless? Why do I have to restrict the type? I can restrict the type just for the operations being performed on it and then my function is open to any param that accepts those operations. I know, I know. This is the same as just a template, but with a different syntax. I just don't understand why you think you will almost always would like to restrict the type you pass to the function. If you do, you limit your code. If you don't, you open your code and you have to write less code.

You want to restrict it for several reasons, including the fact that if you don't, you get hideous error messages when you use a type with a template that it doesn't work with (templates in C++ are famous for these). The fact of the matter is that any type which a template is compiled with needs to fulfill a particular set of requirements to work with that template, and you need a way to express that. Letting the compiler choke on it just doesn't cut it. That's one of the reasons that template constraints are so great. That's why the C++ guys wanted concepts. Another major reason though is that you sometimes need control over what types can be used with a particular function or template. Just because a type happens to have all of the operations that the function requires does not mean that it's going to work with it. You frequently either need to restrict a template to a paricular set of types or create specializations for a template where a particular type so that it works correctly with that type or is better optimized for that type (even if it would have worked with the original template). A classic example of this in Phobos is strings. Functions which operate on arrays must frequently special-case them in order to work correctly. They would compile just fine with the basic template, but the resulting code would be wrong. So, the template gets specializations for strings. Many range-based functions work fine with strings, but sometimes it's just more efficient to special-case them. You _can_ create templates with no template constraints if you want to, but it's generally ill-advised and in a number of cases will lead to incorrect code. And once you need template constraints, then the proposed auto syntax doesn't work anymore. - Jonathan M Davis
Jun 08 2011
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/3/2011 8:19 AM, Matthew Ong wrote:
 Welcome to D forum, where new idea are squashed and maybe re-discussed later.
 Look up my name as Matthew Ong. Avoid asking the same questions.

Yes, I can understand you feeling that way, being new to the forum. But consider the following: 1. Proposals for changing the language come in daily. Yes, I mean day after day, week after week, month after month, etc. An army of programmers could not possibly implement them, and simply reading about them is in itself a full time job. This pretty much forces us to be "Doctor No" to everything but the very, very best of them. 2. By comparison, C++0x took 10 years to settle on a couple dozen new features. It's the opposite extreme, sure, but is another point on the graph. 3. A constant barrage of implementation of new/incompatible/disruptive features makes the language unstable and unusable. 4. D is a large language, and it takes a while to grok the D way of doing things. People new to D naturally try to use it like the language they came from (and come up short because D isn't their old, comfortable language). Heck, my first year of Fortran programs looked like Basic programs. My first year of C programs looked like Fortran programs. My early C++ programs looked like C programs. And etc. 5. While sometimes someone with fresh eyes can see obvious improvements we all missed, it is a high bar for that to happen. 6. Going from a proposal a few lines long to implementing it is many hours of work - designing, interaction with other features, performance, backwards compatibility, rewriting the specification, writing a test suite, all in addition to actually coding up the change. 7. D's implementation is all up on github now. This means that anyone can fork D and try out new language features. Anyone can grab those forks and try the new feature out and provide real world feedback on it. Having such experience makes it easier to see if a feature is worth while or not.
Jun 07 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 03 Jun 2011 11:19:14 -0400, Matthew Ong <ongbp yahoo.com> wrote:

 On 6/3/2011 11:47 AM, Mehrdad wrote:
 == Quote from Jonathan M Davis (jmdavisProg gmx.com)'s article

 understand templates to use D properly - especially when dealing

 that doesn't help at all.
 I see no advantages with this idea and quite a few disadvantages.

 proposal adds absolutely nothing.
 - Jonathan M Davis

o__o way to bash the proposal, it actually convinced me lol...

>> proposal adds absolutely nothing. You will get this frequently. Especially if you identify with Java development.

Please understand two important things: 1. We are open to proposals of new features, as long as you are open to having them rejected. I have had several ideas that have been incorporated (array appending update, scoped const (inout) ) and have had 10x that amount rejected. 2. Do not take offense to being bashed -- there are literally 2 or 3 new proposals for the language a week. These come in two forms. The first are what I'd call "preferences" or "I wish D did things just like X" where X can be substituted for Java or Python or whatever your favorite bikeshed is called. These kinds of proposals rarely go anywhere, because D usually already supports the requested functionality, just with a different style. These are (understandably) met with statements like the above, especially if the community has already discussed such features ad-nauseum. The second form are proposals that solve a problem that D has. When these come about, usually there is a lively discussion which talks about the merits of such a proposal weighted against the drawbacks. Look for the recent discussion about casting for an example. Note that usually the people who maintain the language are going to be resistant to change -- a frequently changing language can lead to a completely unstable or unimplementable one. You need to really convince everyone that your idea is worth changing the language (and potentially breaking existing code). There are lots of subtle consequences to introducing changes. Many times (and this was the case with your proposals), someone brings up an idea that has been discussed and rejected already. It's sort of unfair to the person just joining the community to be rejected immediately -- they weren't a part of the original discussion. But it's also tiresome to continually argue the same things over and over with new people. I think this is just the way things are, and will always be.
 http://www.digitalmars.com/d/
 Notice: We *welcome feedback about the D compiler or language*,

 Not so true. Or out right should warn people as:

 Notice: Take it the way how we like it here, we are Not Burger K*ng.
 Please see:
 d.D.learn
 AND MAKE sure you read this
 d.D.NoSuchUselessSuggestion

 What do you think D forum people, at least new people here are for warn.
 Add a bit of humor into that.

 I do see a pattern here. Just joined D forum less than 4 weeks ago.
 Got a week off to clear my head. I think now I understand why D is still
 such a small community in the forum.

Go into any community which has a decade of discussion and structure under its belt and say "I'm new here, I think we should change everything to be the way I like it," and see how far you get. This is not a property of D, it's a property of a stable development process. We resist change, but we are open to *new* ideas and creative solutions. For me, I'd rather be bluntly told "this is never going to be accepted, forget about it" than waste time arguing something that has no chance of success. Yes, we welcome feedback about the D compiler or language, but you should also welcome feedback as to why your ideas might not work. Just because you are not successful in your suggestions is not because of some deep-seated hatred for your original language. -Steve
Jun 03 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I don't see the problem, Jonathan explained it pretty well. If someone
gets insulted because their feature request was objectively shot down
then someone is taking themselves a little bit too seriously. :)
Jun 03 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/2/11 10:16 PM, Mehrdad wrote:
 I just thought of something:

 The patterns

 	auto foo1(T)(T arg) { /+ ... +/ }
 	auto foo2(T...)(T args) { /+ ... +/ }

 are very common.


 Why not just supporting the syntax

 	auto foo1(auto arg) { /+ ... +/ }
 	auto foo2(auto args...) { /+ ... +/ }

 to make things easier?

 People can still say typeof(arg), typeof(args[0]), etc., just like
 before, but it's a lot easier (and cooler!) to have a code with all
 inferred types, rather than explicitly typed templates.

 Any ideas?

Walter and I were looking very seriously at this around the beginning of 2008, with exactly the same syntax. At some point I recall we discussed a "static" version too. That was just before we invented template constraints, and around the time when the discussion of C++ concepts were very intensively discussed. C++ concepts ended up not being adopted, but the discussions and past experience with C++ have revealed one important truth: you _almost never_ want a completely unconstrained template. Most any template (aside from the trivial identity function) wants to restrict the types it accepts. max() wants its parameters to be comparable. equal() wants its parameters to be iterable. map() wants its first argument to be a unary function that applies to the elements of the iterable second argument. And so on. Even seemingly completely generic functions such as "to", which accepts most any type, are carefully specialized on type categories (classes, structs, enums, primitives, etc.) By the time all has been said and done, there are extremely few cases in which one ever wants to say "I'll take any argument here, and I don't care about its type". What we realized, therefore, was that such a feature would be usable very rarely, and furthermore it would simply encourage bad practice and sloppy programming (unrestricted templates are black holes that accept everything but then fail to compile with unintuitive error messages and loci). (Cross one element off my wishlist: use "loci" at least once in 2011.) Following the C++ concepts saga has helped us enormously. First, we realized that going that way would collapse D (as they nearly collapsed C++). Second, we figured we needed a simple, lightweight means to curb templates, and that's how restricted templates were born. It's one of our best ideas, and it has dramatically improved generic coding in D. Thanks, Andrei
Jun 03 2011
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Incidentally I did write a feature request for some new constraint
syntax, it wasn't shot down but it wasn't discussed all that much. But
now that I look at it again my problem wasn't really the syntax, but
the error messages.
Jun 03 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 as a templated function gets several
 constraints it's impossible to figure out which constraint failed just
 by looking at the error message. The only thing you ever get back is:
 "<complex template declaration> does not match any function template
 declaration"
 "<complex template declaration> cannot deduce template function from
 argument types <your arguments here>"
 
 You get to see which arguments you've passed, but not which of the
 constraints failed. If you wrote the template it might be easy to
 figure out that you can't pass a certain type of argument, but if you
 didn't write it it's hard to figure out what went wrong.

This is a problem that I've discussed some in past. I think it's worth discussing some more about a possible way to add user defined error messages (like the second argument of a static assert) to template constraints. To do this it's good to have first of all a short list of typical use cases where we'd like to add some messages. Bye, bearophile
Jun 03 2011
prev sibling next sibling parent reply Matthew Ong <ongbp yahoo.com> writes:
On 6/3/2011 11:16 AM, Mehrdad wrote:

But it's also tiresome to continually argue the same things over and 
over with new people.  I think this is just the way things are, and 
will always be.

experience? Perhaps people knows that is the useful syntax? Nope, the world changed in the last 3-4 years, and shocked a lot of people. Past does not define the future. Just like C++ people mocked at Java 1.0 or Java mocked at C# does not mean those idea are alll bad? The only constant in history is: Past does not define the future. Walter and I were looking very seriously at this around the beginning of 2008, with exactly the same syntax. At some point I recall we discussed a "static" version too. + Many times (and this was the case with your proposals), someone brings up an idea that has been discussed and rejected already. =
AND MAKE sure you read this
d.D.NoSuchUselessSuggestion

See, I do understand your frustration targeted at newbie with such suggestion. Personally I think Mehrdad did a good job in suggesting this new syntax. He might have been exposed in other modern language like X? Feel free to shoot this down like a bug also. -- Matthew Ong email: ongbp yahoo.com
Jun 03 2011
next sibling parent reply Matthew Ong <ongbp yahoo.com> writes:
On 6/4/2011 12:36 AM, Matthew Ong wrote:
 On 6/3/2011 11:16 AM, Mehrdad wrote:

yahoo to help vote for syntax that programmer really wants. A simple solution to the long like JCP process in Java. If the aim is to grow D into a large community, popular hated syntactic sugar counts!!! Plain old fact. How did people in Java overcome the need of new syntactic sugar and still keep the some original bytecode design? See this URL: http://www.javac.info/closures-v05.html Example. The variable declaration {int,String=>Number throws IOException} xyzzy; is *translated into* interface Function1<R,A2,throws E> { // system-generated R invoke(int x1, A2 x2) throws E; } Function1<? extends Number,? super String,? extends IOException> xyzzy; Original syntax kept, original binary generated is also kept. No changes to the JVM and NO changes to the API. Just overcome that with the compilation and linking process. Just a 'simpleton' suggestion, yes? Just ensure someone filter the list on new feature, so that it will meet: to consistently *do the right thing* within the constraints it chose My dear 'friends', this is like deciding what is the best official language in a world conference. Not possible. IT world tried once with XML protocol and look at the end results? Not a total failure, but went further and further away from that original goal. Then JSON, BSON, YAML... so on and so on... Did Java XML talk transparently with C# or C++ XML? See a software developers common thinking pattern here? D need to open up and tries to see how to pick the syntax people like. I am just citing an example in english, it could have been french/spanish/... I am sure, before poetry format are created in the past for english language, the same content can be communicated via point form sentences. But poetry is formed because it also communicate more beautifully, emotion can be attached to the content? That my 'friend' is the syntactic sugar in the human language. Hopefully you understand what the current direction of the programming language seems to be going? -- Matthew Ong
Jun 03 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/3/11 12:22 PM, Matthew Ong wrote:
 On 6/4/2011 12:36 AM, Matthew Ong wrote:
 On 6/3/2011 11:16 AM, Mehrdad wrote:

yahoo to help vote for syntax that programmer really wants. A simple solution to the long like JCP process in Java. If the aim is to grow D into a large community, popular hated syntactic sugar counts!!! Plain old fact. How did people in Java overcome the need of new syntactic sugar and still keep the some original bytecode design? See this URL: http://www.javac.info/closures-v05.html Example. The variable declaration {int,String=>Number throws IOException} xyzzy; is *translated into* interface Function1<R,A2,throws E> { // system-generated R invoke(int x1, A2 x2) throws E; } Function1<? extends Number,? super String,? extends IOException> xyzzy; Original syntax kept, original binary generated is also kept. No changes to the JVM and NO changes to the API. Just overcome that with the compilation and linking process. Just a 'simpleton' suggestion, yes?

Although I'm sure you don't mean it, this is a manipulation because it vaguely associates your argument with an obviously good example. Then by extension that implies that your argument has value on its own. The above is called lowering, and D uses it extensively. "lowering" is present in TDPL's index with five referring pages. The value of syntactic sugar is understood and we provide it to the best extent we can. That doesn't mean any suggestion for syntactic sugar is good, and it doesn't mean that not accepting such is a sign of narrow-mindedness of the community.
 Just ensure someone filter the list on new feature, so that it will meet:
 to consistently *do the right thing* within the constraints it chose

 My dear 'friends', this is like deciding what is the best official
 language in a world conference. Not possible.

 IT world tried once with XML protocol and look at the end results?
 Not a total failure, but went further and further away from that
 original goal.

 Then JSON, BSON, YAML... so on and so on...

 Did Java XML talk transparently with C# or C++ XML?

 See a software developers common thinking pattern here?
 D need to open up and tries to see how to pick the syntax people
 like.

 I am just citing an example in english, it could have been
 french/spanish/...
 I am sure, before poetry format are created in the past for english
 language, the same content can be communicated via point form sentences.
 But poetry is formed because it also communicate more beautifully,
 emotion can be attached to the content?

 That my 'friend' is the syntactic sugar in the human language.

 Hopefully you understand what the current direction of the programming
 language seems to be going?

Mehrdad made a sensible suggestion, and just as sensibly understood the issues that surround it. The fact that you refuse to do so, and instead are falling increasingly in a self-reassuring pattern, does not speak well about your competence. If I were you, I'd abandon this increasingly disorganized rant, and thought of how I can improve the quality of my proposals and contributions. Thanks, Andrei
Jun 03 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 On 6/3/11 12:22 PM, Matthew Ong wrote:
 On 6/4/2011 12:36 AM, Matthew Ong wrote:
 On 6/3/2011 11:16 AM, Mehrdad wrote:

yahoo to help vote for syntax that programmer really wants. A simple solution to the long like JCP process in Java. If the aim is to grow D into a large community, popular hated syntactic sugar counts!!! Plain old fact. How did people in Java overcome the need of new syntactic sugar and still keep the some original bytecode design? See this URL: http://www.javac.info/closures-v05.html Example. The variable declaration {int,String=>Number throws IOException} xyzzy; is *translated into* interface Function1<R,A2,throws E> { // system-generated R invoke(int x1, A2 x2) throws E; } Function1<? extends Number,? super String,? extends IOException> xyzzy; Original syntax kept, original binary generated is also kept. No changes to the JVM and NO changes to the API. Just overcome that with the compilation and linking process. Just a 'simpleton' suggestion, yes?

vaguely associates your argument with an obviously good example. Then by extension that implies that your argument has value on its own. The above is called lowering, and D uses it extensively. "lowering" is present in TDPL's index with five referring pages. The value of syntactic sugar is understood and we provide it to the best extent we can. That doesn't mean any suggestion for syntactic sugar is good, and it doesn't mean that not accepting such is a sign of narrow-mindedness of the community.
 Just ensure someone filter the list on new feature, so that it will meet:
 to consistently *do the right thing* within the constraints it chose

 My dear 'friends', this is like deciding what is the best official
 language in a world conference. Not possible.

 IT world tried once with XML protocol and look at the end results?
 Not a total failure, but went further and further away from that
 original goal.

 Then JSON, BSON, YAML... so on and so on...

 Did Java XML talk transparently with C# or C++ XML?

 See a software developers common thinking pattern here?
 D need to open up and tries to see how to pick the syntax people
 like.

 I am just citing an example in english, it could have been
 french/spanish/...
 I am sure, before poetry format are created in the past for english
 language, the same content can be communicated via point form sentences.
 But poetry is formed because it also communicate more beautifully,
 emotion can be attached to the content?

 That my 'friend' is the syntactic sugar in the human language.

 Hopefully you understand what the current direction of the programming
 language seems to be going?

issues that surround it. The fact that you refuse to do so, and instead are falling increasingly in a self-reassuring pattern, does not speak well about your competence. If I were you, I'd abandon this increasingly disorganized rant, and thought of how I can improve the quality of my proposals and contributions. Thanks, Andrei

Interesting... I just saw the continuation of this thread, and wanted to make some meta-comments (I guess this should be on meta.digitalmars.com, haha): I admittedly didn't bother to check whether my suggestion was made before. Sorry. :( Question: Why? Answer: Because it's really hard to search for it, and it gets really annoying past the Nth time you try to. The *only* useful way I know of for searching is to add "site:digitalmars.com" in my Google query, which gets _really_ annoying to type after a while... and it doesn't help that the results aren't always on the mark (although it's hard to say anybody is at fault here). So I just stopped bothering to do that a while ago (sorry) and didn't really bother checking whether my suggestion was already made. But, on the other side of things, if I was on a newsgroup where newbies repeated the same suggestions over and over again, I'd get pretty annoyed myself. I think it's natural, and ultimately, a lot of this boils down to the inability to search the newsgroup effectively (or perhaps my lack of knowledge on how to do that effectively, if I haven't found the right way to do it). Ultimately, I'm not sure myself what the fix for this would be. The only thing I've found found to be AMAZINGLY useful is StackOverflow's automatic search based on the title (while you're typing your own question), but that's not exactly easy to implement well, and I'm not sure if that's a reasonable thing to expect for this site, at least in the short term. I'm not sure what the solution is, but _some_ easy way to search the newsgroups would DEFINITELY make duplicate suggestions by newbies less likely, IMHO. Possible ideas for improvement: 1. Better searching on the newsgroup 2. Allow for categorization of posts somehow (although that's kinda against how newsgroups work, I guess...) 3. Something better that I can't think of Again, I'm not blaming anybody or anything, just noting why duplicate and/or not-so-great ideas sometimes get posted (IMO). Hope this feedback is useful. :) Mehrdad
Jun 03 2011
next sibling parent Matthew Ong <ongbp yahoo.com> writes:
On 6/4/2011 12:20 PM, Mehrdad wrote:

meta-comments (I guess this should be on meta.digitalmars.com, haha):

 But, on the other side of things, if I was on a newsgroup where newbies
repeated the same suggestions over and over again, I'd get pretty annoyed
myself. I think it's natural, and ultimately, a
 lot of this boils down to the inability to search the newsgroup effectively
(or perhaps my lack of knowledge on how to do that effectively, if I haven't
found the right way to do it).

coparation network does not allow newsgroup protocol and only HTTP/S from laptop.
The only thing I've found found to be AMAZINGLY useful is 

your own question) I will like that a lot also. -- Matthew Ong email: ongbp yahoo.com
Jun 03 2011
prev sibling parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 04.06.2011 06:20, schrieb Mehrdad:
 Interesting... I just saw the continuation of this thread, and wanted to make
some meta-comments (I guess this should be on meta.digitalmars.com, haha):


 I admittedly didn't bother to check whether my suggestion was made before.
Sorry. :(

 Question: Why?

 Answer:   Because it's really hard to search for it, and it gets really
annoying past the Nth time you try to. The *only* useful way I know of for
searching is to add "site:digitalmars.com" in
 my Google query, which gets _really_ annoying to type after a while...

Or you just use the search form on digitalmars.com/d and you don't have to type site:digitalmars.com yourself :-)
Jun 04 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
== Quote from Daniel Gibson (metalcaedes gmail.com)'s article
 Am 04.06.2011 06:20, schrieb Mehrdad:
 Interesting... I just saw the continuation of this thread, and


meta.digitalmars.com, haha):
 I admittedly didn't bother to check whether my suggestion was


 Question: Why?

 Answer:   Because it's really hard to search for it, and it gets


I know of for searching is to add "site:digitalmars.com" in
 my Google query, which gets _really_ annoying to type after a


 Or you just use the search form on digitalmars.com/d and you don't

 to type site:digitalmars.com yourself :-)

Does it search the newsgroups? More than 75% of my searches on language features fail (since it seems to ignore the language for some reason), so I haven't tried using it for the newsgroups too much...
Jun 04 2011
parent Daniel Gibson <metalcaedes gmail.com> writes:
Am 04.06.2011 10:48, schrieb Mehrdad:
 == Quote from Daniel Gibson (metalcaedes gmail.com)'s article
 Am 04.06.2011 06:20, schrieb Mehrdad:
 Interesting... I just saw the continuation of this thread, and


meta.digitalmars.com, haha):
 I admittedly didn't bother to check whether my suggestion was


 Question: Why?

 Answer:   Because it's really hard to search for it, and it gets


I know of for searching is to add "site:digitalmars.com" in
 my Google query, which gets _really_ annoying to type after a


 Or you just use the search form on digitalmars.com/d and you don't

 to type site:digitalmars.com yourself :-)

Does it search the newsgroups? More than 75% of my searches on language features fail (since it seems to ignore the language for some reason), so I haven't tried using it for the newsgroups too much...

http://www.digitalmars.com/NewsGroup.html at least if your start here it does search the newsgroups. The site search never seems to return results from the language spec, for whatever reason.
Jun 04 2011
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 03 Jun 2011 12:36:20 -0400, Matthew Ong <ongbp yahoo.com> wrote:

 On 6/3/2011 11:16 AM, Mehrdad wrote:

  >But it's also tiresome to continually argue the same things over and  
  >over with new people.  I think this is just the way things are, and  
  >will always be.
 Have you ever wonder why that pops up over and over again by your own
 experience?

It depends on the problem. If the problem has a conclusive negative answer, it's just annoying. If it's something that seems promising but we could not find a way to implement it, or we already implemented it some other way, then it can be difficult to convince someone to reopen it. Take for instance rebindable const object references. Walter steadfastly refused to look at any possible new suggestions because he had already expended so much time trying to find a syntax that worked and was not confusing. I still feel there is a possible syntax that would work, and that it's a feature we need. Michel Fortin's patch for it seems like the only possible way to get this through with Walter, we'll see how it works out. But yes, there are cases where something is a good idea, but it is difficult to get people to listen to your ideas because they have too much bad blood with it.
 Perhaps people knows that is the useful syntax? Nope,
 the world changed in the last 3-4 years, and shocked a lot of people.

Again, if you have new ideas that people haven't seen before or haven't tried before, it's always worth trying to see if people will accept them. When you see "we tried that already, and it doesn't work" it's a good idea to stop right there (although a thorough explanation is usually more appreciated).
 Past does not define the future. Just like C++ people mocked at Java 1.0
 or Java mocked at C# does not mean those idea are alll bad?

I hate salmon. Every time I go out to eat with my parents and my father gets salmon, he tries to get me to eat it saying "yeah, I know you don't like salmon, but this is different, this is really good". And any time I try it, I still hate it. If someone says "we tried that *EXACT* thing in the past, and it doesn't work" you are basically wasting your time arguing that you have some new interesting way to get it to work. BTW, D has a lot of ideas that came from Java and C#, we are not against them.
 The only constant in history is: Past does not define the future.

No, the only constant is people who ignore history are bound to repeat it. -Steve
Jun 03 2011
parent reply Matthew Ong <ongbp yahoo.com> writes:
On 6/4/2011 1:32 AM, Steven Schveighoffer wrote:

 But yes, there are cases where something is a good idea, but
 it is difficult to get people to listen to your ideas because they have
 too much bad blood with it.

 Perhaps people knows that is the useful syntax? Nope,
 the world changed in the last 3-4 years, and shocked a lot of people.
 Past does not define the future. Just like C++ people mocked at Java 1.0
 or Java mocked at C# does not mean those idea are alll bad?

gets salmon, he tries to get me to eat it saying "yeah, I know you don't like salmon, but this is different, this is really good". And any time I try it, I still hate it.

NOT impact the rest of the community. We are talking about the other way around. Single or small group of people's choice that DOES impacting the entire D community. Unless we are talking about being a iron curtain style management, EVEN that has changed.
 The only constant in history is: Past does not define the future.

No, the only constant is people who ignore history are bound to repeat it.

Sometime, repeating the history, get things changed. Most people need linear time to 'sink' in the idea. -- Matthew Ong
Jun 03 2011
parent Matthew Ong <ongbp yahoo.com> writes:
On 6/4/2011 2:10 AM, Steven Schveighoffer wrote:

 Again, you can't base all this on one failed proposal.

http://download.java.net/jdk7/docs/technotes/guides/language/strings-switch.html I am sure they would have talked about the pro and cons already? That suggestion is ahead of this java 7 implementation of only static string value.
*Sometime* (not all the time), repeating the history, get things 

This should speak for itself clearly.
Walter steadfastly

If you have a legitimate argument, you will get better results. 

submitted. Totally agree about this. Which is why I suggested this: Alternatively, D might want to use *some kind of voting tool online* on yahoo (group, missing) to help vote for syntax that programmer really wants. A simple solution to the long like JCP process in Java. Web base open voting with clear results viewed. Or else, who knows what has already been suggested and voted on for the next version of DMD?
The point is, if something doesn't work, "trying it again" isn't going 

I understand that, I went offline for a week plus to see if someone with more solid case to present and is similar or inline with the proposal that presented. No point being the lone person voicing out?
Single or small group of people's choice that DOES impacting the 

I know most of them are not from digital mars.
a iron curtain style management, EVEN that has changed.

 Good ideas aren't always accompanied by good or obvious designs.  The
 point I was making is, you need to have a very solid "oh, obviously that
 is better!" design in those cases in order to re-open the issue, even if
 the core ideas are solid.

What I see in your past proposals are personal choices that will 

That is normal for all mankind to make a preference of choices, some think english is good because of Shakespear, chinese is good because of LiBai, and yet others,
What you need to do in this case is *avoid* repeating history.

to consistently *do the right thing* within the constraints it chose In programming and *most*(not all) thing in life. As not possible. Unless you claim to know all possible path of future. That mentality is in itself self-contradictory. Since, it is constrained. It is more like recovering from the error that you make and solutions found and kept. Java 1.4 to 1.5, James Gosling also had the mind set of trying to keep things as simple as possible. M$ proved otherwise with C#. It is an industrial factual history. M$ did the right choice in this aspect and captured a large set of developer. Hopefully this makes a clear solid point as shown here.
The point I was making is, you need to have a very solid "oh, 

I am not talking about "auto" anymore, but the process of reviewing new suggestions and improvement. -- Matthew Ong email: ongbp yahoo.com
Jun 03 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 03 Jun 2011 13:50:49 -0400, Matthew Ong <ongbp yahoo.com> wrote:

 On 6/4/2011 1:32 AM, Steven Schveighoffer wrote:

 But yes, there are cases where something is a good idea, but
 it is difficult to get people to listen to your ideas because they have
 too much bad blood with it.


Good ideas aren't always accompanied by good or obvious designs. The point I was making is, you need to have a very solid "oh, obviously that is better!" design in those cases in order to re-open the issue, even if the core ideas are solid.
 Perhaps people knows that is the useful syntax? Nope,
 the world changed in the last 3-4 years, and shocked a lot of people.
 Past does not define the future. Just like C++ people mocked at Java  
 1.0
 or Java mocked at C# does not mean those idea are alll bad?

gets salmon, he tries to get me to eat it saying "yeah, I know you don't like salmon, but this is different, this is really good". And any time I try it, I still hate it.

does NOT impact the rest of the community. We are talking about the other way around.

The point is, if something doesn't work, "trying it again" isn't going to make it work the next time. What I see in your past proposals are personal choices that will affect everyone in the community, almost all of which are happy with the current state of things. It's not a good place to start from. If you want to tackle a problem that affects a lot of people, you will definitely get better reception, and if you can do it in a way that doesn't break existing code, you will be even further.
 Single or small group of people's choice that DOES impacting the entire  
 D community. Unless we are talking about being a iron curtain style  
 management, EVEN that has changed.

Not accepting bad designs does not mean management is ruling with an iron curtain. Propose better designs, you'll get a better response. Again, you can't base all this on one failed proposal. If you have a legitimate argument, you will get better results. Listening to the community doesn't mean obeying every request that gets submitted.
 The only constant in history is: Past does not define the future.

No, the only constant is people who ignore history are bound to repeat it.

Sometime, repeating the history, get things changed. Most people need linear time to 'sink' in the idea.

Really? That goes against all logic I can think of. Isn't the definition of insanity doing the same thing over and over again, but expecting different results? What you need to do in this case is *avoid* repeating history. Don't have the same failed arguments over and over, you will get nowhere. -Steve
Jun 03 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 04 Jun 2011 02:05:14 -0400, Matthew Ong <ongbp yahoo.com> wrote:

 Alternatively, D might want to use *some kind of voting tool online* on  
 yahoo (group, missing) to help vote for syntax that programmer really  
 wants. A simple solution to the long like JCP process in Java.

We have this, bugzilla allows voting, you can vote once per bug/proposal (and you have 10 votes total you can distribute): http://d.puremagic.com/issues/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&query_format=advanced&votes=1&order=votes%2Cbug_id&query_based_on= That is all the open bugs that have at least one vote, sorted by votes. We also have a wiki where DIPs (D improvement proposals) can be created to flesh out ideas in a more formal fashion. However, this system has no voting or really feedback, so I'd recommend using bugzilla or the newsgroups first. -Steve
Jun 06 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/3/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 (unrestricted templates are black holes that accept
 everything but then fail to compile with unintuitive error messages and
 loci).

Agreed for that point, but as a templated function gets several constraints it's impossible to figure out which constraint failed just by looking at the error message. The only thing you ever get back is: "<complex template declaration> does not match any function template declaration" "<complex template declaration> cannot deduce template function from argument types <your arguments here>" You get to see which arguments you've passed, but not which of the constraints failed. If you wrote the template it might be easy to figure out that you can't pass a certain type of argument, but if you didn't write it it's hard to figure out what went wrong.
Jun 03 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-06-07 10:20, Timon Gehr wrote:
 Jonathan M Davis wrote:
 ...
 And while D might arguably allow too many implicit conversions, it allows
 fewer than C or C++. I actually would expect that bugs due to implicit
 conversions would be fairly rare in D. And requiring more conversions to
 be explicit might actually make things worse, because it would become
 more frequently necessary to use casts, which tend to hide various types
 of bugs. So, while it might be better to require casting in a few more
 places than D currently does, on the whole it works quite well. And
 certainly expecting a major paradigm shift at this point is unrealistic.
 Minor improvements may be added to the language, and perhaps major
 backwards-compatible features may be added, but for the most part, D is
 currently in the mode of stabilizing and completing the implementation
 of its existing feature set. It's _far_ too late in the game to
 introduce something like Hindley-Milner type inference, regardless of
 whether it would have been a good idea in the beginning (and honestly,
 given D's C and C++ roots, I very much doubt that it ever would have
 been a good idea to have Hindley-Milner type inference in it - that
 would have made for a _very_ different sort of language, which
 definitely wouldn't be D).
 
 - Jonathan M Davis

Widening implicit casts are very convenient. What I think is annoying is that D allows implicit conversions that are narrowing. Eg: int -> float long -> double real -> double double -> float Especially questionable is the real -> double -> float chain. This and implicitly casting an integer value to a floating point type whose mantissa is too small should imho be disallowed.

Hmmm. That's a bit odd given that narrowing conversion require casts for integral types. Casting from an integral type to a floating point type of the same size seems fine to me (floating point values aren't exactly exact anyway), but I would have thought that narrowing conversions between floating point types would have required casts.
 BTW: You can have safe 'casts'. I think std.conv.to does/will allow only
 type conversions that are safe.

Yes. But just because a type conversion is safe doesn't mean that it's the right thing to do (e.g. narrowing conversions are _always_ safe but often incorrect). Casts hide things, and while to does it less, that doesn't mean that it doesn't do it. So, it's not like to solves all of the problems that you might have with casting. And there are plenty of programmers who will just use casts when they should be using to, because casting is the normal thing to do in most C-based languages. So, introducing situations where casts are required but could reasonably not be can be problematic. The trick is determining which implicit casts ultimately make sense and which don't. - Jonathan M Davis
Jun 07 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/7/11, foobar <foo bar.com> wrote:
 foo(a, b) { return a + b; } // will be lowered to:
 T foo(T) (T a, T b) { return a + b; }

Thanks to someone who was trying to be clever, the win32 bindings have these templates: template max(T) { T max(T a, T b) { return a > b ? a : b; } } template min(T) { T min(T a, T b) { return a < b ? a : b; } } They clash with std.algorithm : min and max, but at the same time they can't really be instantiated in the same way. Now I have the situation where they conflict but at the same time only the std.algorithm templates can be instantiated. Compiler errors everywhere, great. So now I have to force my code to use std.algorithm by importing via: import std.algorithm : min, max; or alternatively: import std.algorithm; alias std.algorithm.min min; alias std.algorithm.max max; Pain in the ass.
Jun 07 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-08 19:27, Ary Manzana wrote:
 On 6/8/11 11:56 PM, Jonathan M Davis wrote:
 On 2011-06-08 02:20, Ary Manzana wrote:
 On 6/7/11 9:50 PM, Andrei Alexandrescu wrote:
 On 6/7/11 5:35 AM, Ary Manzana wrote:
 Well, in Ruby every parameter type is auto. And it works pretty well.
 
 :-)
 
 When you invoke a method and something goes wrong, like the auto
 parameter doesn't have a method, it gives a sensible error message.

It does, just at run time. The way dynamic languages and static languages set up computation is very different and as such difficult to compare something as core as function call resolution as equals for equals.
 So:
 
 void foo(auto parameter) {
 return parameter * 2;
 }
 
 could just be the same as
 
 void foo(T)(T parameter) {
 return parameter * 2;
 }
 
 just with a nicer syntax (but I understand it doesn't add much).

The counterpoint is that you seldom want to write foo() as written above. You want to clarify what family of types it is intended for.

Why? Note that in Ruby you *NEVER* say the family of types, and that is a huge bennefit. Good tests and good documentation are better than restricting the time. Look at this: ====================================================== import std.stdio; // This is Ruby :-) auto foo(T)(T param) { return param * 2; } class MyClass { int value; this(int value) { this.value = value; } int opBinary(string op)(int other) if (op == "*") { return value * other; } } int main() { auto x = foo(3); auto y = foo(6L); auto z = foo(new MyClass(10)); writefln("%s", x); writefln("%s", y); writefln("%s", z); return 0; } ====================================================== This function: auto foo(T)(T param) { return param * 2; } Could be just as well: auto foo(auto param) { return param * 2; } Yes, in Ruby it is checked on runtime, on D it is checked on compile-time. What's cool about "auto param"? I have written a function once and it will work for everything that can be multiplied and it will be compiled efficiently for every type that I pass that complies to the function. Why you find it useless? Why do I have to restrict the type? I can restrict the type just for the operations being performed on it and then my function is open to any param that accepts those operations. I know, I know. This is the same as just a template, but with a different syntax. I just don't understand why you think you will almost always would like to restrict the type you pass to the function. If you do, you limit your code. If you don't, you open your code and you have to write less code.

You want to restrict it for several reasons, including the fact that if you don't, you get hideous error messages when you use a type with a template that it doesn't work with.

That's not the reason I shouldn't be using it. The compiler should give precise error messages. For instance, first I wrote this code: void foo(T)(T param) { return param * 2; } I got these messages back: main.d(4): Error: * has no effect in expression (param * 2) main.d(20): Error: template instance main.foo!(int) error instantiating main.d(20): Error: variable main.main.x voids have no value main.d(20): Error: expression foo(3) is void and has no value Umm... can't it just tell me "foo's return type is void and you are trying to return an int"?

There are definitely things that can be done to improve error messages, but providing good error messages for templates is notoriously hard. C++ has been at it for years, and its error messages are still pretty awful regardless of the compiler you're using. Remember that when you're dealing with templates, you're compiling generated code, which complicates things a fair bit. If it gives you error messages like it does if you had written the code by hand (which is what it frequently ends up doing, if not always), then the messages tend to be incredibly obtuse, because you may not have written the code which is failing, and there's a good chance that error message means nothing to you. And if it doesn't treat the templates as normal code when dealing with errors, then that complicates template compilation a fair bit, because you have to duplicate all kinds of error checking and error reporting stuff. And how does the compiler know whether it's an error in the template itself or if it's an error simply because you gave it a template argument which just doesn't work with that template? I don't think that there's any question that template error messages could be improved, and they likely will be, but by their very nature, reporting template-related errors seems to be a difficult task to adequately solve. It's one of the things that many people complain about with C++. Template constraints improve the situation considerably. - Jonathan M Davis
Jun 08 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-09 00:19, Ary Manzana wrote:
 On 6/9/11 9:56 AM, Jonathan M Davis wrote:
 I don't think that there's any question that template error messages
 could be improved, and they likely will be, but by their very nature,
 reporting template-related errors seems to be a difficult task to
 adequately solve. It's one of the things that many people complain about
 with C++. Template constraints improve the situation considerably.

I don't think the problem is with templates. If I try to compile this: === void foo(int param) { return param * 2; } void main() { foo(3); } === it says: main.d(2): Error: * has no effect in expression (param * 2) WTF? Don't make me think. I just really want to know that I'm returning from a void function and I can't do that. Let's assign foo(3) to something: === void foo(int param) { return param * 2; } void main() { auto x = foo(3); } === It says: main.d(2): Error: * has no effect in expression (param * 2) main.d(6): Error: variable main.main.x voids have no value main.d(6): Error: expression foo(3) is void and has no value Really? Voids have no value? That's good to know, I didn't know that voids have no value. Mmm... those are messages to be read by the compiler, not by the user. The compiler is expecting something that's not void and it is getting a void thing. The message it generates is "Voids has no value". The problem are not templates or templates messages. The problem is that the very basic compiler error messages are targeted at the compiler, not the developer. And then this: === void main() { const x = 1; x = 3; } === main.d(3): Error: variable main.main.x cannot modify const What do you mean when you say that the variable x cannot modify const? Wait, I desguise myself as Tarzan and now I understand. It should be "Error: trying to modify const variable main.main.x". There is an excellent book called "Don't make me think". When I see "variable main.main.x cannot modify const" I have to think a little to understand that that means "variable main.main.x is const and cannot be modified". Don't make me think. :-)

Template error messages _do_ tend to be hideous. But that doesn't mean that normal errors are the best either. And as I said, templates often end up reporting exactly the same errors that you'd get if you wrote the code by hand, it's just that the errors are then in the template and generally harder to understand, because there's a good chance that it's not the code that you write. But regardless, none of these error messages are intended to be "read by the compiler." They're all intended to be read by humans. It's just that you don't find the choice of wording to be particularly understandable. However, everything that it's saying is correct. If you find particular error messages to be bad - particularly if you can think of better alternatives - then create enhancement requests for them in bugzilla. Then perhaps we'll get better error messages. But remember that the compiler doesn't know what you're trying to do. It only knows what you told it to do, so its messages tend to be targetted at telling you that what you're doing isn't working rather than telling you what you should be doing instead. So, error messages are often not that great simply because the compiler is not a mind-reader. Still, if you have suggestions for improvements to error messages, please submit them to bugzilla so that the error messages can be improved. - Jonathan M Davis
Jun 09 2011