Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Kyllingstad | I think this is possible using std.bind |
October 17, 2008 Re: Partial argument specification | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Kyllingstad | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Fraser | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Kyllingstad | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to downs | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Kyllingstad | 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!
|
Copyright © 1999-2021 by the D Language Foundation