Partial argument specification

Denis Koroskin 2korden at gmail.com
Fri Oct 17 04:51:45 PDT 2008


Lars Kyllingstad <public at kyllingen.nospamnet> писал(а) в своём письме Fri,  
17 Oct 2008 15:27:52 +0400:

> Hello,
>
> There is a feature I would very much like to see in D. I don't know if  
> it has been discussed before, or whether is's even possible, but I'm  
> just going to throw it out here. Please tell me what you think.
>
> Suppose you have a function that takes a certain number of arguments, say
>
>    creal f(real x, int i);
>
> Then it would be neat if one could specify just some of the arguments,  
> and have the result be a pointer to a function that takes the remaining  
> arguments. To clarify, the type of
>
>    f(real, 2)
>
> would then be
>
>    creal function(real)
>

You *have to* store an "int i" parameter somewhere unless you want to be a  
compile time constant. Use a template in this case. Alternatively use a  
struct or class wrapper. Struct won't allocate heap, class gives more  
flexibility. Delegates allow contruction on-fly without (even more  
flexibility) at the cost of additional overhead.

I'd go with delegates unless the performance degrade drastically.

// use of delegates:
creal delegate(real) f2 = (real x){ return f(x, 2); }
real x = ...;
creal result = f2(x); // same as f(x, 2);

// use of a class wrapper:
class F
{
     this(int i) { this.i = i; }
     creal opCall(real x) { return f(x, i); }
     private int i;
}

F f2 = new F(2);
real x = ...;
creal result = f2(x); // same as f(x, 2);

// struct wrapper
struct F2
{
     int i;
     creal opCall(real x) { return f(x, i); }
}

F2 f2 = { 2 };
real x = ...;
creal result = f2(x);

> Why would this be nice? As an example, say you have a function that  
> calculates the derivative of another function at a certain point:
>
>    real derivative(real function(real), real z);
>
> With the above notation I can use this for functions of several  
> variables:
>
>    real f(real x, real y) { ... };
>    auto dfdx = derivative( f(real, 1.23), 4.56 );
>
> As an added bonus, I can even differentiate with respect to y:
>
>    auto dfdy = derivative( f(1.23, real), 4.56 );
>
> Already, there are several ways to do similar things, but in my opinion  
> they are not as good:
>
> 1. Use templates
> Nice, but only works when the pre-specified arguments are known at  
> compile time. (Or is there some trick I don't know about?)
>
> 2. Use functors
> This works, but leads to worse performance and is in my opinion less  
> elegant. One has to type a lot of code just to define simple functions.
>
> 3. Use wrapper functions
> Same problems as (2), and also leads to use of global variables.
>
> 4. The GSL way: Pass remaining arguments in a void* pointer.
> Example:
>
>    real derivative(real function(real, void*), real z);
>
> IMO, this is UGLY, not to mention un-D-ish.
>
>
> I mainly use D for numerical computations, hence the examples above. But  
> I'm sure there are many other uses for such a feature. What do you think?
>
> -Lars




More information about the Digitalmars-d mailing list