Partial argument specification

Robert Fraser fraserofthenight at gmail.com
Fri Oct 17 15:05:02 PDT 2008


Bill Baxter wrote:
> On Fri, Oct 17, 2008 at 8:51 PM, Denis Koroskin <2korden at gmail.com> wrote:
>> 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?
> 
> Sounds like what you want is partial evaluation
> (http://en.wikipedia.org/wiki/Partial_evaluation) but done at run
> time.
> That's only going to be possible if there's a compiler built into the
> runtime.  So not possible currently.
> 
> --bb

I think all he was asking for is currying, which is indeed possible.



More information about the Digitalmars-d mailing list