www.digitalmars.com         C & C++   DMDScript  

digitalmars.dip.ideas - Mixin every entity

reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
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:
```d
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.
Jul 24
next sibling parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
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:
 ```d
 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. ```d module mixin(expr); ``` That is a big no-no because module names are probably parsed specially. And that’s fine.
Jul 24
prev sibling next sibling parent monkyyy <crazymonkyyy gmail.com> writes:
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 ```d mixin foo: void mixin("bar")(){} mixin(foo); ```
Jul 24
prev sibling next sibling parent Nick Treleaven <nick geany.org> writes:
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:
 ```d
 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.
Jul 24
prev sibling next sibling parent reply Basile B. <b2.temp gmx.com> writes:
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:
 ```d
 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:")`.
Jul 24
parent reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
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:
 ```d
 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?
Jul 25
parent Basile B. <b2.temp gmx.com> writes:
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:
 ```d
 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.
Jul 25
prev sibling parent Paul Backus <snarwin gmail.com> writes:
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][1]. [1]: https://dlang.org/library/std/typecons/wrap.html
Jul 25