www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Compile-Time Function Parameters That Aren't Types?

reply Kyle Ingraham <kyle kyleingraham.com> writes:
I was reading the code for the DCV library and came across this 
function: 
https://github.com/libmir/dcv/blob/master/source/dcv/imgproc/color.d#L128

Here is a shortened form:
[return type] rgbbgr2gray(bool isBGR, V)([run-time 
parameters]){[implementation]}

and an example call:
rgbbgr2gray!(true, [a type])([run-time arguments])

The part that got my attention was `bool isBGR`. I was under the 
impression that compile-time or template parameters were only for 
types. Where would one find information on this in the D spec? 
Why would one write a function this way?
Feb 23 2021
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 24 February 2021 at 03:52:57 UTC, Kyle Ingraham 
wrote:
 The part that got my attention was `bool isBGR`. I was under 
 the impression that compile-time or template parameters were 
 only for types.
No, you can pass almost anything to them. https://dlang.org/spec/template.html#template_value_parameter and other surrounding sections
 Why would one write a function this way?
To specialize on information known at compile time. It will also call functions as-needed to get that value all at compile time.
Feb 23 2021
parent Kyle Ingraham <kyle kyleingraham.com> writes:
On Wednesday, 24 February 2021 at 03:57:37 UTC, Adam D. Ruppe 
wrote:
 On Wednesday, 24 February 2021 at 03:52:57 UTC, Kyle Ingraham 
 wrote:
 The part that got my attention was `bool isBGR`. I was under 
 the impression that compile-time or template parameters were 
 only for types.
No, you can pass almost anything to them. https://dlang.org/spec/template.html#template_value_parameter
Much appreciated. This is exactly what I wanted to take a look at.
 and other surrounding sections

 Why would one write a function this way?
To specialize on information known at compile time. It will also call functions as-needed to get that value all at compile time.
That brings it all together. Types aren't the only thing one would want to use to specialize. Thank you for the explanation. I'm making my way in from interpreted languages so templates are a still unfamiliar way to solve problems.
Feb 23 2021
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Feb 24, 2021 at 03:52:57AM +0000, Kyle Ingraham via Digitalmars-d-learn
wrote:
[...]
 I was under the impression that compile-time or template parameters
 were only for types.
In D, template parameters can take not only types, but almost any type (provided they are constructible at compile-time). Basically, D views template parameters as *compile-time parameters*; i.e., they are treated like ordinary parameters, except that they happen to be passed at compile-time.
 [...] Why would one write a function this way?
Usually it's when there's a decision that needs to be made at compile-time (or desirable to be made at compile-time for whatever reason). For example, if there are two very different branches of code that should run depending on the value of parameter, and user code is expected to want only one or the other code path, so fixing the code path at compile-time may be advantageous. D's operator overloading is one example of this. It takes a compile-time string containing the operator, which lets the implementor choose whether to implement multiple operator overloads separately, or grouped together in a common implementation. E.g.: struct MyObject { private int impl; /** * Example of separate implementations for operators: */ MyObject opBinary(string op)(MyObject b) if (op == "*") { return ... /* multiplication algorithm here */; } /// ditto MyObject opBinary(string op)(MyObject b) if (op == "/") { return ... /* division algorithm here */; } /** * Example of multiple operators sharing a common * implementation. */ MyObject opBinary(string op)(MyObject b) if (op == "+" || op == "-") { // Use mixin to implement both operators at // once. Avoids excessive boilerplate. return MyObject(mixin("impl" ~ op ~ "b.impl")); } } Passing the operator as a compile-time parameter gives the flexibility to implement different operators separately, or together with a common implementation, or some combination of both as in the above example. T -- Real men don't take backups. They put their source on a public FTP-server and let the world mirror it. -- Linus Torvalds
Feb 23 2021
parent Kyle Ingraham <kyle kyleingraham.com> writes:
On Wednesday, 24 February 2021 at 06:18:02 UTC, H. S. Teoh wrote:
 Usually it's when there's a decision that needs to be made at 
 compile-time (or desirable to be made at compile-time for 
 whatever reason).  For example, if there are two very different 
 branches of code that should run depending on the value of 
 parameter, and user code is expected to want only one or the 
 other code path, so fixing the code path at compile-time may be 
 advantageous.

 D's operator overloading is one example of this.  It takes a 
 compile-time string containing the operator, which lets the 
 implementor choose whether to implement multiple operator 
 overloads separately, or grouped together in a common 
 implementation. E.g.:
Thank you for the additional clarification with a new example. Compile-time parameters are indeed a powerful tool.
Feb 24 2021
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 2/23/21 7:52 PM, Kyle Ingraham wrote:

 Where would one find information on this
There are Point and Polygon struct templates on the following page where one can pick e.g. the dimension (e.g. three dimensional space) by a size_t template parameter. http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.value%20template%20parameter Ali
Feb 24 2021
parent Kyle Ingraham <kyle kyleingraham.com> writes:
On Wednesday, 24 February 2021 at 20:15:08 UTC, Ali Çehreli wrote:
 On 2/23/21 7:52 PM, Kyle Ingraham wrote:

 Where would one find information on this
There are Point and Polygon struct templates on the following page where one can pick e.g. the dimension (e.g. three dimensional space) by a size_t template parameter. http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.value%20template%20parameter Ali
Thank you very much Ali. This is another great example. Your book has been most helpful!
Feb 25 2021