digitalmars.D - Partial argument specification
- Lars Kyllingstad (37/37) Oct 17 2008 Hello,
- Lutger (1/1) Oct 17 2008 I think this is possible using std.bind
- Denis Koroskin (31/69) Oct 17 2008 You *have to* store an "int i" parameter somewhere unless you want to be...
- Bill Baxter (59/59) Oct 17 2008 T24gRnJpLCBPY3QgMTcsIDIwMDggYXQgODo1MSBQTSwgRGVuaXMgS29yb3NraW4gPDJrb3Jk...
- Robert Fraser (2/108) Oct 17 2008 I think all he was asking for is currying, which is indeed possible.
- Bill Baxter (73/73) Oct 17 2008 T24gU2F0LCBPY3QgMTgsIDIwMDggYXQgNzowNSBBTSwgUm9iZXJ0IEZyYXNlcgo8ZnJhc2Vy...
- Lars Kyllingstad (11/138) Oct 18 2008 I didn't know what currying was, so I checked out the Wikipedia article....
- downs (6/66) Oct 17 2008 How about an implicit functor?
- Lars Kyllingstad (7/78) Oct 18 2008 Ok, but say I want to do this several times:
- downs (3/89) Oct 20 2008 Yes, but how could it possibly do that?
- Lars Kyllingstad (18/107) Oct 20 2008 I'm not sure I understand. Wouldn't it be possible to do something like
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
Oct 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
Oct 17 2008
T24gRnJpLCBPY3QgMTcsIDIwMDggYXQgODo1MSBQTSwgRGVuaXMgS29yb3NraW4gPDJrb3JkZW5A Z21haWwuY29tPiB3cm90ZToKPiBMYXJzIEt5bGxpbmdzdGFkIDxwdWJsaWNAa3lsbGluZ2VuLm5v c3BhbW5ldD4g0MnTwcwowSkg1yDT18+jzSDQydPYzcUgRnJpLAo+IDE3IE9jdCAyMDA4IDE1OjI3 OjUyICswNDAwOgo+Cj4+IEhlbGxvLAo+Pgo+PiBUaGVyZSBpcyBhIGZlYXR1cmUgSSB3b3VsZCB2 ZXJ5IG11Y2ggbGlrZSB0byBzZWUgaW4gRC4gSSBkb24ndCBrbm93IGlmIGl0Cj4+IGhhcyBiZWVu IGRpc2N1c3NlZCBiZWZvcmUsIG9yIHdoZXRoZXIgaXMncyBldmVuIHBvc3NpYmxlLCBidXQgSSdt IGp1c3QgZ29pbmcKPj4gdG8gdGhyb3cgaXQgb3V0IGhlcmUuIFBsZWFzZSB0ZWxsIG1lIHdoYXQg eW91IHRoaW5rLgo+Pgo+PiBTdXBwb3NlIHlvdSBoYXZlIGEgZnVuY3Rpb24gdGhhdCB0YWtlcyBh IGNlcnRhaW4gbnVtYmVyIG9mIGFyZ3VtZW50cywgc2F5Cj4+Cj4+ICAgY3JlYWwgZihyZWFsIHgs IGludCBpKTsKPj4KPj4gVGhlbiBpdCB3b3VsZCBiZSBuZWF0IGlmIG9uZSBjb3VsZCBzcGVjaWZ5 IGp1c3Qgc29tZSBvZiB0aGUgYXJndW1lbnRzLCBhbmQKPj4gaGF2ZSB0aGUgcmVzdWx0IGJlIGEg cG9pbnRlciB0byBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgdGhlIHJlbWFpbmluZwo+PiBhcmd1bWVu dHMuIFRvIGNsYXJpZnksIHRoZSB0eXBlIG9mCj4+Cj4+ICAgZihyZWFsLCAyKQo+Pgo+PiB3b3Vs ZCB0aGVuIGJlCj4+Cj4+ICAgY3JlYWwgZnVuY3Rpb24ocmVhbCkKPj4KPgo+IFlvdSAqaGF2ZSB0 byogc3RvcmUgYW4gImludCBpIiBwYXJhbWV0ZXIgc29tZXdoZXJlIHVubGVzcyB5b3Ugd2FudCB0 byBiZSBhCj4gY29tcGlsZSB0aW1lIGNvbnN0YW50LiBVc2UgYSB0ZW1wbGF0ZSBpbiB0aGlzIGNh c2UuIEFsdGVybmF0aXZlbHkgdXNlIGEKPiBzdHJ1Y3Qgb3IgY2xhc3Mgd3JhcHBlci4gU3RydWN0 IHdvbid0IGFsbG9jYXRlIGhlYXAsIGNsYXNzIGdpdmVzIG1vcmUKPiBmbGV4aWJpbGl0eS4gRGVs ZWdhdGVzIGFsbG93IGNvbnRydWN0aW9uIG9uLWZseSB3aXRob3V0IChldmVuIG1vcmUKPiBmbGV4 aWJpbGl0eSkgYXQgdGhlIGNvc3Qgb2YgYWRkaXRpb25hbCBvdmVyaGVhZC4KPgo+IEknZCBnbyB3 aXRoIGRlbGVnYXRlcyB1bmxlc3MgdGhlIHBlcmZvcm1hbmNlIGRlZ3JhZGUgZHJhc3RpY2FsbHku Cj4KPiAvLyB1c2Ugb2YgZGVsZWdhdGVzOgo+IGNyZWFsIGRlbGVnYXRlKHJlYWwpIGYyID0gKHJl YWwgeCl7IHJldHVybiBmKHgsIDIpOyB9Cj4gcmVhbCB4ID0gLi4uOwo+IGNyZWFsIHJlc3VsdCA9 IGYyKHgpOyAvLyBzYW1lIGFzIGYoeCwgMik7Cj4KPiAvLyB1c2Ugb2YgYSBjbGFzcyB3cmFwcGVy Ogo+IGNsYXNzIEYKPiB7Cj4gICAgdGhpcyhpbnQgaSkgeyB0aGlzLmkgPSBpOyB9Cj4gICAgY3Jl YWwgb3BDYWxsKHJlYWwgeCkgeyByZXR1cm4gZih4LCBpKTsgfQo+ICAgIHByaXZhdGUgaW50IGk7 Cj4gfQo+Cj4gRiBmMiA9IG5ldyBGKDIpOwo+IHJlYWwgeCA9IC4uLjsKPiBjcmVhbCByZXN1bHQg PSBmMih4KTsgLy8gc2FtZSBhcyBmKHgsIDIpOwo+Cj4gLy8gc3RydWN0IHdyYXBwZXIKPiBzdHJ1 Y3QgRjIKPiB7Cj4gICAgaW50IGk7Cj4gICAgY3JlYWwgb3BDYWxsKHJlYWwgeCkgeyByZXR1cm4g Zih4LCBpKTsgfQo+IH0KPgo+IEYyIGYyID0geyAyIH07Cj4gcmVhbCB4ID0gLi4uOwo+IGNyZWFs IHJlc3VsdCA9IGYyKHgpOwo+Cj4+IFdoeSB3b3VsZCB0aGlzIGJlIG5pY2U/IEFzIGFuIGV4YW1w bGUsIHNheSB5b3UgaGF2ZSBhIGZ1bmN0aW9uIHRoYXQKPj4gY2FsY3VsYXRlcyB0aGUgZGVyaXZh dGl2ZSBvZiBhbm90aGVyIGZ1bmN0aW9uIGF0IGEgY2VydGFpbiBwb2ludDoKPj4KPj4gICByZWFs IGRlcml2YXRpdmUocmVhbCBmdW5jdGlvbihyZWFsKSwgcmVhbCB6KTsKPj4KPj4gV2l0aCB0aGUg YWJvdmUgbm90YXRpb24gSSBjYW4gdXNlIHRoaXMgZm9yIGZ1bmN0aW9ucyBvZiBzZXZlcmFsIHZh cmlhYmxlczoKPj4KPj4gICByZWFsIGYocmVhbCB4LCByZWFsIHkpIHsgLi4uIH07Cj4+ICAgYXV0 byBkZmR4ID0gZGVyaXZhdGl2ZSggZihyZWFsLCAxLjIzKSwgNC41NiApOwo+Pgo+PiBBcyBhbiBh ZGRlZCBib251cywgSSBjYW4gZXZlbiBkaWZmZXJlbnRpYXRlIHdpdGggcmVzcGVjdCB0byB5Ogo+ Pgo+PiAgIGF1dG8gZGZkeSA9IGRlcml2YXRpdmUoIGYoMS4yMywgcmVhbCksIDQuNTYgKTsKPj4K Pj4gQWxyZWFkeSwgdGhlcmUgYXJlIHNldmVyYWwgd2F5cyB0byBkbyBzaW1pbGFyIHRoaW5ncywg YnV0IGluIG15IG9waW5pb24KPj4gdGhleSBhcmUgbm90IGFzIGdvb2Q6Cj4+Cj4+IDEuIFVzZSB0 ZW1wbGF0ZXMKPj4gTmljZSwgYnV0IG9ubHkgd29ya3Mgd2hlbiB0aGUgcHJlLXNwZWNpZmllZCBh cmd1bWVudHMgYXJlIGtub3duIGF0IGNvbXBpbGUKPj4gdGltZS4gKE9yIGlzIHRoZXJlIHNvbWUg dHJpY2sgSSBkb24ndCBrbm93IGFib3V0PykKPj4KPj4gMi4gVXNlIGZ1bmN0b3JzCj4+IFRoaXMg d29ya3MsIGJ1dCBsZWFkcyB0byB3b3JzZSBwZXJmb3JtYW5jZSBhbmQgaXMgaW4gbXkgb3Bpbmlv biBsZXNzCj4+IGVsZWdhbnQuIE9uZSBoYXMgdG8gdHlwZSBhIGxvdCBvZiBjb2RlIGp1c3QgdG8g ZGVmaW5lIHNpbXBsZSBmdW5jdGlvbnMuCj4+Cj4+IDMuIFVzZSB3cmFwcGVyIGZ1bmN0aW9ucwo+ PiBTYW1lIHByb2JsZW1zIGFzICgyKSwgYW5kIGFsc28gbGVhZHMgdG8gdXNlIG9mIGdsb2JhbCB2 YXJpYWJsZXMuCj4+Cj4+IDQuIFRoZSBHU0wgd2F5OiBQYXNzIHJlbWFpbmluZyBhcmd1bWVudHMg aW4gYSB2b2lkKiBwb2ludGVyLgo+PiBFeGFtcGxlOgo+Pgo+PiAgIHJlYWwgZGVyaXZhdGl2ZShy ZWFsIGZ1bmN0aW9uKHJlYWwsIHZvaWQqKSwgcmVhbCB6KTsKPj4KPj4gSU1PLCB0aGlzIGlzIFVH TFksIG5vdCB0byBtZW50aW9uIHVuLUQtaXNoLgo+Pgo+Pgo+PiBJIG1haW5seSB1c2UgRCBmb3Ig bnVtZXJpY2FsIGNvbXB1dGF0aW9ucywgaGVuY2UgdGhlIGV4YW1wbGVzIGFib3ZlLiBCdXQKPj4g SSdtIHN1cmUgdGhlcmUgYXJlIG1hbnkgb3RoZXIgdXNlcyBmb3Igc3VjaCBhIGZlYXR1cmUuIFdo YXQgZG8geW91IHRoaW5rPwoKU291bmRzIGxpa2Ugd2hhdCB5b3Ugd2FudCBpcyBwYXJ0aWFsIGV2 YWx1YXRpb24KKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUGFydGlhbF9ldmFsdWF0aW9u KSBidXQgZG9uZSBhdCBydW4KdGltZS4KVGhhdCdzIG9ubHkgZ29pbmcgdG8gYmUgcG9zc2libGUg aWYgdGhlcmUncyBhIGNvbXBpbGVyIGJ1aWx0IGludG8gdGhlCnJ1bnRpbWUuICBTbyBub3QgcG9z c2libGUgY3VycmVudGx5LgoKLS1iYgo=
Oct 17 2008
Bill Baxter wrote:On Fri, Oct 17, 2008 at 8:51 PM, Denis Koroskin <2korden gmail.com> wrote:I think all he was asking for is currying, which is indeed possible.Lars Kyllingstad <public kyllingen.nospamnet> () ϣ Fri, 17 Oct 2008 15:27:52 +0400: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. --bbHello, 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?
Oct 17 2008
T24gU2F0LCBPY3QgMTgsIDIwMDggYXQgNzowNSBBTSwgUm9iZXJ0IEZyYXNlcgo8ZnJhc2Vyb2Z0 aGVuaWdodEBnbWFpbC5jb20+IHdyb3RlOgo+IEJpbGwgQmF4dGVyIHdyb3RlOgo+Pgo+PiBPbiBG cmksIE9jdCAxNywgMjAwOCBhdCA4OjUxIFBNLCBEZW5pcyBLb3Jvc2tpbiA8MmtvcmRlbkBnbWFp bC5jb20+IHdyb3RlOgo+Pj4KPj4+IExhcnMgS3lsbGluZ3N0YWQgPHB1YmxpY0BreWxsaW5nZW4u bm9zcGFtbmV0PiDQydPBzCjBKSDXINPXz6PNINDJ09jNxQo+Pj4gRnJpLAo+Pj4gMTcgT2N0IDIw MDggMTU6Mjc6NTIgKzA0MDA6Cj4+Pgo+Pj4+IEhlbGxvLAo+Pj4+Cj4+Pj4gVGhlcmUgaXMgYSBm ZWF0dXJlIEkgd291bGQgdmVyeSBtdWNoIGxpa2UgdG8gc2VlIGluIEQuIEkgZG9uJ3Qga25vdyBp Zgo+Pj4+IGl0Cj4+Pj4gaGFzIGJlZW4gZGlzY3Vzc2VkIGJlZm9yZSwgb3Igd2hldGhlciBpcydz IGV2ZW4gcG9zc2libGUsIGJ1dCBJJ20ganVzdAo+Pj4+IGdvaW5nCj4+Pj4gdG8gdGhyb3cgaXQg b3V0IGhlcmUuIFBsZWFzZSB0ZWxsIG1lIHdoYXQgeW91IHRoaW5rLgo+Pj4+Cj4+Pj4gU3VwcG9z ZSB5b3UgaGF2ZSBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYSBjZXJ0YWluIG51bWJlciBvZiBhcmd1 bWVudHMsCj4+Pj4gc2F5Cj4+Pj4KPj4+PiAgY3JlYWwgZihyZWFsIHgsIGludCBpKTsKPj4+Pgo+ Pj4+IFRoZW4gaXQgd291bGQgYmUgbmVhdCBpZiBvbmUgY291bGQgc3BlY2lmeSBqdXN0IHNvbWUg b2YgdGhlIGFyZ3VtZW50cywKPj4+PiBhbmQKPj4+PiBoYXZlIHRoZSByZXN1bHQgYmUgYSBwb2lu dGVyIHRvIGEgZnVuY3Rpb24gdGhhdCB0YWtlcyB0aGUgcmVtYWluaW5nCj4+Pj4gYXJndW1lbnRz LiBUbyBjbGFyaWZ5LCB0aGUgdHlwZSBvZgo+Pj4+Cj4+Pj4gIGYocmVhbCwgMikKPj4+Pgo+Pj4+ IHdvdWxkIHRoZW4gYmUKPj4+Pgo+Pj4+ICBjcmVhbCBmdW5jdGlvbihyZWFsKQo+Pj4+Cj4+PiBZ b3UgKmhhdmUgdG8qIHN0b3JlIGFuICJpbnQgaSIgcGFyYW1ldGVyIHNvbWV3aGVyZSB1bmxlc3Mg eW91IHdhbnQgdG8gYmUKPj4+IGEKPj4+IGNvbXBpbGUgdGltZSBjb25zdGFudC4gVXNlIGEgdGVt cGxhdGUgaW4gdGhpcyBjYXNlLiBBbHRlcm5hdGl2ZWx5IHVzZSBhCj4+PiBzdHJ1Y3Qgb3IgY2xh c3Mgd3JhcHBlci4gU3RydWN0IHdvbid0IGFsbG9jYXRlIGhlYXAsIGNsYXNzIGdpdmVzIG1vcmUK Pj4+IGZsZXhpYmlsaXR5LiBEZWxlZ2F0ZXMgYWxsb3cgY29udHJ1Y3Rpb24gb24tZmx5IHdpdGhv dXQgKGV2ZW4gbW9yZQo+Pj4gZmxleGliaWxpdHkpIGF0IHRoZSBjb3N0IG9mIGFkZGl0aW9uYWwg b3ZlcmhlYWQuCj4+Pgo+Pj4gSSdkIGdvIHdpdGggZGVsZWdhdGVzIHVubGVzcyB0aGUgcGVyZm9y bWFuY2UgZGVncmFkZSBkcmFzdGljYWxseS4KPj4+Cj4+PiAvLyB1c2Ugb2YgZGVsZWdhdGVzOgo+ Pj4gY3JlYWwgZGVsZWdhdGUocmVhbCkgZjIgPSAocmVhbCB4KXsgcmV0dXJuIGYoeCwgMik7IH0K Pj4+IHJlYWwgeCA9IC4uLjsKPj4+IGNyZWFsIHJlc3VsdCA9IGYyKHgpOyAvLyBzYW1lIGFzIGYo eCwgMik7Cj4+Pgo+Pj4gLy8gdXNlIG9mIGEgY2xhc3Mgd3JhcHBlcjoKPj4+IGNsYXNzIEYKPj4+ IHsKPj4+ICAgdGhpcyhpbnQgaSkgeyB0aGlzLmkgPSBpOyB9Cj4+PiAgIGNyZWFsIG9wQ2FsbChy ZWFsIHgpIHsgcmV0dXJuIGYoeCwgaSk7IH0KPj4+ICAgcHJpdmF0ZSBpbnQgaTsKPj4+IH0KPj4+ Cj4+PiBGIGYyID0gbmV3IEYoMik7Cj4+PiByZWFsIHggPSAuLi47Cj4+PiBjcmVhbCByZXN1bHQg PSBmMih4KTsgLy8gc2FtZSBhcyBmKHgsIDIpOwo+Pj4KPj4+IC8vIHN0cnVjdCB3cmFwcGVyCj4+ PiBzdHJ1Y3QgRjIKPj4+IHsKPj4+ICAgaW50IGk7Cj4+PiAgIGNyZWFsIG9wQ2FsbChyZWFsIHgp IHsgcmV0dXJuIGYoeCwgaSk7IH0KPj4+IH0KPj4+Cj4+PiBGMiBmMiA9IHsgMiB9Owo+Pj4gcmVh bCB4ID0gLi4uOwo+Pj4gY3JlYWwgcmVzdWx0ID0gZjIoeCk7Cj4+Pgo+Pj4+IFdoeSB3b3VsZCB0 aGlzIGJlIG5pY2U/IEFzIGFuIGV4YW1wbGUsIHNheSB5b3UgaGF2ZSBhIGZ1bmN0aW9uIHRoYXQK Pj4+PiBjYWxjdWxhdGVzIHRoZSBkZXJpdmF0aXZlIG9mIGFub3RoZXIgZnVuY3Rpb24gYXQgYSBj ZXJ0YWluIHBvaW50Ogo+Pj4+Cj4+Pj4gIHJlYWwgZGVyaXZhdGl2ZShyZWFsIGZ1bmN0aW9uKHJl YWwpLCByZWFsIHopOwo+Pj4+Cj4+Pj4gV2l0aCB0aGUgYWJvdmUgbm90YXRpb24gSSBjYW4gdXNl IHRoaXMgZm9yIGZ1bmN0aW9ucyBvZiBzZXZlcmFsCj4+Pj4gdmFyaWFibGVzOgo+Pj4+Cj4+Pj4g IHJlYWwgZihyZWFsIHgsIHJlYWwgeSkgeyAuLi4gfTsKPj4+PiAgYXV0byBkZmR4ID0gZGVyaXZh dGl2ZSggZihyZWFsLCAxLjIzKSwgNC41NiApOwo+Pj4+Cj4+Pj4gQXMgYW4gYWRkZWQgYm9udXMs IEkgY2FuIGV2ZW4gZGlmZmVyZW50aWF0ZSB3aXRoIHJlc3BlY3QgdG8geToKPj4+Pgo+Pj4+ICBh dXRvIGRmZHkgPSBkZXJpdmF0aXZlKCBmKDEuMjMsIHJlYWwpLCA0LjU2ICk7Cj4+Pj4KPj4+PiBB bHJlYWR5LCB0aGVyZSBhcmUgc2V2ZXJhbCB3YXlzIHRvIGRvIHNpbWlsYXIgdGhpbmdzLCBidXQg aW4gbXkgb3Bpbmlvbgo+Pj4+IHRoZXkgYXJlIG5vdCBhcyBnb29kOgo+Pj4+Cj4+Pj4gMS4gVXNl IHRlbXBsYXRlcwo+Pj4+IE5pY2UsIGJ1dCBvbmx5IHdvcmtzIHdoZW4gdGhlIHByZS1zcGVjaWZp ZWQgYXJndW1lbnRzIGFyZSBrbm93biBhdAo+Pj4+IGNvbXBpbGUKPj4+PiB0aW1lLiAoT3IgaXMg dGhlcmUgc29tZSB0cmljayBJIGRvbid0IGtub3cgYWJvdXQ/KQo+Pj4+Cj4+Pj4gMi4gVXNlIGZ1 bmN0b3JzCj4+Pj4gVGhpcyB3b3JrcywgYnV0IGxlYWRzIHRvIHdvcnNlIHBlcmZvcm1hbmNlIGFu ZCBpcyBpbiBteSBvcGluaW9uIGxlc3MKPj4+PiBlbGVnYW50LiBPbmUgaGFzIHRvIHR5cGUgYSBs b3Qgb2YgY29kZSBqdXN0IHRvIGRlZmluZSBzaW1wbGUgZnVuY3Rpb25zLgo+Pj4+Cj4+Pj4gMy4g VXNlIHdyYXBwZXIgZnVuY3Rpb25zCj4+Pj4gU2FtZSBwcm9ibGVtcyBhcyAoMiksIGFuZCBhbHNv IGxlYWRzIHRvIHVzZSBvZiBnbG9iYWwgdmFyaWFibGVzLgo+Pj4+Cj4+Pj4gNC4gVGhlIEdTTCB3 YXk6IFBhc3MgcmVtYWluaW5nIGFyZ3VtZW50cyBpbiBhIHZvaWQqIHBvaW50ZXIuCj4+Pj4gRXhh bXBsZToKPj4+Pgo+Pj4+ICByZWFsIGRlcml2YXRpdmUocmVhbCBmdW5jdGlvbihyZWFsLCB2b2lk KiksIHJlYWwgeik7Cj4+Pj4KPj4+PiBJTU8sIHRoaXMgaXMgVUdMWSwgbm90IHRvIG1lbnRpb24g dW4tRC1pc2guCj4+Pj4KPj4+Pgo+Pj4+IEkgbWFpbmx5IHVzZSBEIGZvciBudW1lcmljYWwgY29t cHV0YXRpb25zLCBoZW5jZSB0aGUgZXhhbXBsZXMgYWJvdmUuIEJ1dAo+Pj4+IEknbSBzdXJlIHRo ZXJlIGFyZSBtYW55IG90aGVyIHVzZXMgZm9yIHN1Y2ggYSBmZWF0dXJlLiBXaGF0IGRvIHlvdQo+ Pj4+IHRoaW5rPwo+Pgo+PiBTb3VuZHMgbGlrZSB3aGF0IHlvdSB3YW50IGlzIHBhcnRpYWwgZXZh bHVhdGlvbgo+PiAoaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QYXJ0aWFsX2V2YWx1YXRp b24pIGJ1dCBkb25lIGF0IHJ1bgo+PiB0aW1lLgo+PiBUaGF0J3Mgb25seSBnb2luZyB0byBiZSBw b3NzaWJsZSBpZiB0aGVyZSdzIGEgY29tcGlsZXIgYnVpbHQgaW50byB0aGUKPj4gcnVudGltZS4g IFNvIG5vdCBwb3NzaWJsZSBjdXJyZW50bHkuCj4+Cj4+IC0tYmIKPgo+IEkgdGhpbmsgYWxsIGhl IHdhcyBhc2tpbmcgZm9yIGlzIGN1cnJ5aW5nLCB3aGljaCBpcyBpbmRlZWQgcG9zc2libGUuCgpZ b3UgbWVhbiB0aGlzIGtpbmQgb2Ygc29sdXRpb24gOgpodHRwOi8vd2ViLm1pdC5lZHUvZF92MS4w MjAvaHRtbC9kL3RlbXBsYXRlLmh0bWwgIChzZWFyY2ggZm9yICJDdXJyeSIKb24gdGhlIHBhZ2Up ID8KCk5vLCBoZSBzcGVjaWZpY2FsbHkgc2FpZCBoZSBkaWRuJ3Qgd2FudCB0aGUgb3ZlcmhlYWQg b2YgY2FycnlpbmcKYXJvdW5kIHRoZSBhcmd1bWVudHMuICBUaGF0J3MgYmFzaWNhbGx5IHRoZSAi ZnVuY3RvciIgc29sdXRpb24gaGUKbWVudGlvbnMuICBPbmx5IGl0IHJldHVybnMgYSBkZWxlZ2F0 ZSB0byB0aGUgZnVuY3RvcidzIG1ldGhvZCByYXRoZXIKdGhhbiByZXR1cm5pbmcgdGhlIGZ1bmN0 b3IgaXRzZWxmLgoKQnV0IHRoYXQgaXMgdGhlIGNsb3Nlc3QgeW91IGNhbiBnZXQuCgotLWJiCg==
Oct 17 2008
Bill Baxter wrote:On Sat, Oct 18, 2008 at 7:05 AM, Robert Fraser <fraserofthenight gmail.com> wrote: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. -LarsBill Baxter wrote: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.On Fri, Oct 17, 2008 at 8:51 PM, Denis Koroskin <2korden gmail.com> wrote:I think all he was asking for is currying, which is indeed possible.Lars Kyllingstad <public kyllingen.nospamnet> () ϣ Fri, 17 Oct 2008 15:27:52 +0400: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. --bbHello, 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?
Oct 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? -LarsHow 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 :)
Oct 17 2008
downs wrote:Lars Kyllingstad wrote: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? -LarsHello, 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? -LarsHow 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 :)
Oct 18 2008
Lars Kyllingstad wrote:downs wrote: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!Lars Kyllingstad wrote: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? -LarsHello, 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? -LarsHow 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 :)
Oct 20 2008
downs wrote:Lars Kyllingstad wrote:I'm not sure I understand. Wouldn't it be possible to do something like this: struct FunctionWrapper { ... SomeType opCall(...) { ... } } and then have /rfix/ (or bind) return a FunctionWrapper? Of course it would have to return by value instead of returning a pointer, since whatever is pointed to will be lost on scope exit. If there are no pointers to stack data inside the struct there shouldn't be a problem. Don't know if it's possible to avoid this, though. But perhaps the cost of returning a (possibly large) struct by value would outweigh the cost of calling functors on the heap? I guess it depends on how many times a single functor is called, compared to how often a new one is created. -Larsdowns wrote: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!Lars Kyllingstad wrote: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? -LarsHello, 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? -LarsHow 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 :)
Oct 20 2008