November 07, 2006 Re: 1.0 ?? [templates and currying] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | Tom S wrote: > Walter Bright wrote: >> BTW, I am considering changing the ==function and ==delegate is expressions, which you use, to the following: >> >> >> ==return gets the return type: >> >>> template Return(dg) >>> { >>> static if (is(dg R == return)) >>> alias R Return; >>> else >>> static assert(0, "argument has no return type"); >>> } >> >> ==function or ==delegate gets the parameter types as a tuple: >> >>> template Parameters(dg) >>> { >>> static if (is(dg P == function)) >>> alias P Parameters; >>> else static if (is(dg P == delegate)) >>> alias P Parameters; >>> else static if (is(dg P == P*)) >>> alias Parameters!(P) Parameters; >>> else >>> static assert(0, "argument has no parameters"); >>> } >> >> This will require some adjustment in your code. I didn't think anyone was using that stuff. Will it be an issue for you? Or should I find another way to do it? > > Whoa, That would be awesome ! I don't think anyone would mind such a change :) > I'm certainly not the only one to use that code/feature. E.g. that link I gave you is from Kirk's Pyd, which contains modified versions of my code. It's also based on efforts from Daniel Keep. But I'm sure they will gladly welcome the enhancement you're proposing :) I hate to tip over working code. I'll see if I can find another way. > One question thought: will the 'P' tuple from your example be able to remember in/out/inout/lazy modifiers ? I don't know. I'll have to work on that. |
November 07, 2006 Re: 1.0 ?? [templates and currying] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kirk McDonald | Kirk McDonald wrote:
> This would be great! The one thing we lose is the ability to get the underlying function type of a delegate.
Is that needed, though?
|
November 07, 2006 Re: 1.0 ?? [templates and currying] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > Tom S wrote: >> Whoa, That would be awesome ! I don't think anyone would mind such a >> change :) >> I'm certainly not the only one to use that code/feature. E.g. that >> link I gave you is from Kirk's Pyd, which contains modified versions >> of my code. It's also based on efforts from Daniel Keep. But I'm sure >> they will gladly welcome the enhancement you're proposing :) > > I hate to tip over working code. I'll see if I can find another way. To derive a function's return type, number of arguments, type of arguments, I had to write an external Python script that spat out a huge ugly-as-hell D source file with support for functions of N arguments. I can't speak for Kirk, but if you can do away with the need for the current way of doing things, I don't care if my code is completely broken—I'd be a happy little Vegemiter[1]. Sometimes you need to break a bone to help it heal properly. -- Daniel [1]: I *hate* Vegemite, but I think you get the idea :3 -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/ |
November 07, 2006 Re: 1.0 ?? [templates and currying] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kirk McDonald | Kirk McDonald wrote:
> This would be great! The one thing we lose is the ability to get the underlying function type of a delegate. If you were to also add some mechanism to freely convert a function type to a delegate type and vice versa, that would be perfect.
Or... a mechanism to derive a function or delegate type from a tuple (for param types) and one more type (for the return type).
e.g.
static assert (is(delegateType!(int, tuple(float, out char)) == int delegate(float, out char));
It would provide more power than just function/delegate type conversion and simplify some parametric function generation. For instance, my Bind lib generates a delegate from compile-type calculations based on the curried/bound arguments and function composition.
--
Tomasz Stachowiak
|
November 07, 2006 Re: 1.0 ?? [templates and currying] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep wrote:
> Walter Bright wrote:
>> I hate to tip over working code. I'll see if I can find another way.
>
> To derive a function's return type, number of arguments, type of
> arguments, I had to write an external Python script that spat out a huge
> ugly-as-hell D source file with support for functions of N arguments.
I'm writing an std.traits module, which will abstract away that stuff. So, if you're willing to rewrite using std.traits.Returns and std.traits .Parameters, you'll be immunized against changes in the future.
Also, to get number of parameters for function foo:
Parameters!(foo).length
will do it. First parameter type is:
Parameters!(foo)[0]
Rest of the parameter types are:
Parameters!(foo)[1 .. length]
Etc.
|
November 07, 2006 Re: 1.0 ?? [templates and currying] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | "Walter Bright" <newshound@digitalmars.com> wrote in message news:eiosfr$283p$1@digitaldaemon.com... > I'm writing an std.traits module, which will abstract away that stuff. So, if you're willing to rewrite using std.traits.Returns and std.traits .Parameters, you'll be immunized against changes in the future. > > Also, to get number of parameters for function foo: > > Parameters!(foo).length > > will do it. First parameter type is: > > Parameters!(foo)[0] > > Rest of the parameter types are: > > Parameters!(foo)[1 .. length] > > Etc. Sounds great. Just dreaming: template bind(alias func, dchar[] name = nameof(func))() { alias RetType!(func) ReturnType; alias Parameters!(func) Params; // Creates a MiniD-friendly function which acts as a shim between // MiniD and the real function. // GOD I wish I could create identifiers using token pasting. int identifier("bound_" ~ nameof(func))(MDState s) { // Create a new tuple big enough to hold all the parameter values alias NTuple!(Params.length) paramValues; // Get the params off the MiniD stack foreach(i, paramType; Params) paramValues[i] = s.getParam!(paramType)(i); // Call the function with the params (natively!) static if(is(ReturnType == void)) { func(paramValues); return 0; } else { s.push(func(paramValues)); return 1; } } // actually create the closure and set it as a global void bind(MDState s) { s.setGlobal(name, new MDClosure(s, &identifier("bound_" ~ nameof(func)), name)); } } ... void foo(int x, int y) { writefln(x, y); } bind!(foo); AAAAA I wish. |
November 07, 2006 Re: 1.0 ?? [templates and currying] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > ... > > I'm writing an std.traits module, which will abstract away that stuff. So, if you're willing to rewrite using std.traits.Returns and std.traits ..Parameters, you'll be immunized against changes in the future. > Well, I originally wrote the code because I was playing with embedding Python in D, and needed a way to get that information about a function. However, Kirk beat me to the punch, so I haven't used it since. So, yes. I'd be happy to use the "proper" traits library :) Any idea what else will be going in std.traits? I've already got a small traits library that I use in a few places that does things like convert between signed and unsigned types, find the next largest integer type, work out if a type is an integer or float, etc. I can post the code if you're looking for ideas. > Also, to get number of parameters for function foo: > > Parameters!(foo).length > > will do it. First parameter type is: > > Parameters!(foo)[0] > > Rest of the parameter types are: > > Parameters!(foo)[1 .. length] > > Etc. Very cool. I likes :) -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/ |
November 07, 2006 Re: 1.0 ?? [templates and currying] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > "Walter Bright" <newshound@digitalmars.com> wrote in message news:eiosfr$283p$1@digitaldaemon.com... > >> I'm writing an std.traits module, which will abstract away that stuff. So, if you're willing to rewrite using std.traits.Returns and std.traits .Parameters, you'll be immunized against changes in the future. >> >> Also, to get number of parameters for function foo: >> >> Parameters!(foo).length >> >> will do it. First parameter type is: >> >> Parameters!(foo)[0] >> >> Rest of the parameter types are: >> >> Parameters!(foo)[1 .. length] >> >> Etc. > > Sounds great. > > Just dreaming: > > template bind(alias func, dchar[] name = nameof(func))() > { > alias RetType!(func) ReturnType; > alias Parameters!(func) Params; > > // Creates a MiniD-friendly function which acts as a shim between > // MiniD and the real function. > // GOD I wish I could create identifiers using token pasting. > int identifier("bound_" ~ nameof(func))(MDState s) > { > // Create a new tuple big enough to hold all the parameter values > alias NTuple!(Params.length) paramValues; > > // Get the params off the MiniD stack > foreach(i, paramType; Params) > paramValues[i] = s.getParam!(paramType)(i); > > // Call the function with the params (natively!) > static if(is(ReturnType == void)) > { > func(paramValues); > return 0; > } > else > { > s.push(func(paramValues)); > return 1; > } > } > > // actually create the closure and set it as a global > void bind(MDState s) > { > s.setGlobal(name, new MDClosure(s, &identifier("bound_" ~ nameof(func)), name)); > } > } > > ... > > void foo(int x, int y) > { > writefln(x, y); > } > > bind!(foo); > > AAAAA > > I wish. > > ... have you been reading Pyd's function wrapping code? ;-) The internal code isn't /quite/ that clean, but the end result (the def template) is. http://www.dsource.org/projects/pyd/browser/trunk/infrastructure/pyd/func_wrap.d void foo(int x, int y) { writefln(x, y); } extern(C) export void inittestdll() { def!(foo); module_init("testdll"); } -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org |
November 07, 2006 Re: 1.0 ?? [templates and currying] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep wrote:
> Any idea what else will be going in std.traits?
So far, it's got only two entries <g>. I figure it to be a grab bag of stuff like what you've done. After the next update, please look it over and see what makes sense to go in it from your stuff.
|
November 07, 2006 Re: 1.0 ?? [templates and currying] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > Kirk McDonald wrote: >> This would be great! The one thing we lose is the ability to get the underlying function type of a delegate. > > Is that needed, though? Yes. It will be less needed if, as Tom suggests, there is a way to derive a tuple from a function or delegate type, and then derive a function or delegate type from a tuple. As was pointed out in a previous thread, the latter could be done if the following worked: template FuncType(Ret, T ...) { alias Ret function(T) FuncType; } In Pyd, users wrap member functions by providing an alias to the member function directly. Take the following class: class Foo { void f() { } } Wrapping this class in Pyd might be done with: wrapped_class!(Foo) f; f.def!(Foo.f); finalize_class(f); The signature of .def is: void def(alias fn, char[] name=symbolnameof!(fn), fn_t=typeof(&fn))(); fn_t, then, comes out to be void function(). Note that this is a /function/ type, and not a delegate type (which is right and proper). To actually call this, I need to derive a delegate type from this function type, and perform some hackery to call it. Which brings up another point: It's really great that you added the .ptr property to delegates in 0.168, but it would also be great to have a .fn property to access the function pointer. (And optimally, this pointer would be of the right type, and not just a void*.) -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org |
Copyright © 1999-2021 by the D Language Foundation