Skip to content

Remove the long-winded use of __MODULE__.ReturnType in refraction module#11

Open
aliak00 wants to merge 1 commit into
masterfrom
refract-remove-returntype
Open

Remove the long-winded use of __MODULE__.ReturnType in refraction module#11
aliak00 wants to merge 1 commit into
masterfrom
refract-remove-returntype

Conversation

@aliak00

@aliak00 aliak00 commented Jul 20, 2020

Copy link
Copy Markdown
Owner

Try and remove need for verbosity for return type. If we can get this to
work we can probably do the same for Parameters

Try and remove need for verbosity for return type. If we can get this to
work we can probably do the same for Parameters
@aliak00

aliak00 commented Jul 20, 2020

Copy link
Copy Markdown
Owner Author

@jll63 what do you think?

@jll63

jll63 commented Jul 23, 2020

Copy link
Copy Markdown
Contributor

@jll63 what do you think?

It would break everything.

Let's split the GrandTour example into two modules, and change it a tiny bit. To make it simpler, I'll just drop them in experimental:

module bolts.experimental.problem;

import bolts.experimental.mock;

struct Problem {}

interface GrandTour {
    pure Problem foo() immutable; // Ha!
    @nogc @trusted nothrow ref int foo(out real, return ref int, lazy int) const;
    @safe shared scope void bar(scope Object);
}

unittest {
    auto gt = new Mock!GrandTour();
}
module bolts.experimental.mock;

import bolts.experimental.refraction;
import std.format;
import std.traits;

class Mock(Interface) : Interface {
    static foreach (member; __traits(allMembers, Interface)) {
        static foreach (fun; __traits(getOverloads, Interface, member)) {
            mixin({
                    enum Model = refract!(fun, "fun");
                    if (is(ReturnType!fun == void)) {
                        return Model.withBody("{}").mixture;
                    } else if (Model.attributes & FunctionAttribute.ref_) {
                        return Model.withBody(q{{
                                    static %s rv;
                                    return rv;
                                }}.format(Model.returnType)).mixture;
                    } else {
                        return Model.withBody(q{{
                                    return %s.init;
                                }}.format(Model.returnType)).mixture;
                    }
                }());
        }
    }
}

Now, dub test:

mixins.txt(238,32): Error: undefined identifier `Problem`

Problem is not accessible from bolts.experimental.mock. Well not directly: ReturnType can grab it.

I am putting this in a branch in case you want to play with it.

@jll63

jll63 commented Jul 23, 2020

Copy link
Copy Markdown
Contributor

I have an idea for trimming the mixture in some circumstances. I will try it during the weekend.

Also, don't you think that ParameterAttribute should move somewhere in bolts.traits? It should be in std.traits, really, but in the meantime...

And this would be better than the current version:

import std.meta;

template ParameterAttributes(alias fun, int i) {
    static if (is(typeof(fun) P == __parameters)) {
        alias ParameterAttributes = __traits(getAttributes, P[i..i+1]);
    }
}

struct virtual;

void kick(int times, @virtual @("Animal") Object animal);

pragma(msg, ParameterAttributes!(kick, 1).length);
pragma(msg, ParameterAttributes!(kick, 1));
2LU
tuple((virtual), "Animal")

@jll63

jll63 commented Jul 25, 2020

Copy link
Copy Markdown
Contributor

Branch with less verbose mixtures is here: https://github.com/jll63/bolts/tree/refraction-compact-mixture

Basically, it avoids unpacking the parameter list unless it is modified. Then it avoids unpacking the parameters into type, storage classes and UDAs unless they are modified.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants