Thread overview
Mixin every entity
Jul 24
monkyyy
Jul 24
Basile B.
Jul 25
Basile B.
July 24

Mixins can produce types, expressions, statements, and declarations. That is great, but it could be better.

Why not allow mixin identifiers, storage classes, attributes, etc.?

Contrived example:

struct mixin("C")
{
mixin("const"):
    void f(mixin("ref") int x) mixin("@safe") { }
}

There’s no good reason a whole entity must be written in a string literal with a “hole” to be filled by format just because its name is generated. Interpolated strings help, but are not fundamentally different.

July 24

On Wednesday, 24 July 2024 at 11:57:35 UTC, Quirin Schroll wrote:

>

Mixins can produce types, expressions, statements, and declarations. That is great, but it could be better.

Why not allow mixin identifiers, storage classes, attributes, etc.?

Contrived example:

struct mixin("C")
{
mixin("const"):
    void f(mixin("ref") int x) mixin("@safe") { }
}

There’s no good reason a whole entity must be written in a string literal with a “hole” to be filled by format just because its name is generated. Interpolated strings help, but are not fundamentally different.

One difference between usual mixins and mixins generating storage classes and attributes (possibly more entities) is that those would be valid when called with the empty string, resulting in no storage class or attribute.


The only place I’d exclude from having its name generated is a module.

module mixin(expr);

That is a big no-no because module names are probably parsed specially. And that’s fine.

July 24

On Wednesday, 24 July 2024 at 11:57:35 UTC, Quirin Schroll wrote:

>

There’s no good reason a whole entity must be written in a string literal

the dev team has claimed everytime "its intentional so we airnt c preprocessor"
(pretending d's meta programming is sane and bug free)


maybe they could be convinced of a labeled mixin; but I doubt it

mixin foo:
  void mixin("bar")(){}

mixin(foo);
July 24

On Wednesday, 24 July 2024 at 11:57:35 UTC, Quirin Schroll wrote:

>

Mixins can produce types, expressions, statements, and declarations. That is great, but it could be better.

Why not allow mixin identifiers, storage classes, attributes, etc.?

Just to mention, any new non-trivial feature needs compelling use-cases.

>

Contrived example:

struct mixin("C")
{
mixin("const"):
    void f(mixin("ref") int x) mixin("@safe") { }
}

Perhaps being able to alias attributes would be nicer, for metaprogramming.

>

There’s no good reason a whole entity must be written in a string literal with a “hole” to be filled by format just because its name is generated. Interpolated strings help, but are not fundamentally different.

Mixin identifiers would be useful:
https://forum.dlang.org/post/aznmkielsozvfgrzehoc@forum.dlang.org

Generally if you could mixin anything, that would probably make parsing much more complicated for tools.

July 24

On Wednesday, 24 July 2024 at 11:57:35 UTC, Quirin Schroll wrote:

>

Mixins can produce types, expressions, statements, and declarations. That is great, but it could be better.

Why not allow mixin identifiers, storage classes, attributes, etc.?

Contrived example:

struct mixin("C")
{
mixin("const"):
    void f(mixin("ref") int x) mixin("@safe") { }
}

There’s no good reason a whole entity must be written in a string literal with a “hole” to be filled by format just because its name is generated. Interpolated strings help, but are not fundamentally different.

There is a good reason for that, that is not what is explained in one of the answer I can read. Mixins must introduce full grammatical constructs, i.e an expression, a statement, or a declaration, so that the content can be passed to the parser. Also they cant interfere with a scope. There's a well known bug (closed as of today), mixin("private:").

July 25

On Wednesday, 24 July 2024 at 20:17:21 UTC, Basile B. wrote:

>

On Wednesday, 24 July 2024 at 11:57:35 UTC, Quirin Schroll wrote:

>

Mixins can produce types, expressions, statements, and declarations. That is great, but it could be better.

Why not allow mixin identifiers, storage classes, attributes, etc.?

Contrived example:

struct mixin("C")
{
mixin("const"):
    void f(mixin("ref") int x) mixin("@safe") { }
}

There’s no good reason a whole entity must be written in a string literal with a “hole” to be filled by format just because its name is generated. Interpolated strings help, but are not fundamentally different.

There is a good reason for that, that is not what is explained in one of the answer I can read. Mixins must introduce full grammatical constructs, i.e an expression, a statement, or a declaration, so that the content can be passed to the parser. Also they cant interfere with a scope. There's a well known bug (closed as of today), mixin("private:").

I think you missed the point. What counts as a whole grammatical construct? Types can be mixed in, after all… So, at this point, calling types, expressions, statements, and declarations “whole,” but others which have names in the D grammar not is just arbitrary. Now, mixin("private:") isn’t illegal, it just doesn’t do anything useful. Why can’t identifiers, storage classes, attributes, etc. not count as whole entities?

July 25

On Thursday, 25 July 2024 at 14:30:31 UTC, Quirin Schroll wrote:

>

On Wednesday, 24 July 2024 at 20:17:21 UTC, Basile B. wrote:

>

On Wednesday, 24 July 2024 at 11:57:35 UTC, Quirin Schroll wrote:

>

Mixins can produce types, expressions, statements, and declarations. That is great, but it could be better.

Why not allow mixin identifiers, storage classes, attributes, etc.?

Contrived example:

struct mixin("C")
{
mixin("const"):
    void f(mixin("ref") int x) mixin("@safe") { }
}

There’s no good reason a whole entity must be written in a string literal with a “hole” to be filled by format just because its name is generated. Interpolated strings help, but are not fundamentally different.

There is a good reason for that, that is not what is explained in one of the answer I can read. Mixins must introduce full grammatical constructs, i.e an expression, a statement, or a declaration, so that the content can be passed to the parser. Also they cant interfere with a scope. There's a well known bug (closed as of today), mixin("private:").

I think you missed the point. What counts as a whole grammatical construct? Types can be mixed in, after all… So, at this point, calling types, expressions, statements, and declarations “whole,” but others which have names in the D grammar not is just arbitrary. Now, mixin("private:") isn’t illegal, it just doesn’t do anything useful. Why can’t identifiers, storage classes, attributes, etc. not count as whole entities?

I dont know how to this explain this better but let's try. The AST is essentially made of 4 great family of nodes, Statements, Expressions, Declarations and Types.
Those are easy to insert dynamically. That's all. I did not say that partial construct could not be mixed-in, rather that this seems complicated at first glance.

July 25

On Wednesday, 24 July 2024 at 11:57:35 UTC, Quirin Schroll wrote:

>

Mixins can produce types, expressions, statements, and declarations. That is great, but it could be better.

Why not allow mixin identifiers, storage classes, attributes, etc.?

IMO the most impactful addition would be the ability to mixin an identifier.

Currently, one of the only use-cases that actually requires using a string mixin is generating identifiers at compile time. The ability to mix in an identifier on its own, without enclosing the entire declaration it belongs to in a string mixin, would simplify this use-case immensely.

For an example of this use-case in Phobos, see std.typecons.wrap.