The syntax of sort and templates

zakk via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri May 26 04:27:19 PDT 2017


On Friday, 26 May 2017 at 11:18:44 UTC, Stanislav Blinov wrote:
> On Friday, 26 May 2017 at 09:59:26 UTC, zakk wrote:
>> Hello everyone,
>>
>> I just started using D and I am a bit puzzled by the syntax of 
>> the sort function is std.algorithm.sorting, which is
>>
>> sort!(comparingFunction)(list)
>>
>> where comparingFunction is often a lambda expression. For 
>> instance in the Wolfram Language the equivalent function is
>>
>> Sort[list,comparingFunction]
>>
>> My questions are:
>>
>> 1) Why is D making using of the binary ! operator, which as 
>> far as I understand introduces a template?
>
> The ! operator is needed to distinguish template arguments, 
> passed and known at compile time, from actual function 
> arguments, passed and known at run time. "!" doesn't 
> "introduce" a template. The definition of 'sort' is a template, 
> sort!(fn)(list) is an instantiation of that template with 
> concrete arguments.
>
> In C++, template arguments are denoted with <>, which is more 
> verbose and introduces syntax ambiguity in complex templates. D 
> avoids that by using the !.
>
>> 2) Why is a template needed here?
>
> Templates are a form of polymorphism that works at compile 
> time. It allows the programmer to write, and the compiler to 
> generate, the most efficient an/or the most practical code 
> given the concrete use case. The net effect is that at runtime 
> you get the sorting function that is tailored for the specific 
> types and comparison predicate, as if it was written by hand.
>
>
>> 3) It seems to me like the argument passed to the template is 
>> a lambda expression. I only know about templates taking types 
>> as argument. What's going on?
>
> In D, depending on their definition, templates can take types, 
> values or symbols as arguments. In this case, sort takes the 
> comparison function and inserts it directly into the algorithm, 
> which enables the compiler to inline it and/or perform various 
> other optimizations, which would've been harder or impossible 
> to do if the function was only known at runtime.
> Also, this enables writing concise code: in Phobos, algorithms 
> that take predicates allow to pass them as string literals 
> instead of full-blown functions:
>
> sort!"a < b"(list);
>
> The "a < b" will be transformed at compile time into (a, b) => 
> a < b.

Thanks Gary and Stanislav for your replies.

I have a followup question: my background is C and in Wolfram 
Mathematica, so my knowledge of templates is limited to trivial 
examples in C++, like:

template <class T>
const T& min(const T& lhs, const T& rhs)
{
     return lhs < rhs ? lhs : rhs;
}

where the template argument is a type, and the function does the 
same job for different types.

It seems to me that when programming in D templates are something 
more powerful, is it correct of thinking of them as some argument 
which is known at compile time? Is this misleading?

Many thanks again for your replies!


More information about the Digitalmars-d-learn mailing list