www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Crazy code by Adam on SO

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Worth a look:

http://stackoverflow.com/questions/25555329/d-finding-all-functions-with-certain-attribute

Andrei
Aug 29 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 29 August 2014 at 16:48:52 UTC, Andrei Alexandrescu 
wrote:
 Worth a look:

 http://stackoverflow.com/questions/25555329/d-finding-all-functions-with-certain-attribute

 Andrei
This is exactly the stuff I have referring to in DConf talk as "must have things that are simple by concept but very hard to implement correctly for a newcomer" :) Exactly type of helpers I'd love to add in future std.meta
Aug 29 2014
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Fri, Aug 29, 2014 at 05:06:56PM +0000, Dicebot via Digitalmars-d wrote:
 On Friday, 29 August 2014 at 16:48:52 UTC, Andrei Alexandrescu wrote:
Worth a look:

http://stackoverflow.com/questions/25555329/d-finding-all-functions-with-certain-attribute

Andrei
This is exactly the stuff I have referring to in DConf talk as "must have things that are simple by concept but very hard to implement correctly for a newcomer" :) Exactly type of helpers I'd love to add in future std.meta
A lot of Adam's stuff are in that category. One of the things I find eminently useful in my own code is the pseudo-"slots-and-signals" design of arsd.eventloop, which contains a particularly ingenious bit of code that does *runtime* dispatching of signal types (basically structs) to handlers of the correct type (delegates receiving structs of a specific type). The code figures out which signals to send to which delegates *at runtime*. The way this is done is to use the .mangleof of the struct's type as key to an AA of arrays of handlers, suitably wrapped to allow runtime-binding of incoming struct type to delegate parameter type. I highly recommending studying how Adam's code achieves this. :-) T -- May you live all the days of your life. -- Jonathan Swift
Aug 29 2014
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 29 August 2014 at 17:29:34 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 The code figures out which signals to send to which delegates
 *at runtime*. The way this is done is to use the .mangleof of
 the struct's type as key to an AA
I think there might be an easier way to do this too: cast(size_t) typeid(T). That'd be a unique integer for each type too that could be passed through the pipe... IIRC the reason I went with the mangle hash though was to work across processes, where the TypeInfo pointer might not as reliable (my rpc.d file works more in that direction but I can't recall if I actually finished it or not). BTW that eventloop thing uses malloc/free now whereas in the first draft it used the GC. Why? While the pointer was sitting in the kernel pipe buffer, the GC would sometimes collect it, causing random crashes. Just because the pointer hasn't left the program entirely doesn't mean the GC can still see it! I think I wrote this story in my book too in one of those little info boxes.
Aug 29 2014
prev sibling parent "Philippe Sigaud" <philippe.sigaud gmail.com> writes:
On Friday, 29 August 2014 at 17:29:34 UTC, H. S. Teoh via 
Digitalmars-d wrote:

 A lot of Adam's stuff are in that category.
(...)
 I highly recommending studying how Adam's code achieves this. 
 :-)
It's also a bit hypnotic. I wanted to do a quick test of his simpledisplay.d module, after reading one of his recipes. I fetched his github repo and... found myself one hour later, still reading a totally different module :)
Aug 29 2014
prev sibling next sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Fri, Aug 29, 2014 at 09:48:51AM -0700, Andrei Alexandrescu via Digitalmars-d
wrote:
 Worth a look:
 
 http://stackoverflow.com/questions/25555329/d-finding-all-functions-with-certain-attribute
[...] Wow. That's ... awesome. Kudos to Adam for the ingenuity!!! Compile-time reflection FTW! The mixin("import "...) line was mind-blowingly ingenious, I have to say. As are the mixin(x) lines where x is an alias, to coax the compiler to recursively scan submodules. D seriously rawkz for compile-time reflection. T -- Almost all proofs have bugs, but almost all theorems are true. -- Paul Pedersen
Aug 29 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/29/14, 10:12 AM, H. S. Teoh via Digitalmars-d wrote:
 On Fri, Aug 29, 2014 at 09:48:51AM -0700, Andrei Alexandrescu via
Digitalmars-d wrote:
 Worth a look:

 http://stackoverflow.com/questions/25555329/d-finding-all-functions-with-certain-attribute
[...] Wow. That's ... awesome. Kudos to Adam for the ingenuity!!! Compile-time reflection FTW! The mixin("import "...) line was mind-blowingly ingenious, I have to say. As are the mixin(x) lines where x is an alias, to coax the compiler to recursively scan submodules. D seriously rawkz for compile-time reflection.
Worth redditing? Or too much information? :o) Andrei
Aug 29 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 29 August 2014 at 19:04:33 UTC, Andrei Alexandrescu 
wrote:
 The mixin("import "...) line was mind-blowingly ingenious, I 
 have to
 say. As are the mixin(x) lines where x is an alias, to coax 
 the compiler
 to recursively scan submodules. D seriously rawkz for 
 compile-time
 reflection.
Worth redditing? Or too much information? :o) Andrei
Btw, while I remember it, doing mixin("static import ...") is highly recommended instead for namespace hygiene reason if you are actually going to do anything with found symbols.
Aug 29 2014
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 29 August 2014 at 19:22:42 UTC, Dicebot wrote:
 Btw, while I remember it, doing mixin("static import ...") is 
 highly recommended instead for namespace hygiene reason if you 
 are actually going to do anything with found symbols.
Logical. I've never actually used this trick for anything serious though, indeed, the first time I attempted it was writing that answer. It just occurred to me that a mixin with local imports is a solution to getting deeper and I slapped it down. Amusingly, this is now my highest rated SO answer ever.
Aug 29 2014
prev sibling next sibling parent Philippe Sigaud via Digitalmars-d <digitalmars-d puremagic.com> writes:
 http://stackoverflow.com/questions/25555329/d-finding-all-functions-with-certain-attribute
That's what a good part of his book is about, also. A nice read, one of my favorite chapters of the "D Cookbook". Ideally, Adam should do a PR for Phobos to add some code-walking ability like this. I'm interested by any answer on one of his points: is there currently a way to find function-local imports?
Aug 29 2014
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
There's another bug I didn't notice when writing the SO answer: 
the "module b.d;" didn't actually get picked up. Renaming it to 
"module b;" works, but not when it includes the package.

ooooh cuz it is considered "package mod" in stringof.... which 
has no members. Maybe if the compiler just called it "module 
foo.bar" instead of "package foo" we'd be in business though.
Aug 29 2014
parent "Dicebot" <public dicebot.lv> writes:
On Friday, 29 August 2014 at 17:17:07 UTC, Adam D. Ruppe wrote:
 There's another bug I didn't notice when writing the SO answer: 
 the "module b.d;" didn't actually get picked up. Renaming it to 
 "module b;" works, but not when it includes the package.

 ooooh cuz it is considered "package mod" in stringof.... which 
 has no members. Maybe if the compiler just called it "module 
 foo.bar" instead of "package foo" we'd be in business though.
Yes this is a known and unfortunate limitation with this technique :(
Aug 29 2014
prev sibling next sibling parent reply Philippe Sigaud via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Fri, Aug 29, 2014 at 7:12 PM, H. S. Teoh via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 The mixin("import "...) line was mind-blowingly ingenious, I have to
 say.
I remember using the same 'module' trick a few years ago (that is, getting a name with __traits and testing whether it begins with "module " or not) and, like Adam, being a bit ashamed by what I just did :) While reading his book this summe, I was, like, "Oh, then this is what we all do". Ideally, there should be a __traits(getModules) or __traits(getImports, ...). I know, I know, "where is the PR?". Also, this helper!(__traits) just to avoid a hole in the alias syntax is... what we all do here I suppose, but honestly the parser should accept alias member = __traits(getMember, ID, memberName); as valid D code.
Aug 29 2014
parent "Dicebot" <public dicebot.lv> writes:
On Friday, 29 August 2014 at 17:21:00 UTC, Philippe Sigaud via 
Digitalmars-d wrote:
 I remember using the same 'module' trick a few years ago (that 
 is,
 getting a name with __traits and testing whether it begins with
 "module " or not) and, like Adam, being a bit ashamed by what I 
 just
 did :) While reading his book this summe, I was, like, "Oh, 
 then this
 is what we all do".

 Ideally, there should be a __traits(getModules) or
 __traits(getImports, ...). I know, I know, "where is the PR?".
I have this in my TODO list but I want to take care of other things in related domain first. DIP63 being the most important priority
Aug 29 2014
prev sibling next sibling parent "Atila Neves" <atila.neves gmail.com> writes:
On Friday, 29 August 2014 at 16:48:52 UTC, Andrei Alexandrescu 
wrote:
 Worth a look:

 http://stackoverflow.com/questions/25555329/d-finding-all-functions-with-certain-attribute

 Andrei
Cool stuff. Maybe it's just because I started programming D by doing compile-time reflection (and 3 of my dub packages use it), but I was mostly nodding along going "yeah, yeah, done stuff like that". :P I like passing modules around as strings, that way I don't have to type the "import " part of it cos I'm super lazy. This means doing the same `mixin("import " ~ moduleName);` on the other side. I would've written: allWithSillyWalk!(onEach, "c", "mod.b") instead of picking them up from the imports. Again, lazy. :P Atila
Aug 29 2014
prev sibling next sibling parent reply Shammah Chancellor <anonymous coward.com> writes:
On 2014-08-29 16:48:51 +0000, Andrei Alexandrescu said:

 Worth a look:
 
 http://stackoverflow.com/questions/25555329/d-finding-all-functions-wi
h-certain-attribute 
 
 
 Andrei
Is this bug fixed then? https://issues.dlang.org/show_bug.cgi?id=11595
Sep 02 2014
parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Tuesday, 2 September 2014 at 22:30:59 UTC, Shammah Chancellor 
wrote:
 On 2014-08-29 16:48:51 +0000, Andrei Alexandrescu said:

 Worth a look:
 
 http://stackoverflow.com/questions/25555329/d-finding-all-functions-with-certain-attribute
 
 
 Andrei
Is this bug fixed then? https://issues.dlang.org/show_bug.cgi?id=11595
I have a PR open for this bug [0]. But I have had no feedback regarding it nor confirmation that it fixes the bug for others. No idea if anybody else has done something for it as well. [0] https://github.com/D-Programming-Language/dmd/pull/3921
Sep 02 2014
parent Shammah Chancellor <anonymous coward.com> writes:
On 2014-09-03 01:41:57 +0000, Rikki Cattermole said:

 On Tuesday, 2 September 2014 at 22:30:59 UTC, Shammah Chancellor wrote:
 On 2014-08-29 16:48:51 +0000, Andrei Alexandrescu said:
 
 Worth a look:
 
 http://stackoverflow.com/questions/25555329/d-finding-all-functions-wi
h-certain-attribute 
 
 
 
 Andrei
Is this bug fixed then? https://issues.dlang.org/show_bug.cgi?id=11595
I have a PR open for this bug [0]. But I have had no feedback regarding it nor confirmation that it fixes the bug for others. No idea if anybody else has done something for it as well. [0] https://github.com/D-Programming-Language/dmd/pull/3921
Looks like you made this pretty recently. Thanks! That bug was quite a thorn in my side for awhile. -Shammah
Sep 03 2014
prev sibling parent Shammah Chancellor <email domain.com> writes:
On 2014-08-29 16:48:51 +0000, Andrei Alexandrescu said:

 Worth a look:
 
 http://stackoverflow.com/questions/25555329/d-finding-all-functions-wi
h-certain-attribute 
 
 
 Andrei
That's some pretty neat code, I did something similar awhile ago for deserializing classes. Here's a reduced case of it: http://dpaste.dzfl.pl/4fffa339368f The facility to be able to create such a factory through compile time reflection is absolutely awesome. However, it "feels" as though the ability to do this is making use of undefined behavior rather than actual language features. First: I consider it sort of a language wart that alias hack(alias T) = T; is necessary for aliasing to the particular symbol, and that the __traits(getMember) expression can't be substituted in to the same places as the alias to it without compiler errors. It's very non-intuitive. I would have never figured that out on my own with out some other D wizards helping me about a year ago. I still don't understand why I can't simply do : alias member = __traits(getMember, ...); Also: The way that the foreach works in the pasted example is very surprising. I would be nice if this was a "static foreach" instead of just a foreach which happens to run at compile time over a TypeTuple. Normally doing a switch inside a foreach like that would not work at all, but near as I can tell the compiler unrolls the whole thing since it's inputs are known at compile time. Finally: If you actually want to have something that returns a TypeTuple!() of only subclasses which you can foreach over in other places -- you have to make a *very* ugly recursive template: (Line 208 thru Line 235 returns a TypeTuple of all subclasses of the Message class) https://github.com/schancel/gameserver/blob/master/source/messages/core.d#L208 Making these awesome feature more intuitive and easy to use would go a long way. I feel like this should be on your short list along with the GC and C++ compatibility. -S.
Sep 25 2014