September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | On 9/19/2013 12:44 PM, Benjamin Thaut wrote:
> Can't we make the compiler deduce the static attribute? If a template method or
> a method of a template struct / class does not access any of its members it
> becomes static automatically?
static/nonstatic member functions have different ABIs, so no, it would not work.
|
September 19, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Thu, Sep 19, 2013 at 01:32:06PM -0700, Walter Bright wrote: > On 9/19/2013 12:44 PM, Benjamin Thaut wrote: > >Can't we make the compiler deduce the static attribute? If a template method or a method of a template struct / class does not access any of its members it becomes static automatically? > > static/nonstatic member functions have different ABIs, so no, it would not work. There's also the problem of base class methods turning static where you didn't intend it to, for example: class Base { // This method is intended to be overridden by derived // classes. void method() { // Oops, didn't access 'this', now we're static. assert(0, "Not implemented"); } } class Derived : Base { int x; override void method() { // NG x++; } } T -- Computers aren't intelligent; they only think they are. |
September 20, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Thursday, 19 September 2013 at 17:20:53 UTC, Andrej Mitrovic wrote: > On Thursday, 19 September 2013 at 17:10:43 UTC, Andrei Alexandrescu wrote: >> Any ideas for a clean solution? I can't get much further than string mixins, which wouldn't be clean :o). > > opDispatch comes to mind. You'd only need two of them, one marked static and the other one not. Hello, I decided to try and solve this as an exercise with the opDispatch hint above. I am not very experienced with D, but I am sharing my solution anyway in case it is of interest: http://dpaste.dzfl.pl/3bde7db1 Enjoy/Destroy :) |
September 20, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu Attachments:
| 2013/9/20 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> > Consider a struct that may or may not have state depending on a type parameter: > > struct S(T) > { > enum hasState = FieldTypeTuple!T.length || isNested!T; > static if (hasState) > T _theT; > else > alias _theT = T; > ... > } > > This is really nice because I don't bloat S unnecessarily and I get to use _theT.method() uniformly whether or not it's the type itself or the data member. > > The duplication problem appears when S itself must define a method that should be static or nonstatic depending on the existence of state. Consider: > > struct S(T) > { > ... continued from above ... > if (hasState) > int method() { return 1 + _theT.method(); } > else > static int method() { return 1 + _theT.method(); } > } > > In the general case the body of S!T.method() may be of course larger, which makes for a nasty duplication - essentially all but the "static" keyword must be duplicated. > > Any ideas for a clean solution? I can't get much further than string mixins, which wouldn't be clean :o). > Just an idea: string mixin + UDA? @mixin(hasState ? "" : "static") int method() { return 1 + _theT.method(); } Kenji Hara |
September 20, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 19-Sep-2013 21:10, Andrei Alexandrescu пишет: > Consider a struct that may or may not have state depending on a type > parameter: [snip] > Any ideas for a clean solution? I can't get much further than string > mixins, which wouldn't be clean :o). It seems like s/string/template and we are there. This works for me: import std.traits; struct Static{ static int method(){ return 21; } } struct Instance{ int v; //so that it "hasState" int method(){ return 12; } } mixin template Methods() { int method() { return 1 + _theT.method(); } } struct S(T) { enum hasState = FieldTypeTuple!T.length || isNested!T; static if (hasState) T _theT; else alias _theT = T; static if (hasState) mixin Methods!(); else{ static{ mixin Methods!(); } } } void main() { S!Static s1; S!Instance s2; assert(S!Static.method() == 22); assert(s1.method() == 22); assert(s2.method() == 13); assert(s1.sizeof == 1); assert(s2.sizeof == 4); } -- Dmitry Olshansky |
September 20, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to safety0ff | On 9/19/13 9:59 PM, safety0ff wrote:
> On Thursday, 19 September 2013 at 17:20:53 UTC, Andrej Mitrovic wrote:
>> On Thursday, 19 September 2013 at 17:10:43 UTC, Andrei Alexandrescu
>> wrote:
>>> Any ideas for a clean solution? I can't get much further than string
>>> mixins, which wouldn't be clean :o).
>>
>> opDispatch comes to mind. You'd only need two of them, one marked
>> static and the other one not.
>
> Hello,
>
> I decided to try and solve this as an exercise with the opDispatch hint
> above.
>
> I am not very experienced with D, but I am sharing my solution anyway in
> case it is of interest: http://dpaste.dzfl.pl/3bde7db1
>
> Enjoy/Destroy :)
Nice. If that's what you write while not being very experienced, I'm really looking forward to what you'll write when you'll be!
Thanks,
Andrei
|
September 20, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 9/19/13 1:02 PM, Andrej Mitrovic wrote:
> On 9/19/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>> I'm not sure I understand how that would work.
>
> -----
> module test;
[snip]
Thanks, that's the simplest and most effective. I reduced it to:
struct A
{
enum hasState = false;
private mixin template funDef()
{
void fun(int x) { writeln(x); }
}
static if (hasState)
mixin funDef!();
else
static mixin funDef!();
}
void main()
{
A a;
a.fun(42);
}
I see no way to extract the scaffolding into a library.
Andrei
|
September 20, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kenji Hara | On 9/20/13 12:34 AM, Kenji Hara wrote:
> Just an idea: string mixin + UDA?
>
> @mixin(hasState ? "" : "static")
> int method() { return 1 + _theT.method(); }
That would be nice but would be a language change (and a subtle one... now we have @mixin which introduces attributes that themselves may or may not start with "@").
I decided to go with a slightly different design, but the problem remains - there is no simple way to introduce conditional attributes and qualifiers.
Andrei
|
September 20, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 20-Sep-2013 19:20, Andrei Alexandrescu пишет: > On 9/19/13 1:02 PM, Andrej Mitrovic wrote: >> On 9/19/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: >>> I'm not sure I understand how that would work. >> >> ----- >> module test; > [snip] > > Thanks, that's the simplest and most effective. I reduced it to: > > struct A > { > enum hasState = false; > private mixin template funDef() > { > void fun(int x) { writeln(x); } > } > static if (hasState) > mixin funDef!(); > else > static mixin funDef!(); > } > > void main() > { > A a; > a.fun(42); > } > > I see no way to extract the scaffolding into a library. Shouldn't it as simple as a mixin-able template that simply forwards all methods of a type T (and if it has no state it does so statically). With __traits(allMembers,...) to extract all publics, it must be doable. The end result should be around the following... struct A{ //aliases type or contains state as required mixin extractState!T; } -- Dmitry Olshansky |
September 20, 2013 Re: Eliminating code duplication for static/nonstatic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 2013-09-20, 17:20, Andrei Alexandrescu wrote: > On 9/19/13 1:02 PM, Andrej Mitrovic wrote: >> On 9/19/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: >>> I'm not sure I understand how that would work. >> >> ----- >> module test; > [snip] > > Thanks, that's the simplest and most effective. I reduced it to: > > struct A > { > enum hasState = false; > private mixin template funDef() > { > void fun(int x) { writeln(x); } > } > static if (hasState) > mixin funDef!(); > else > static mixin funDef!(); > } > > void main() > { > A a; > a.fun(42); > } > > I see no way to extract the scaffolding into a library. Like this? import std.stdio; mixin template maybeStatic(bool isStatic, alias funDef, args...) { static if (isStatic) { static mixin funDef!args; } else { mixin funDef!args; } } struct A { enum hasState = false; private mixin template funDef() { void fun(int x) { writeln(x); } } mixin maybeStatic!(!hasState, funDef); } void main() { A a; a.fun(42); } -- Simen |
Copyright © 1999-2021 by the D Language Foundation