How about "auto" parameters?

Jonathan M Davis jmdavisProg at gmx.com
Wed Jun 8 09:56:16 PDT 2011


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


More information about the Digitalmars-d mailing list