D import idiom compilation time
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Mon Jan 7 21:50:20 UTC 2019
On 1/5/19 5:48 PM, Dgame wrote:
> On Saturday, 5 January 2019 at 21:36:10 UTC, Neia Neutuladh wrote:
>> On Sat, 05 Jan 2019 21:14:37 +0000, Dgame wrote:
>>> I'm curious about that. Would that work or did I miss something?
>>
>> In your version, I might write:
>>
>> from.std.stdio.thisFunctionDoesNotExist("Hallo");
>>
>> And the error I would get is:
>>
>> Error: struct FromImpl does not overload ()
>
> True.. What about:
>
> ----
> template isModuleImport(string import_)
> {
> enum isModuleImport = __traits(compiles, { mixin("import ",
> import_, ";"); });
> }
>
> template isSymbolInModule(string module_, string symbol)
> {
> static if (isModuleImport!module_) {
> enum import_ = module_ ~ ":" ~ symbol;
> enum isSymbolInModule = __traits(compiles, { mixin("import ",
> import_, ";"); });
> } else {
> enum isSymbolInModule = false;
> }
> }
>
> template FailedSymbol(string symbol, string module_)
> {
> auto FailedSymbol(Args...)(auto ref Args args)
> {
> assert(0, "Symbol \"" ~ symbol ~ "\" not found in " ~ module_);
> }
> }
>
> struct FromImpl(string module_)
> {
> template opDispatch(string symbol)
> {
> static if (isSymbolInModule!(module_, symbol)) {
> mixin("import ", module_, "; alias opDispatch = ", symbol,
> ";");
> } else {
> static if (module_.length == 0) {
> enum opDispatch = FromImpl!(symbol)();
> } else {
> enum import_ = module_ ~ "." ~ symbol;
> static if (isModuleImport!import_) {
> enum opDispatch = FromImpl!(import_)();
> } else {
> alias opDispatch = FailedSymbol!(symbol, module_);
> }
> }
> }
> }
> }
>
> enum from = FromImpl!null();
>
> void main()
> {
> from.std.stdio.writeln("Hallo");
> auto _ = from.std.datetime.stopwatch.AutoStart.yes;
> from.std.stdio.thisFunctionDoesNotExist("Hallo");
> from.std.stdio.thisFunctionDoesNotExist(42);
> }
> ----
>
> Output:
>
> ----
> Hallo
> core.exception.AssertError at onlineapp.d(20): Symbol
> "thisFunctionDoesNotExist" not found in std.stdio
> ----------------
> ??:? _d_assert_msg [0x3c00dc54]
> onlineapp.d:20 pure nothrow @nogc @safe void
> onlineapp.FailedSymbol!("thisFunctionDoesNotExist",
> "std.stdio").FailedSymbol!(immutable(char)[]).FailedSymbol(immutable(char)[])
> [0x3c00ceac]
> onlineapp.d:52 _Dmain [0x3c00c8c3]
> ----
This is pretty awesome.
I ran a couple of experiments and the idiom seems to be lazy as
expected, e.g. in the declaration:
void fun(T)() if (from.std.traits.isIntegral!T)
{
from.std.stdio.writeln("Hallo");
}
neither std.traits nor std.stdio gets loaded if fun is not instantiated.
I took the liberty to ask Razvan Nitu to look into fixing
https://issues.dlang.org/show_bug.cgi?id=17181.
I also asked Eduard Staniloiu to investigate using this idiom internally
in Phobos so as to accumulate some experience with it. Dgame's
implementation is a good start.
Since the implementation would (initially at least) be private, the
presence of "from" in documentation would be awkward. So I suggest the
glorious hack:
alias std = from.std;
so then things like std.traits.isIntegral and
std.algorithm.comparison.min resolve and auto-load properly, while also
standing beautifully in the documentation.
Andrei
More information about the Digitalmars-d
mailing list