Discussion:
Crazy code by Adam on SO
Andrei Alexandrescu via Digitalmars-d
2014-08-29 16:48:51 UTC
Permalink
Worth a look:

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

Andrei
Dicebot via Digitalmars-d
2014-08-29 17:06:56 UTC
Permalink
On Friday, 29 August 2014 at 16:48:52 UTC, Andrei Alexandrescu
Post by Andrei Alexandrescu via Digitalmars-d
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
H. S. Teoh via Digitalmars-d
2014-08-29 17:27:53 UTC
Permalink
Post by Andrei Alexandrescu via Digitalmars-d
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
Adam D. Ruppe via Digitalmars-d
2014-08-29 17:37:00 UTC
Permalink
On Friday, 29 August 2014 at 17:29:34 UTC, H. S. Teoh via
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.
Philippe Sigaud via Digitalmars-d
2014-08-29 17:40:46 UTC
Permalink
On Friday, 29 August 2014 at 17:29:34 UTC, H. S. Teoh via
Post by H. S. Teoh via Digitalmars-d
A lot of Adam's stuff are in that category.
(...)
Post by H. S. Teoh via Digitalmars-d
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 :)
H. S. Teoh via Digitalmars-d
2014-08-29 17:12:06 UTC
Permalink
Post by Andrei Alexandrescu via Digitalmars-d
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
Philippe Sigaud via Digitalmars-d
2014-08-29 17:20:51 UTC
Permalink
On Fri, Aug 29, 2014 at 7:12 PM, H. S. Teoh via Digitalmars-d
Post by H. S. Teoh via Digitalmars-d
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.
Dicebot via Digitalmars-d
2014-08-29 17:43:10 UTC
Permalink
On Friday, 29 August 2014 at 17:21:00 UTC, Philippe Sigaud via
Post by Philippe Sigaud via Digitalmars-d
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
Philippe Sigaud via Digitalmars-d
2014-08-29 17:14:29 UTC
Permalink
Post by Andrei Alexandrescu via Digitalmars-d
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?
Adam D. Ruppe via Digitalmars-d
2014-08-29 17:17:06 UTC
Permalink
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.
Dicebot via Digitalmars-d
2014-08-29 17:40:44 UTC
Permalink
Post by Adam D. Ruppe via Digitalmars-d
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 :(
Atila Neves via Digitalmars-d
2014-08-29 18:34:06 UTC
Permalink
On Friday, 29 August 2014 at 16:48:52 UTC, Andrei Alexandrescu
Post by Andrei Alexandrescu via Digitalmars-d
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
Andrei Alexandrescu via Digitalmars-d
2014-08-29 19:04:31 UTC
Permalink
Post by H. S. Teoh via Digitalmars-d
Post by Andrei Alexandrescu via Digitalmars-d
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
Dicebot via Digitalmars-d
2014-08-29 19:22:41 UTC
Permalink
On Friday, 29 August 2014 at 19:04:33 UTC, Andrei Alexandrescu
Post by Andrei Alexandrescu via Digitalmars-d
Post by H. S. Teoh via Digitalmars-d
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.
Adam D. Ruppe via Digitalmars-d
2014-08-30 01:34:25 UTC
Permalink
Post by Dicebot via Digitalmars-d
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.
Shammah Chancellor via Digitalmars-d
2014-09-02 22:30:59 UTC
Permalink
Post by Andrei Alexandrescu via Digitalmars-d
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
Rikki Cattermole via Digitalmars-d
2014-09-03 01:41:57 UTC
Permalink
On Tuesday, 2 September 2014 at 22:30:59 UTC, Shammah Chancellor
Post by Shammah Chancellor via Digitalmars-d
Post by Andrei Alexandrescu via Digitalmars-d
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
Shammah Chancellor via Digitalmars-d
2014-09-03 11:14:05 UTC
Permalink
Post by Rikki Cattermole via Digitalmars-d
Post by Shammah Chancellor via Digitalmars-d
Post by Andrei Alexandrescu via Digitalmars-d
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
Looks like you made this pretty recently. Thanks! That bug was quite
a thorn in my side for awhile.

-Shammah
Shammah Chancellor via Digitalmars-d
2014-09-26 04:26:09 UTC
Permalink
Post by Andrei Alexandrescu via Digitalmars-d
http://stackoverflow.com/questions/25555329/d-finding-all-functions-with-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.

Continue reading on narkive:
Loading...