www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Walter, I need a __trait please.

reply Stefan Koch <uplink.coder googlemail.com> writes:
Hi,

I found myself in need of __trait that might be useful to include.

something that would give me the parameters of a the body of the 
lambda as string and the parmeters of a lambda as AliasSequence.
e.g
foreach (p;__traits(lambda, (x,y) => x < y)) {
  writeln(p);
}

would output
x
y
x < y

I am sure this is doable unfortunately I lack the insight into 
DMD to implement this in a reasonable amount of time, and code 
quality.

Thanks in advance!

Stefan
Mar 14 2016
next sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Tuesday, 15 March 2016 at 00:29:17 UTC, Stefan Koch wrote:
 Hi,

 I found myself in need of __trait that might be useful to 
 include.

 something that would give me the parameters of a the body of 
 the lambda as string and the parmeters of a lambda as 
 AliasSequence.
 e.g
 foreach (p;__traits(lambda, (x,y) => x < y)) {
  writeln(p);
 }

 would output
 x
 y
 x < y

 I am sure this is doable unfortunately I lack the insight into 
 DMD to implement this in a reasonable amount of time, and code 
 quality.

 Thanks in advance!

 Stefan
Also can we have an isEnum and isStruct. yes __traits(compiles,Fields!(__traits(getMember,moduleName, member))) and the equivalent for enumMembers works but is very ugly.
Mar 14 2016
parent Stefan Koch <uplink.coder googlemail.com> writes:
On Tuesday, 15 March 2016 at 03:10:46 UTC, Nicholas Wilson wrote:
 On Tuesday, 15 March 2016 at 00:29:17 UTC, Stefan Koch wrote:
 Hi,

 I found myself in need of __trait that might be useful to 
 include.

 something that would give me the parameters of a the body of 
 the lambda as string and the parmeters of a lambda as 
 AliasSequence.
 e.g
 foreach (p;__traits(lambda, (x,y) => x < y)) {
  writeln(p);
 }

 would output
 x
 y
 x < y

 I am sure this is doable unfortunately I lack the insight into 
 DMD to implement this in a reasonable amount of time, and code 
 quality.

 Thanks in advance!

 Stefan
Also can we have an isEnum and isStruct. yes __traits(compiles,Fields!(__traits(getMember,moduleName, member))) and the equivalent for enumMembers works but is very ugly.
We have is (T == enum) and is(T == struct)
Mar 15 2016
prev sibling next sibling parent reply Jaocb Carlborg <doob me.com> writes:
On Tuesday, 15 March 2016 at 00:29:17 UTC, Stefan Koch wrote:
 Hi,

 I found myself in need of __trait that might be useful to 
 include.

 something that would give me the parameters of a the body of 
 the lambda as string and the parmeters of a lambda as 
 AliasSequence.
 e.g
 foreach (p;__traits(lambda, (x,y) => x < y)) {
  writeln(p);
 }

 would output
 x
 y
 x < y

 I am sure this is doable unfortunately I lack the insight into 
 DMD to implement this in a reasonable amount of time, and code 
 quality.

 Thanks in advance!

 Stefan
To get the parameters as as strings, I think this [1] will allow you to that. To get the body as a string, that sounds almost as AST macros :) [1] https://github.com/D-Programming-Language/dmd/pull/5201 -- /Jacob Carlborg
Mar 15 2016
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Tuesday, 15 March 2016 at 08:02:34 UTC, Jaocb Carlborg wrote:
 On Tuesday, 15 March 2016 at 00:29:17 UTC, Stefan Koch wrote:
 [...]
To get the parameters as as strings, I think this [1] will allow you to that. To get the body as a string, that sounds almost as AST macros :) [1] https://github.com/D-Programming-Language/dmd/pull/5201 -- /Jacob Carlborg
mixin templates are AST macros really. I will talk about that at Dconf If I get the chance :)
Mar 15 2016
prev sibling parent reply ZombineDev <petar.p.kirov gmail.com> writes:
On Tuesday, 15 March 2016 at 08:02:34 UTC, Jaocb Carlborg wrote:
 On Tuesday, 15 March 2016 at 00:29:17 UTC, Stefan Koch wrote:
 Hi,

 I found myself in need of __trait that might be useful to 
 include.

 something that would give me the parameters of a the body of 
 the lambda as string and the parmeters of a lambda as 
 AliasSequence.
 e.g
 foreach (p;__traits(lambda, (x,y) => x < y)) {
  writeln(p);
 }

 would output
 x
 y
 x < y

 I am sure this is doable unfortunately I lack the insight into 
 DMD to implement this in a reasonable amount of time, and code 
 quality.

 Thanks in advance!

 Stefan
To get the parameters as as strings, I think this [1] will allow you to that. To get the body as a string, that sounds almost as AST macros :) [1] https://github.com/D-Programming-Language/dmd/pull/5201 -- /Jacob Carlborg
Hi Jacob, I've been thinking quite a bit about the next step in the evolution of D's metaprogramming, and I thought that AST macros are the best way forward, however since then I become convinced that macros are a distraction from a much more powerful language feature. Firstly, macros are a kind of declarative preprocessor, in the case of AST macros they process ASTs. Surely operating at AST level is a significant improvement than plain text processing, however macros by themselves are separate language that requires a lot of additions to work. One of the biggest advantages of D is you don't need to use a different language for CTFE. Furthermore being purely declarative is very limiting, compared to how powerful imperative CTFE is. Next, macros may add new syntax to the language or change the meaning of the existing syntax which would be a very disruptive change to the language (even if it's made in a backwards compatible way). Instead I think that if we improve D's existing introspection capabilities and expose the compiler as a library at compile-time, we will have a much powerful system than any potential macro system, for a fraction of the complexity. These videos are what changed my mind: 1. https://www.youtube.com/watch?v=OHZwYYW9koI 2. https://www.youtube.com/watch?v=59lKAlb6cRg (Jonathan Blow's programming language for games)
Mar 15 2016
next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 15 March 2016 at 11:47:20 UTC, ZombineDev wrote:
 Instead I think that if we improve D's existing introspection 
 capabilities and expose the compiler as a library at 
 compile-time, we will have a much powerful system than any 
 potential macro system, for a fraction of the complexity.

 These videos are what changed my mind:
 1. https://www.youtube.com/watch?v=OHZwYYW9koI
 2. https://www.youtube.com/watch?v=59lKAlb6cRg
 (Jonathan Blow's programming language for games)
It is like one of these simili good idea that everybody tries and everybody regrets it. You DON'T want to expose your compiler implementation to the language. Jonathan Blow is certainly a talented person, but he has a very grave NIH syndrome and various blind spot in language design.
Mar 15 2016
next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 15 March 2016 at 19:59:01 UTC, deadalnix wrote:
 On Tuesday, 15 March 2016 at 11:47:20 UTC, ZombineDev wrote:
 Instead I think that if we improve D's existing introspection 
 capabilities and expose the compiler as a library at 
 compile-time, we will have a much powerful system than any 
 potential macro system, for a fraction of the complexity.

 These videos are what changed my mind:
 1. https://www.youtube.com/watch?v=OHZwYYW9koI
 2. https://www.youtube.com/watch?v=59lKAlb6cRg
 (Jonathan Blow's programming language for games)
It is like one of these simili good idea that everybody tries and everybody regrets it. You DON'T want to expose your compiler implementation to the language. Jonathan Blow is certainly a talented person, but he has a very grave NIH syndrome and various blind spot in language design.
So, to give a concrete example, because my critic sounds free and mean. https://youtu.be/59lKAlb6cRg?t=28m24s He quote C++ and D while presenting the defers feature. Turns out this feature is the same thing as scope(exit) and is planned to be added to C++ at some point. The more general subject of the video is basically AOP. For the most part, is is a clumsy implementation of something like lombok: https://projectlombok.org/ In addition it exposes the compiler, which will create maintenance problems in the future.
Mar 15 2016
parent reply ZombineDev <petar.p.kirov gmail.com> writes:
On Tuesday, 15 March 2016 at 23:04:59 UTC, deadalnix wrote:
 On Tuesday, 15 March 2016 at 19:59:01 UTC, deadalnix wrote:
 On Tuesday, 15 March 2016 at 11:47:20 UTC, ZombineDev wrote:
 Instead I think that if we improve D's existing introspection 
 capabilities and expose the compiler as a library at 
 compile-time, we will have a much powerful system than any 
 potential macro system, for a fraction of the complexity.

 These videos are what changed my mind:
 1. https://www.youtube.com/watch?v=OHZwYYW9koI
 2. https://www.youtube.com/watch?v=59lKAlb6cRg
 (Jonathan Blow's programming language for games)
It is like one of these simili good idea that everybody tries and everybody regrets it. You DON'T want to expose your compiler implementation to the language. Jonathan Blow is certainly a talented person, but he has a very grave NIH syndrome and various blind spot in language design.
So, to give a concrete example, because my critic sounds free and mean. https://youtu.be/59lKAlb6cRg?t=28m24s He quote C++ and D while presenting the defers feature. Turns out this feature is the same thing as scope(exit) and is planned to be added to C++ at some point. The more general subject of the video is basically AOP. For the most part, is is a clumsy implementation of something like lombok: https://projectlombok.org/ In addition it exposes the compiler, which will create maintenance problems in the future.
Yes, I know about AOP, but this is just a single application of all the possible use cases of his idea. Another example is describing the build process of your project with the same language, in the same source file. I'm sure there are many other possible use cases. Of course this can be easily abused, but it doesn't seem difficult to use it appropriately either. "With great power, comes great responsibility." It looks clumsy because it is low-level. Surely you can built higher level functionality that is nice and easy to use. "You DON'T want to expose your compiler implementation to the language." ironically, it looks like there is a company whose business is solely based on this idea (https://www.postsharp.net/aop.net/compiletime-weaving) and it looks like they are quite successful (https://www.postsharp.net/). The list of features (https://www.postsharp.net/features) proves that more access is better than no access, because otherwise none of them would be possible.
Mar 16 2016
parent ZombineDev <petar.p.kirov gmail.com> writes:
On Wednesday, 16 March 2016 at 11:45:28 UTC, ZombineDev wrote:
 ...

 "You DON'T want to expose your compiler implementation to the 
 language."
 ironically, it looks like there is a company whose business is 
 solely based on this idea 
 (https://www.postsharp.net/aop.net/compiletime-weaving) and it 
 looks like they are quite successful 
 (https://www.postsharp.net/). The list of features 
 (https://www.postsharp.net/features) proves that more access is 
 better than no access, because otherwise none of them would be 
 possible.
I know that a lot of the stuff are possible with mixin templates but, you can only wrap existing code with them. You can't modify the function bodies.
Mar 16 2016
prev sibling next sibling parent ZombineDev <petar.p.kirov gmail.com> writes:
On Tuesday, 15 March 2016 at 19:59:01 UTC, deadalnix wrote:
 On Tuesday, 15 March 2016 at 11:47:20 UTC, ZombineDev wrote:
 Instead I think that if we improve D's existing introspection 
 capabilities and expose the compiler as a library at 
 compile-time, we will have a much powerful system than any 
 potential macro system, for a fraction of the complexity.

 These videos are what changed my mind:
 1. https://www.youtube.com/watch?v=OHZwYYW9koI
 2. https://www.youtube.com/watch?v=59lKAlb6cRg
 (Jonathan Blow's programming language for games)
It is like one of these simili good idea that everybody tries and everybody regrets it. You DON'T want to expose your compiler implementation to the language. Jonathan Blow is certainly a talented person, but he has a very grave NIH syndrome and various blind spot in language design.
Well I agree with most of what you said. While I was watching his videos, I could't stop thinking "but you can already do this in D" about a lot of the stuff he "invented". On the other hand, his videos are quite interesting, especially considering he has no PL design/compiler background. I like that he takes some ideas to the extreme. I'm certain that if he didn't have such strong NIHS, it would have taken him years to get same results with D. Pointers with ownership semantics, SoA/AoS, purely CTFE-based build system, compiler message loop, etc. are are all very powerful things (as he demonstrates), and sadly I don't see them comming to D in the near future, so it's good that he decided to pursue them, so we can see if they're worthwhile exploring for D. An interface to the compiler is not the same as exposing the internels of the implementation. If you're skeptical about robustness or scalability of such system, I will point out this access can restricted to certain well-defined places (maybe something similar to shared static this()). But certainly his direction game-changing if not game-enabling (to quote Andrei).
Mar 15 2016
prev sibling parent reply cy <dlang verge.info.tm> writes:
On Tuesday, 15 March 2016 at 19:59:01 UTC, deadalnix wrote:
 It is like one of these simili good idea that everybody tries 
 and everybody regrets it. You DON'T want to expose your 
 compiler implementation to the language.
I'm sorry, but I know a lot of people who don't expose their compiler implementation to the language, and I don't know anyone at all who tried exposing their compiler implementation to the language, and regretted it. Instead of concocting these scenarios that nobody has even tried, then claiming "everybody regrets" it, perhaps you should give your reasoning as to why they are not a good thing. I'd honestly worry more about the compiler hiding implementation, that could have been used to make things easier for programmers.
Mar 15 2016
parent Dejan Lekic <dejan.lekic gmail.com> writes:
On Wednesday, 16 March 2016 at 04:47:05 UTC, cy wrote:

 I'd honestly worry more about the compiler hiding 
 implementation, that could have been used to make things easier 
 for programmers.
You worry too much.
Mar 16 2016
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 15/03/16 12:47, ZombineDev wrote:

 Hi Jacob,

 I've been thinking quite a bit about the next step in the evolution of
 D's metaprogramming, and I thought that AST macros are the best way
 forward, however since then I become convinced that macros are a
 distraction from a much more powerful language feature.

 Firstly, macros are a kind of declarative preprocessor, in the case of
 AST macros they process ASTs. Surely operating at AST level is a
 significant improvement than plain text processing, however macros by
 themselves are separate language that requires a lot of additions to
 work. One of the biggest advantages of D is you don't need to use a
 different language for CTFE. Furthermore being purely declarative is
 very limiting, compared to how powerful imperative CTFE is.
AST macros can be implemented in many different ways. The basic idea of the way I'm thinking is very simple. It consists of two feature (or one, depending on how you look at it). 1. A way to expose parts of the AST in the compiler to user 2. A way to turn an AST create by a user to something the compiler can use Example: macro foo(Ast a) { return a; } foo(3 + 4); The compiler exposes the AST of the expression "3 + 4" as the library type "Ast". That would be 1. Converting the returned value of the library type "Ast" to something the compiler can use. That would be 2. The rest is just manipulating AST's with CTFE.
 Next, macros may add new syntax to the language
Not in my vision.
 or change the meaning of the existing syntax which would be a very disruptive
change to the
 language (even if it's made in a backwards compatible way).
It's already possible to do that today with operator overloading. I think that's a very important feature of AST macros, which allows to do things like this: Person.where(e => e.name == "John") Which would be turned into an SQL query that fetches all rows from the "Person" table where name is "John".
 Instead I think that if we improve D's existing introspection
 capabilities and expose the compiler as a library at compile-time, we
 will have a much powerful system than any potential macro system, for a
 fraction of the complexity.

 These videos are what changed my mind:
 1. https://www.youtube.com/watch?v=OHZwYYW9koI
 2. https://www.youtube.com/watch?v=59lKAlb6cRg
 (Jonathan Blow's programming language for games)
I've only watched the second video, but yes, that's very powerful. I don't think what's in the video is any more or less complex than my view of AST macros. It's just two different ways of exposing the AST of the compiler. I think both kinds are useful. Or rather, it's useful to have a way to hook into the compiler before all semantic processing is done. For more details of my vision see DIP 50 [1]. [1] http://wiki.dlang.org/DIP50 -- /Jacob Carlborg
Mar 15 2016
prev sibling next sibling parent Jaocb Carlborg <doob me.com> writes:
On Tuesday, 15 March 2016 at 00:29:17 UTC, Stefan Koch wrote:
 Hi,

 I found myself in need of __trait that might be useful to 
 include.

 something that would give me the parameters of a the body of 
 the lambda as string and the parmeters of a lambda as 
 AliasSequence.
 e.g
 foreach (p;__traits(lambda, (x,y) => x < y)) {
  writeln(p);
 }

 would output
 x
 y
 x < y

 I am sure this is doable unfortunately I lack the insight into 
 DMD to implement this in a reasonable amount of time, and code 
 quality.
I think someone created a pull request which added .codeof, that would return any piece of code as a string. The PR was rejected, for some reason. Might not even have been a PR, perhaps only a proof of concept. -- /Jacob Carlbor
Mar 15 2016
prev sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
 foreach (p;__traits(lambda, (x,y) => x < y)) {
  writeln(p);
 }

 would output
 x
 y
 x < y
If something like that would be merged I can implement this now I guess. thanks for the PR link Jacob
Mar 15 2016