Jump to page: 1 2
Thread overview
Partial argument specification
Oct 17, 2008
Lars Kyllingstad
Oct 17, 2008
Lutger
Oct 17, 2008
Denis Koroskin
Oct 17, 2008
Bill Baxter
Oct 17, 2008
Robert Fraser
Oct 17, 2008
Bill Baxter
Oct 18, 2008
Lars Kyllingstad
Oct 18, 2008
downs
Oct 18, 2008
Lars Kyllingstad
Oct 20, 2008
downs
Oct 20, 2008
Lars Kyllingstad
October 17, 2008
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)

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
October 17, 2008
I think this is possible using std.bind
October 17, 2008
Lars Kyllingstad <public@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

October 17, 2008
On Fri, Oct 17, 2008 at 8:51 PM, Denis Koroskin <2korden@gmail.com> wrote:
> Lars Kyllingstad <public@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

October 17, 2008
Bill Baxter wrote:
> On Fri, Oct 17, 2008 at 8:51 PM, Denis Koroskin <2korden@gmail.com> wrote:
>> Lars Kyllingstad <public@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.
October 17, 2008
On Sat, Oct 18, 2008 at 7:05 AM, Robert Fraser <fraserofthenight@gmail.com> wrote:
> Bill Baxter wrote:
>>
>> On Fri, Oct 17, 2008 at 8:51 PM, Denis Koroskin <2korden@gmail.com> wrote:
>>>
>>> Lars Kyllingstad <public@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.

You mean this kind of solution : http://web.mit.edu/d_v1.020/html/d/template.html  (search for "Curry" on the page) ?

No, he specifically said he didn't want the overhead of carrying around the arguments.  That's basically the "functor" solution he mentions.  Only it returns a delegate to the functor's method rather than returning the functor itself.

But that is the closest you can get.

--bb

October 18, 2008
Lars Kyllingstad wrote:
> 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)
> 
> 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

How about an implicit functor?

creal f(real x, int i);

auto f2 = bind(&f, _0, 2); // I think

auto f2 = &f /rfix/ 2; // tools version

This creates a functor on the heap, and is indeed slower, but it's more elegant than you make it sound :)
October 18, 2008
Bill Baxter wrote:
> On Sat, Oct 18, 2008 at 7:05 AM, Robert Fraser
> <fraserofthenight@gmail.com> wrote:
>> Bill Baxter wrote:
>>> On Fri, Oct 17, 2008 at 8:51 PM, Denis Koroskin <2korden@gmail.com> wrote:
>>>> Lars Kyllingstad <public@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.
> 
> You mean this kind of solution :
> http://web.mit.edu/d_v1.020/html/d/template.html  (search for "Curry"
> on the page) ?
> 
> No, he specifically said he didn't want the overhead of carrying
> around the arguments.  That's basically the "functor" solution he
> mentions.  Only it returns a delegate to the functor's method rather
> than returning the functor itself.

I didn't know what currying was, so I checked out the Wikipedia article.  I quote:

    Intuitively, currying says "if you fix some arguments,
    you get a function of the remaining arguments".

This is exactly what I was looking for. There seems to be agreement here that this can't be done without at least a little overhead, but I still think it would be nice with a simple, intuitive syntax like the one I described. Also, I think it would fit in nicely with D2's focus on functional programming.


-Lars
October 18, 2008
downs wrote:
> Lars Kyllingstad wrote:
>> 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)
>>
>> 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
> 
> How about an implicit functor?
> 
> creal f(real x, int i);
> 
> auto f2 = bind(&f, _0, 2); // I think
> 
> auto f2 = &f /rfix/ 2; // tools version
> 
> This creates a functor on the heap, and is indeed slower, but it's more elegant than you make it sound :)

Ok, but say I want to do this several times:

  for (real y=yStart; y<=yEnd; y+=yStep)
      derivative(&f /rfix/ y, 1.23);

Would it be any faster if your /rfix/ (or a similar function) created the functor on the stack instead?

-Lars
October 20, 2008
Lars Kyllingstad wrote:
> downs wrote:
>> Lars Kyllingstad wrote:
>>> 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)
>>>
>>> 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
>>
>> How about an implicit functor?
>>
>> creal f(real x, int i);
>>
>> auto f2 = bind(&f, _0, 2); // I think
>>
>> auto f2 = &f /rfix/ 2; // tools version
>>
>> This creates a functor on the heap, and is indeed slower, but it's more elegant than you make it sound :)
> 
> Ok, but say I want to do this several times:
> 
>   for (real y=yStart; y<=yEnd; y+=yStep)
>       derivative(&f /rfix/ y, 1.23);
> 
> Would it be any faster if your /rfix/ (or a similar function) created the functor on the stack instead?
> 
> -Lars

Yes, but how could it possibly do that?

After all, then the data would become invalid on scope exit, which is exactly what we're trying to avoid!
« First   ‹ Prev
1 2