Jump to page: 1 2 3
Thread overview
Eliminating code duplication for static/nonstatic functions
Sep 19, 2013
Andrej Mitrovic
Sep 19, 2013
Jacob Carlborg
Sep 19, 2013
Andrej Mitrovic
Sep 19, 2013
Andrej Mitrovic
Sep 20, 2013
Dmitry Olshansky
Sep 20, 2013
Simen Kjaeraas
Sep 21, 2013
deadalnix
Sep 19, 2013
Jacob Carlborg
Sep 19, 2013
Andrej Mitrovic
Sep 20, 2013
safety0ff
Sep 19, 2013
Benjamin Thaut
Sep 19, 2013
Walter Bright
Sep 19, 2013
H. S. Teoh
Sep 20, 2013
Kenji Hara
Sep 20, 2013
Dmitry Olshansky
Sep 21, 2013
Vladimir Panteleev
September 19, 2013
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).


Thanks,

Andrei
September 19, 2013
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.
September 19, 2013
On 2013-09-19 19:20, Andrej Mitrovic wrote:

> opDispatch comes to mind. You'd only need two of them, one marked static
> and the other one not.

You cannot overload on "static".

-- 
/Jacob Carlborg
September 19, 2013
On 9/19/13, Jacob Carlborg <doob@me.com> wrote:
> On 2013-09-19 19:20, Andrej Mitrovic wrote:
>
>> opDispatch comes to mind. You'd only need two of them, one marked static and the other one not.
>
> You cannot overload on "static".

Can't you read the damn OP example? He's using a static if to introduce static/non-static functions, do the same for opDispatch and you'll cut down on code.
September 19, 2013
Am 19.09.2013 19:10, schrieb Andrei Alexandrescu:
> 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).
>
>
> Thanks,
>
> Andrei

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?
September 19, 2013
On 9/19/13 12:42 PM, Andrej Mitrovic wrote:
> On 9/19/13, Jacob Carlborg <doob@me.com> wrote:
>> On 2013-09-19 19:20, Andrej Mitrovic wrote:
>>
>>> opDispatch comes to mind. You'd only need two of them, one marked static
>>> and the other one not.
>>
>> You cannot overload on "static".
>
> Can't you read the damn OP example? He's using a static if to
> introduce static/non-static functions, do the same for opDispatch and
> you'll cut down on code.

I'm not sure I understand how that would work.

Andrei


September 19, 2013
On 9/19/13 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?

That would be nice for this case, but it's a breaking change and I'm not sure how confusing it would be in general.

Allowing static/nonstatic overloading would help because at least I could do this:

  int method() { return 1 + _theT.method(); }
  static if (!hasState)
    static int method() { return S().method(); }

which still is quite a bit of work, but less net duplication.


Andrei

September 19, 2013
On 2013-09-19 21:42, Andrej Mitrovic wrote:

> Can't you read the damn OP example? He's using a static if to
> introduce static/non-static functions, do the same for opDispatch and
> you'll cut down on code.

Right, sorry.

-- 
/Jacob Carlborg
September 19, 2013
On 9/19/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> I'm not sure I understand how that would work.

-----
module test;

import std.traits;

struct S(T)
{
    enum hasState = FieldTypeTuple!T.length || isNested!T;

    static if (hasState)
        T _theT;
    else
        alias _theT = T;

    private mixin template OpDispatch()
    {
        auto opDispatch(string meth, Args...)(Args args)
        {
            static if (meth == "method")  // specialization ?
                return 1 + _theT.method();
            else
                return mixin("_theT." ~ meth)(args);
        }
    }

    static if (hasState)
        mixin OpDispatch!();
    else
        static mixin OpDispatch!();
}

struct A
{
    static int method() { return 0; }
}

struct B
{
    int i;
    int method() { return i; }
}

void main()
{
    auto a = S!A();
    auto b = S!B(B(1));

    assert(a.method == 1);  // 1 + A.method() == 1
    assert(b.method == 2);  // 1 + b.i == 2
    assert(S!A.method == 1);  // works due to static dispatch
    // assert(S!B.method == 2);  // denied at CT (requires 'this')
}
-----
September 19, 2013
On 9/19/13, Jacob Carlborg <doob@me.com> wrote:
> On 2013-09-19 21:42, Andrej Mitrovic wrote:
>
>> Can't you read the damn OP example? He's using a static if to introduce static/non-static functions, do the same for opDispatch and you'll cut down on code.
>
> Right, sorry.

Sorry for the harsh response on my part, I wasn't in the mood 5 minutes ago. I shouldn't take it out on fellow D programmers.
« First   ‹ Prev
1 2 3