Infer function template parameters

Jonas Drewsen jdrewsen at nospam.com
Fri Sep 21 04:14:56 PDT 2012


On Thursday, 20 September 2012 at 21:39:31 UTC, Jonathan M Davis 
wrote:
> On Thursday, September 20, 2012 21:57:47 Jonas Drewsen wrote:
>> In foreach statements the type can be inferred:
>> 
>> foreach (MyFooBar fooBar; fooBars) writeln(fooBar);
>> same as:
>> foreach (foobar; fooBars) writeln(fooBar);
>> 
>> This is nice and tidy.
>> Wouldn't it make sense to allow the same for function templates
>> as well:
>> 
>> auto min(L,R)(L a, R b)
>> {
>> return a < b;
>> }
>> 
>> same as:
>> 
>> auto min(a,b)
>> {
>> return a < b;
>> }
>> 
>> What am I missing (except some code that needs chaging because
>> only param type and not name has been specified in t?
>
> You don't want everything templated. Templated functions are 
> fundamentally
> different. They don't exist until they're instantiated, and 
> they're only
> instantiated because you call them. Sometimes, you want 
> functions to always
> exist regardless of whether any of your code is calling them 
> (particularly
> when dealing with libraries).

I agree. And in that case just use a non-templated version that 
specifies the types as always.

> Another result of all of this is that templated functions can't 
> be virtual, so
> your proposal would be a _huge_ problem for classes. Not to 
> mention, errors
> with templated functions tend to be much nastier than with 
> non-templated
> functions even if it's not as bad as C++.

I don't see how the terser syntax for templated functions has 
anything to do with this. The things you mention are simply facts 
about templated functions and nothing special for the suggested 
syntax.

> Also, your prosposal then means that
> we'd up with templated functions without template constraints 
> as a pretty
> normal thing, which would mean that such functions would 
> frequently get called
> with types that don't work with them. To fix that, you'd have 
> to add template
> constraints to such functions, which would be even more verbose 
> than just
> giving the types like we do now.

By looking at the two examples I provided, both the existing 
syntax and the new one suffers from that. The new one is just 
nicer on the eyes I think.

> You really need to be able to control when something is 
> templated or not. And
> your proposal is basically just a terser template syntax. Is it 
> really all
> that more verbose to do
>
> auto min(L, R)(L a, R b) {...}
>
> rather than
>
> auto min(a, b) {...}

Some people would love to be able to use D as a scripting 
language using e.g. rdmd. This is the kind of thing that would 
make it very attractive for scripting.

I am _not_ suggesting to replace the existing syntax since that 
really should be used for things like phobos where everything 
must be checked by the type system as much as possible upfront. 
But for many programs (especially in the prototyping/exploratory 
phases) the same kind of thoroughness is not within the resource 
limits.

That is probably why many use dynamically typed languages like 
python/ruby for prototyping and first editions and end up 
sticking with those languages in the end. D has already taken 
great steps in that direction and this is just a suggestion to 
make it even more attractive.

> And even if we added your syntax, we'd still need the current 
> syntax, because
> you need to able to indicate which types go with which 
> parameters even if it's
> just to say that two parameters have the same type.

As mentioned before this suggestion is an addition. Not a 
replacement.

> Also, what happens if you put types on some parameters but not 
> others? Are
> those parameters given templated types? If so, a simple type 
> could silently
> turn your function into a templated function without you 
> realizing it.

Maybe I wasn't clear in my suggestion. The new syntax in simply a 
way to define a templated function - not a non-templated one ie:

auto foo(a,b) {}
is exactly the same as
auto foo(A,B)(A a, B b) {}

The semantic of what should happen if one of the parameters had 
its type provided is up for discussion. But I think that it 
should be allowed and just lock that template parameter to that 
type. This would not change it from templated to non-templated in 
any case afaik.

> Then there's function overloading. If you wanted to overload a 
> function in
> your proposal, you'd have to either still give the types or use 
> template
> constraints, meaning that it can't be used with overloaded 
> functions.

Yes. As with the the existing template syntax.

> Another thing to consider is that in languages like Haskell 
> where all
> parameter types are inferred, it's often considered good 
> practice to give the
> types anyway (assuming that the language lets you - Haskell 
> does), because the
> functions are then not only easier to understand, but the error 
> messages are
> more sane.

And the good practice is done on stable code or when you are sure 
about what you are doing from the start. I do not think it is 
uncommon to try out a solution and refactor and iterate until 
things gets nice and tidy. This is definitely not the only way to 
work, but for some problem domains (especially the ones you are 
not well versed in yet) this is not uncommon. That claim is my 
own :)

I guess "productivity" could be a buzz word to put in here  if I 
were into buzzwords.

/Jonas



More information about the Digitalmars-d mailing list