View mode: basic / threaded / horizontal-split · Log in · Help
October 17, 2008
Partial argument specification
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
Re: Partial argument specification
I think this is possible using std.bind
October 17, 2008
Re: Partial argument specification
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
Re: Partial argument specification
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
Re: Partial argument specification
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
Re: Partial argument specification
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
Re: Partial argument specification
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
Re: Partial argument specification
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
Re: Partial argument specification
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
Re: Partial argument specification
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
Top | Discussion index | About this forum | D home