www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Workaround for DIP 1005

reply Dominikus Dittes Scherkl <Dominikus.Scherkl continental-corporation.com> writes:
DIP 1005 provides new syntax to make it possible to avoid global 
imports.
Till now global imports are necessary if a function uses types 
declared in some imported module within it's declaration or 
definition (otherwise a local import will do).

But this can already be worked around with some nice trick:

import someModule.SomeType;

SomeType fun()
{
    ...
}

can be replaced by:

fun.ST fun()
{
    import someModule.SomeType;
    alias ST = SomeType;
    ...
}

The same strategy works with types used in parameters or 
constraints, of course.

Any thoughts?
Feb 03
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 04/02/2017 3:43 AM, Dominikus Dittes Scherkl wrote:
 DIP 1005 provides new syntax to make it possible to avoid global imports.
 Till now global imports are necessary if a function uses types declared
 in some imported module within it's declaration or definition (otherwise
 a local import will do).

 But this can already be worked around with some nice trick:

 import someModule.SomeType;

 SomeType fun()
 {
    ...
 }

 can be replaced by:

 fun.ST fun()
 {
    import someModule.SomeType;
    alias ST = SomeType;
    ...
 }

 The same strategy works with types used in parameters or constraints, of
 course.

 Any thoughts?
Needless syntax sugar: struct Foo { int x; } Foo func() { return Foo(9); } typeof(func()) func2() { return func(); } void main() { assert(func2.x == 9); }
Feb 03
parent Dominikus Dittes Scherkl <Dominikus.Scherkl continental-corporation.com> writes:
On Friday, 3 February 2017 at 14:59:09 UTC, rikki cattermole 
wrote:
 On 04/02/2017 3:43 AM, Dominikus Dittes Scherkl wrote:
 DIP 1005 provides new syntax to make it possible to avoid 
 global imports.
 But this can already be worked around with some nice trick:
 Any thoughts?
Needless syntax sugar:
?!? What is syntactic sugar? I did NOT propose any new syntax - my workaround already works with the current D language. In fact I think DIP1005 is syntactic sugar (maybe even "needless").
Feb 03
prev sibling next sibling parent reply Daniel N <ufo orbiting.us> writes:
On Friday, 3 February 2017 at 14:43:01 UTC, Dominikus Dittes 
Scherkl wrote:
 DIP 1005 provides new syntax to make it possible to avoid 
 global imports.
 Any thoughts?
I like it! template imp(string mod) { mixin("import imp = " ~ mod ~ ";"); } auto fun_time(imp!"std.datetime".SysTime tm) { return tm; } void main() { import std.stdio; import std.datetime; fun_time(Clock.currTime()).writeln; }
Feb 03
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/3/17 10:41 AM, Daniel N wrote:
 On Friday, 3 February 2017 at 14:43:01 UTC, Dominikus Dittes Scherkl wrote:
 DIP 1005 provides new syntax to make it possible to avoid global imports.
 Any thoughts?
I like it! template imp(string mod) { mixin("import imp = " ~ mod ~ ";"); } auto fun_time(imp!"std.datetime".SysTime tm) { return tm; } void main() { import std.stdio; import std.datetime; fun_time(Clock.currTime()).writeln; }
Wow. This is... brilliant. Thanks for the great idea. I ran a few tests and it seems to be doing out of the box most of what we want with DIP1005 with no language change at all. Congratulations! Andrei
Feb 03
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/3/17 2:14 PM, Andrei Alexandrescu wrote:
 On 2/3/17 10:41 AM, Daniel N wrote:
 On Friday, 3 February 2017 at 14:43:01 UTC, Dominikus Dittes Scherkl
 wrote:
 DIP 1005 provides new syntax to make it possible to avoid global
 imports.
 Any thoughts?
I like it! template imp(string mod) { mixin("import imp = " ~ mod ~ ";"); } auto fun_time(imp!"std.datetime".SysTime tm) { return tm; } void main() { import std.stdio; import std.datetime; fun_time(Clock.currTime()).writeln; }
Wow. This is... brilliant. Thanks for the great idea. I ran a few tests and it seems to be doing out of the box most of what we want with DIP1005 with no language change at all. Congratulations!
I should also extend thanks to Dominik, who provided the initial idea and the inspiration for this one. -- Andrei
Feb 03
prev sibling next sibling parent reply Daniel Nielsen <daniel.nielsen.se gmail.com> writes:
On Friday, 3 February 2017 at 19:14:16 UTC, Andrei Alexandrescu 
wrote:
 Wow. This is... brilliant. Thanks for the great idea. I ran a 
 few tests and it seems to be doing out of the box most of what 
 we want with DIP1005 with no language change at all.

 Congratulations!


 Andrei
Thank you very much. I was just going to mail you directly to make sure the idea wasn't lost in the forum flood, will be exciting to see some measurements using this idiom. Daniel N
Feb 03
parent reply Daniel Nielsen <daniel.nielsen.se gmail.com> writes:
On Friday, 3 February 2017 at 20:04:22 UTC, Daniel Nielsen wrote:
 On Friday, 3 February 2017 at 19:14:16 UTC, Andrei Alexandrescu 
 wrote:
 Wow. This is... brilliant. Thanks for the great idea. I ran a 
 few tests and it seems to be doing out of the box most of what 
 we want with DIP1005 with no language change at all.

 Congratulations!


 Andrei
I just had to try one more thing. It never ceases to amaze me what is possible in D today. template imp(string mod) { mixin("import imp = " ~ mod ~ ";"); } auto fun_time(imp!"std.datetime".SysTime tm) { return tm; } void main() { with(imp!"std.datetime") static if(is(Clock)) with(imp!"std.stdio") Clock.currTime.fun_time.writeln; }
Feb 03
parent reply crimaniak <crimaniak gmail.com> writes:
On Friday, 3 February 2017 at 21:23:22 UTC, Daniel Nielsen wrote:

 I just had to try one more thing. It never ceases to amaze me 
 what is possible in D today.
Yes, all except of good IDE and tooling.
 template imp(string mod) { mixin("import imp = " ~ mod ~ ";"); }
... because of string mixins.
Feb 04
parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Saturday, 4 February 2017 at 11:50:50 UTC, crimaniak wrote:
 On Friday, 3 February 2017 at 21:23:22 UTC, Daniel Nielsen 
 wrote:

 I just had to try one more thing. It never ceases to amaze me 
 what is possible in D today.
Yes, all except of good IDE and tooling.
 template imp(string mod) { mixin("import imp = " ~ mod ~ ";"); 
 }
... because of string mixins.
please refrain from insulting string-mixins. they are by far the most understandable of meta-programming facilities.
Feb 04
parent crimaniak <crimaniak gmail.com> writes:
On Saturday, 4 February 2017 at 11:56:52 UTC, Stefan Koch wrote:

 please refrain from insulting string-mixins.
 they are by far the most understandable of meta-programming 
 facilities.
Most understandable don't mean "good to use". We can do many things with it but it's really hack and easy way to obscure code and prevent any automatic analysis of it. Because when we have string mixin in code - any tool should become a compiler to work with it. So my opinion: they must be avoided as much as possible.
Feb 04
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 2/3/2017 11:14 AM, Andrei Alexandrescu wrote:
 On 2/3/17 10:41 AM, Daniel N wrote:
 On Friday, 3 February 2017 at 14:43:01 UTC, Dominikus Dittes Scherkl wrote:
 DIP 1005 provides new syntax to make it possible to avoid global imports.
 Any thoughts?
I like it! template imp(string mod) { mixin("import imp = " ~ mod ~ ";"); } auto fun_time(imp!"std.datetime".SysTime tm) { return tm; } void main() { import std.stdio; import std.datetime; fun_time(Clock.currTime()).writeln; }
Wow. This is... brilliant. Thanks for the great idea. I ran a few tests and it seems to be doing out of the box most of what we want with DIP1005 with no language change at all. Congratulations!
I agree, it's pretty dazz! We need to give this technique a memorable name (not an acronym). I thought "Voldemort Types" turned out rather well, whereas CTFE is klunky, UFCS is even worse. The absolute worst is C++ SFINAE. Any ideas? Scherkl-Nielsen Lookup? The perfect bikeshedding moment! Daniel, Dominikus: please consider writing an article about this.
Feb 03
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 02/03/2017 03:33 PM, Walter Bright wrote:

 On 2/3/17 10:41 AM, Daniel N wrote:
 auto fun_time(imp!"std.datetime".SysTime tm)
 We need to give this technique a memorable name (not an acronym).
If it's going to stay "imp" (which I initially found confusing; How about "Import"?), "the imp idiom" might do but imps have a very insignificant appearance in Harry Potter. (There are "Pepper Imps sold at Honeydukes in Hogsmeade".) Ali
Feb 03
next sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 02/03/2017 06:50 PM, Ali Çehreli wrote:
 "the imp idiom" might do but imps have a very
 insignificant appearance in Harry Potter.
But they have much significance in Doom :) ...part of which takes place on Phobos ;)
Feb 03
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/3/17 6:50 PM, Ali Çehreli wrote:
 On 02/03/2017 03:33 PM, Walter Bright wrote:

 On 2/3/17 10:41 AM, Daniel N wrote:
 auto fun_time(imp!"std.datetime".SysTime tm)
 We need to give this technique a memorable name (not an acronym).
If it's going to stay "imp" (which I initially found confusing; How about "Import"?), "the imp idiom" might do but imps have a very insignificant appearance in Harry Potter. (There are "Pepper Imps sold at Honeydukes in Hogsmeade".) Ali
https://github.com/dlang/druntime/pull/1756 -- Andrei
Feb 04
prev sibling next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Friday, 3 February 2017 at 23:33:58 UTC, Walter Bright wrote:
 I agree, it's pretty dazz! We need to give this technique a 
 memorable name (not an acronym). I thought "Voldemort Types" 
 turned out rather well, whereas CTFE is klunky, UFCS is even 
 worse. The absolute worst is C++ SFINAE.

 Any ideas?

   Scherkl-Nielsen Lookup?

 The perfect bikeshedding moment!

 Daniel, Dominikus: please consider writing an article about 
 this.
That's obviously a self important lookup.
Feb 03
parent reply David Gileadi <gileadis NSPMgmail.com> writes:
On 2/3/17 5:00 PM, deadalnix wrote:
 On Friday, 3 February 2017 at 23:33:58 UTC, Walter Bright wrote:
 I agree, it's pretty dazz! We need to give this technique a memorable
 name (not an acronym). I thought "Voldemort Types" turned out rather
 well, whereas CTFE is klunky, UFCS is even worse. The absolute worst
 is C++ SFINAE.

 Any ideas?

   Scherkl-Nielsen Lookup?

 The perfect bikeshedding moment!

 Daniel, Dominikus: please consider writing an article about this.
That's obviously a self important lookup.
This. So much this.
Feb 04
parent reply deadalnix <deadalnix gmail.com> writes:
On Saturday, 4 February 2017 at 23:54:12 UTC, David Gileadi wrote:
 That's obviously a self important lookup.
This. So much this.
I'm afraid you are the only one who appreciate my humor :)
Feb 07
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 02/07/2017 04:28 PM, deadalnix wrote:
 On Saturday, 4 February 2017 at 23:54:12 UTC, David Gileadi wrote:
 That's obviously a self important lookup.
This. So much this.
I'm afraid you are the only one who appreciate my humor :)
"self-important" is official now: https://dlang.org/blog/2017/02/13/a-new-import-idiom/ Ali
Feb 13
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/3/17 6:33 PM, Walter Bright wrote:
 Daniel, Dominikus: please consider writing an article about this.
That would be indeed very very useful. -- Andrei
Feb 04
parent Daniel Nielsen <daniel.nielsen.se gmail.com> writes:
On Saturday, 4 February 2017 at 14:57:59 UTC, Andrei Alexandrescu 
wrote:
 On 2/3/17 6:33 PM, Walter Bright wrote:
 Daniel, Dominikus: please consider writing an article about 
 this.
That would be indeed very very useful. -- Andrei
Okay, I will. However I currently have some obligations which demand my full attention, I estimate having a first draft ready by next weekend. Daniel
Feb 05
prev sibling parent reply Dominikus Dittes Scherkl <Dominikus.Scherkl continental-corporation.com> writes:
On Friday, 3 February 2017 at 23:33:58 UTC, Walter Bright wrote:
 On 2/3/2017 11:14 AM, Andrei Alexandrescu wrote:
 On 2/3/17 10:41 AM, Daniel N wrote:
 On Friday, 3 February 2017 at 14:43:01 UTC, Dominikus Dittes 
 Scherkl wrote:
 DIP 1005 provides new syntax to make it possible to avoid 
 global imports.
 Any thoughts?
I like it!
Wow. This is... brilliant. Thanks for the great idea. I ran a few tests and it seems to be doing out of the box most of what we want with DIP1005 with no language change at all. Congratulations!
I agree, it's pretty dazz! We need to give this technique a memorable name (not an acronym). I thought "Voldemort Types" turned out rather well, whereas CTFE is klunky, UFCS is even worse. The absolute worst is C++ SFINAE. Any ideas? Scherkl-Nielsen Lookup? The perfect bikeshedding moment! Daniel, Dominikus: please consider writing an article about this.
Thank you all that you like the idea. I found myself using this idiom quite some time now in my libraries but only recently realized, that it is the reason why I didn't found DIP1005 too compelling - I just didn't need it because of my workaround. So I thought I should share the idea - and Daniels extension makes it much easier to use. Have to update my libs with that :-) But is this really worth an article?
Feb 06
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Monday, 6 February 2017 at 08:45:45 UTC, Dominikus Dittes 
Scherkl wrote:

 But is this really worth an article?
IMO, as something targeted at non-D users, yes. A brief overview of D's module system, a description of the problem & how the DIP was brought up to address it, how the DIP was made irrelevant by the usage of features every D programmer knows by so many failed to realize could be used in this way... lots of meat for a post there. I'd be happy to publish something like that on the D Blog.
Feb 06
parent reply Dominikus Dittes Scherkl <Dominikus.Scherkl continental-corporation.com> writes:
On Monday, 6 February 2017 at 09:00:43 UTC, Mike Parker wrote:
 On Monday, 6 February 2017 at 08:45:45 UTC, Dominikus Dittes 
 Scherkl wrote:

 But is this really worth an article?
IMO, as something targeted at non-D users, yes.
Oh yeah? For bragging about how D uses modules and doesn't need global imports at all? This is not my style and I didn't feel that not needing global imports is something to brag about - they are useful as an overview. But with this new idiom .di-files are even more useless now - or really need to declare all the local imports to replace the lost overview.
 A brief overview of D's module system, a description of the
 problem & how the DIP was brought up to address it,
But I'm not an expert for this. Especially I was not aware of any problem and even didn't liked the DIP.
 how the DIP was made irrelevant by the usage of features
 every D programmer knows but so many failed to realize could
 be used in this way...
Ok, this is the most interesting part. This is what having an idea is all about. Find new ways to put the things already there together. But hard to describe. Maybe I'll give it a try.
Feb 06
parent Mike Parker <aldacron gmail.com> writes:
On Monday, 6 February 2017 at 09:39:25 UTC, Dominikus Dittes 
Scherkl wrote:
 On Monday, 6 February 2017 at 09:00:43 UTC, Mike Parker wrote:
 On Monday, 6 February 2017 at 08:45:45 UTC, Dominikus Dittes 
 Scherkl wrote:

 But is this really worth an article?
IMO, as something targeted at non-D users, yes.
Oh yeah? For bragging about how D uses modules and doesn't need global imports at all?
No, that's not quite my intent. There's an interesting story here beyond the feature itself that I believe makes for a good blog post. The majority of visitors to the blog are not D users and aren't going to be familiar with the details (like the different ways a module can be imported), so such an article needs to keep them in mind.
Feb 06
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 2/6/2017 12:45 AM, Dominikus Dittes Scherkl wrote:
 But is this really worth an article?
It's ideally suited for an article. It's easy to grasp, and enables a very interesting idiom.
Feb 06
parent TheGag96 <thegag96 gmail.com> writes:
On Monday, 6 February 2017 at 11:03:32 UTC, Walter Bright wrote:
 On 2/6/2017 12:45 AM, Dominikus Dittes Scherkl wrote:
 But is this really worth an article?
It's ideally suited for an article. It's easy to grasp, and enables a very interesting idiom.
I personally think the idiom is neato and think it'd be a neat article! It could potentially inspire wonder in some non-D-users about the limitless possibilities of the language... Or scare some away. :V The idiom would pretty bizarre for newcomers lol.
Feb 06
prev sibling parent reply Andrea Fontana <nospam example.com> writes:
On Friday, 3 February 2017 at 15:41:56 UTC, Daniel N wrote:
 On Friday, 3 February 2017 at 14:43:01 UTC, Dominikus Dittes 
 Scherkl wrote:
 DIP 1005 provides new syntax to make it possible to avoid 
 global imports.
 Any thoughts?
I like it! template imp(string mod) { mixin("import imp = " ~ mod ~ ";"); } auto fun_time(imp!"std.datetime".SysTime tm) { return tm; } void main() { import std.stdio; import std.datetime; fun_time(Clock.currTime()).writeln; }
I don't understand why we can't use a template like: auto fun_time(SysTime)(SysTime tm) { import std.datetime; static assert (is(SysTime == std.datetime.SysTime)); return tm; } void main() { import std.stdio; import std.datetime; fun_time(Clock.currTime()).writeln; } I think I missed something.
Feb 07
next sibling parent Jack Stouffer <jack jackstouffer.com> writes:
On Tuesday, 7 February 2017 at 15:00:17 UTC, Andrea Fontana wrote:
 I don't understand why we can't use a template like:

 auto fun_time(SysTime)(SysTime tm)
 {
     import std.datetime;
     static assert (is(SysTime == std.datetime.SysTime));
     return tm;
 }

 void main()
 {
   import std.stdio;
   import std.datetime;

   fun_time(Clock.currTime()).writeln;
 }

 I think I missed something.
Because Systime's are used in the signiture, a local import cannot be used. Local imports are only evaluated if the function is used in the program and are local to that scope. Therefore, when the signitures are being evaluated, the compiler has no information about std.datetime, and therefore fails with a symbol not found error.
Feb 07
prev sibling next sibling parent Jack Stouffer <jack jackstouffer.com> writes:
On Tuesday, 7 February 2017 at 15:00:17 UTC, Andrea Fontana wrote:
 ...
I think I misunderstood your comment. Please forgive the noise. I need more coffee
Feb 07
prev sibling next sibling parent Chris Wright <dhasenan gmail.com> writes:
On Tue, 07 Feb 2017 15:00:17 +0000, Andrea Fontana wrote:
 I don't understand why we can't use a template like:
You can. However, that makes things awkward when you want to pass that as a delegate. It makes it awkward to read. You don't get to specify the return type unless it happens to be the same as a parameter type. A near equivalent is: template extractDate() { import std.datetime; Date extractDate(SysTime time) { return time.date; } } Better type checking, but you need to refer to it as `extractDate!()` sometimes. That's still better than having to refer to it as `extractDate! (SysTime)`.
Feb 07
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 2/7/2017 7:00 AM, Andrea Fontana wrote:
 I don't understand why we can't use a template like:

 auto fun_time(SysTime)(SysTime tm)
 {
     import std.datetime;
     static assert (is(SysTime == std.datetime.SysTime));
     return tm;
 }

 void main()
 {
   import std.stdio;
   import std.datetime;

   fun_time(Clock.currTime()).writeln;
 }
It's an interesting idea, but it will have problems with overloading, as the template selection will match on everything.
Feb 07
prev sibling next sibling parent Chris Wright <dhasenan gmail.com> writes:
On Fri, 03 Feb 2017 14:43:01 +0000, Dominikus Dittes Scherkl wrote:
 fun.ST fun()
 {
     import someModule.SomeType;
     alias ST = SomeType;
     ...
 }
What compiler version is this? I'm getting segfaults with both 2.072.2 and 2.073.0. Reported as https://issues.dlang.org/show_bug.cgi?id=17140
Feb 03
prev sibling next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 02/03/2017 06:43 AM, Dominikus Dittes Scherkl wrote:
 DIP 1005 provides new syntax to make it possible to avoid global imports.
I haven't followed DIP 1005 closely. Has there been any discussion of automatic imports that seems to have potential to make both the user's and implementor's lives easier: void foo(std.datetime.Duration dur) { // ... } Can the compiler automatically import std.datetime for both the implementation above and the user? Or, too much beer at work on this Friday? :o) Ali
Feb 03
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 2/3/2017 4:01 PM, Ali Çehreli wrote:
 void foo(std.datetime.Duration dur) {
     // ...
 }

 Can the compiler automatically import std.datetime for both the implementation
 above and the user? Or, too much beer at work on this Friday? :o)
How does the compiler know that "std" is supposed to be an import rather than a misspelling of a previously declared "stc" ?
Feb 03
parent crimaniak <crimaniak gmail.com> writes:
On Saturday, 4 February 2017 at 00:43:14 UTC, Walter Bright wrote:
 On 2/3/2017 4:01 PM, Ali Çehreli wrote:
 void foo(std.datetime.Duration dur) {
     // ...
 }

 Can the compiler automatically import std.datetime for both 
 the implementation
 above and the user? Or, too much beer at work on this Friday? 
 :o)
How does the compiler know that "std" is supposed to be an import rather than a misspelling of a previously declared "stc" ?
std.datetime exists. I think, allowing fully qualified names and automatic importing of used fully qualified names will be much, much better, than introduction of string mixins literally everywhere. Woody_and_Buzz_jpg!"String mixins! They are everywhere!"
Feb 04
prev sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Friday, February 03, 2017 14:43:01 Dominikus Dittes Scherkl via 
Digitalmars-d wrote:
 Any thoughts?
This is really cool, but I have a couple of concerns about this and how it seems deficient in comparison to DIP 1005. I mentioned it in Andrei's PR for this, but no one has responded to my comment. This first problem is UFCS. While this technique works great for parameters or on types you want to list in the template constraint, I don't see how it can work with UFCS. So, if you have something like auto func(alias pred, R)(R range) if(isInputRange!R && is(typeof(pred(range.front)) == bool)) {...} you can do auto func(alias pred, R)(R range) if(from!"std.range.primitives".isInputRange!R && is(typeof(pred(range.front)) == bool)) {...} but you can't import std.range.primitives.front to make dynamic arrays work, whereas with DIP 1005, you can just add the import to the function declaration, and it will work without having to tie the import to a specific symbol. And while in many cases, you can just forgo UFCS - e.g. auto func(P)(P param) if(is(typeof(from!"std.algorithm".find(param)) == param)) {...} that not only doesn't work with the range primitives, but it's bad practice to use UFCS in the function body and not the template constraint (since the semantics may not be the same), meaning that not using UFCS in the template constraint means not using it in the function body for anything that's in the template constraint (which many folks won't like and others won't understand, resulting in subtle bugs), and any case where you want a function to work with types that define a function as a member function as well as with types that use a free function, you need to use UFCS and thus cannot choose to not use it in the template constraint. So, unless there's something that I don't understand about this technique (which is definitely possible), it seems like it does not work with UFCS and thus makes it considerably worse than 1005 for a lot of templated code, much as it would work great for code that doesn't need UFCS. The other problem is how much more verbose it is. With DIP 1005, you can do with(import std.datetime) auto foo(SysTime st1, SysTime st2, Duration d); The import is only listed once, whereas with this technique, you have to list it for each symbol. e.g. auto foo(from!"std.datetime".SysTime st1, from!"std.datetime".SysTime st2, from!"std.datetime".Duration d); The result is much more verbose, and if you have several symbols that need imports between the return type, parameters, and template constraint, you quickly end up with a lot of extra text in the middle of your function signatures just because you want to tie the imports to the functions that use them. With DIP 1005, the imports are next to the function but separate where they avoid the need for repeating imports and don't get mixed into the middle of the function signature. So, while the proposed technique is really cool and clever in what it lets us do without actually altering the language, it seems like it's quite a bit worse than DIP 1005. As such, I'm inclined to argue that we should favor DIP 1005 over this proposal, as cool as it is. - Jonathan M Davis
Feb 08
next sibling parent Daniel N <no public.email> writes:
On Thursday, 9 February 2017 at 05:40:01 UTC, Jonathan M Davis 
wrote:
 The import is only listed once, whereas with this technique, 
 you have to list it for each symbol. e.g.

 auto foo(from!"std.datetime".SysTime st1,
          from!"std.datetime".SysTime st2,
          from!"std.datetime".Duration d);

 The result is much more verbose, and if you have several 
 symbols that need imports between the return type, parameters, 
 and template constraint, you quickly end up with a lot of extra 
 text in the middle of your function signatures just because you 
 want to tie the imports to the functions that use them.
 - Jonathan M Davis
Thank you for your insightful feedback, I'm currently pressed for time but I can at least begin to address one of your concerns. Every proposed solution has some sort of tradeoff, verbosity could be dealt with for the price of turning a simple function into a template. In some cases this could be acceptable in others prohibitive. auto foo(alias dt = from!"std.datetime") (dt.SysTime st1, dt.SysTime st2, dt.Duration d) Our "Implicit Function-Template Instantiation" also unfortunately bails with default arguments... maybe there is an enhancement request for that already? (from!"std.datetime") almost works too(it would avoid turning the function into a template), but has other issues.
Feb 09
prev sibling next sibling parent reply Dominikus Dittes Scherkl <Dominikus.Scherkl continental-corporation.com> writes:
On Thursday, 9 February 2017 at 05:40:01 UTC, Jonathan M Davis 
wrote:
 On Friday, February 03, 2017 14:43:01 Dominikus Dittes Scherkl 
 via Digitalmars-d wrote:
 Any thoughts?
This is really cool, but I have a couple of concerns about this and how it seems deficient in comparison to DIP 1005.
Of course. This is why I called it a "workaround". But in fact I would prefer to only use local imports instead of some impoting template. But with this workaround in mind, the implementation of DIP1005 would be much easier (see below).
 [...]
 The other problem is how much more verbose it is. With DIP 
 1005, you can do

 with(import std.datetime)
 auto foo(SysTime st1, SysTime st2, Duration d);

 The import is only listed once, whereas with this technique, 
 you have to list it for each symbol. e.g.

 auto foo(from!"std.datetime".SysTime st1,
          from!"std.datetime".SysTime st2,
          from!"std.datetime".Duration d);
With my original proposal you would write auto foo(foo.M.SysTime st1, foo.M.SysTime st2, foo.M.Duration d) { import std.datetime; }
Feb 10
parent Dominikus Dittes Scherkl <Dominikus.Scherkl continental-corporation.com> writes:
On Friday, 10 February 2017 at 13:28:43 UTC, Dominikus Dittes 
Scherkl wrote:
Sorry, accidentally hit some key-combination that immediately 
send the message that was not yet complete.

 With my original proposal you would write

 auto foo(foo.SysTime st1,
          foo.SysTime st2,
          foo.Duration d)
 {
    import std.datetime;
alias SysTime = std.datetime.SysTime; alias Duration = std.datetime.Duration;
 }
And the implementation of DIP1005 would only "create this alias automatically", so that you would write what you always did - if any type in a declaration is not found, the compiler tries to find it in the function definition and use that instead. Therefore I would call this "auto aliasing" It does not inquire a (visible) language change, only an enhanced lookup within the compiler.
Feb 10
prev sibling next sibling parent Nick Treleaven <nick geany.org> writes:
On Thursday, 9 February 2017 at 05:40:01 UTC, Jonathan M Davis 
wrote:
 auto func(alias pred, R)(R range)
     if(from!"std.range.primitives".isInputRange!R &&
        is(typeof(pred(range.front)) == bool))
 {...}

 but you can't import std.range.primitives.front to make dynamic 
 arrays work, whereas with DIP 1005, you can just add the import 
 to the function declaration, and it will work without having to 
 tie the import to a specific symbol.
That's a problem with UFCS in general. Workaround: import std.functional; import std.range; void main(){ auto r = [1]; auto i = r.unaryFun!(std.range.front); assert(i == 1); } As an enhancement, it seems supporting value.(callable) would work: range.(std.range.front) That would be generally useful: // print reciprocal of reduced range range.reduce!someFunc.(n => 1 / n).writeln;
 The other problem is how much more verbose it is. With DIP 
 1005, you can do

 with(import std.datetime)
 auto foo(SysTime st1, SysTime st2, Duration d);

 The import is only listed once, whereas with this technique, 
 you have to list it for each symbol.
That's a problem only when very few of a module's declarations need more than one symbol from the same module. How often does that occur when a module-level import should be avoided?
Feb 10
prev sibling next sibling parent Meta <jared771 gmail.com> writes:
On Thursday, 9 February 2017 at 05:40:01 UTC, Jonathan M Davis 
wrote:
 On Friday, February 03, 2017 14:43:01 Dominikus Dittes Scherkl 
 via Digitalmars-d wrote:
 Any thoughts?
This is really cool, but I have a couple of concerns about this and how it seems deficient in comparison to DIP 1005. I mentioned it in Andrei's PR for this, but no one has responded to my comment. This first problem is UFCS. While this technique works great for parameters or on types you want to list in the template constraint, I don't see how it can work with UFCS. So, if you have something like auto func(alias pred, R)(R range) if(isInputRange!R && is(typeof(pred(range.front)) == bool)) {...} you can do auto func(alias pred, R)(R range) if(from!"std.range.primitives".isInputRange!R && is(typeof(pred(range.front)) == bool)) {...} but you can't import std.range.primitives.front to make dynamic arrays work, whereas with DIP 1005, you can just add the import to the function declaration, and it will work without having to tie the import to a specific symbol. And while in many cases, you can just forgo UFCS - e.g. auto func(P)(P param) if(is(typeof(from!"std.algorithm".find(param)) == param)) {...} that not only doesn't work with the range primitives, but it's bad practice to use UFCS in the function body and not the template constraint (since the semantics may not be the same), meaning that not using UFCS in the template constraint means not using it in the function body for anything that's in the template constraint (which many folks won't like and others won't understand, resulting in subtle bugs), and any case where you want a function to work with types that define a function as a member function as well as with types that use a free function, you need to use UFCS and thus cannot choose to not use it in the template constraint. So, unless there's something that I don't understand about this technique (which is definitely possible), it seems like it does not work with UFCS and thus makes it considerably worse than 1005 for a lot of templated code, much as it would work great for code that doesn't need UFCS. The other problem is how much more verbose it is. With DIP 1005, you can do with(import std.datetime) auto foo(SysTime st1, SysTime st2, Duration d); The import is only listed once, whereas with this technique, you have to list it for each symbol. e.g. auto foo(from!"std.datetime".SysTime st1, from!"std.datetime".SysTime st2, from!"std.datetime".Duration d); The result is much more verbose, and if you have several symbols that need imports between the return type, parameters, and template constraint, you quickly end up with a lot of extra text in the middle of your function signatures just because you want to tie the imports to the functions that use them. With DIP 1005, the imports are next to the function but separate where they avoid the need for repeating imports and don't get mixed into the middle of the function signature. So, while the proposed technique is really cool and clever in what it lets us do without actually altering the language, it seems like it's quite a bit worse than DIP 1005. As such, I'm inclined to argue that we should favor DIP 1005 over this proposal, as cool as it is. - Jonathan M Davis
It's a hack on top of a hack, but you can do something like this: void test(T1, T2, alias isIntegral = from!"std.traits".isIntegral,(T1 t1, T2 t2) if (isIntegral!T1 && isIntegral!T2) { pragma(msg, isIntegral!T1); pragma(msg, isIntegral!T2); } void main() { } The only problem is that it allows a user to supply their own value for isIntegral, which can lead to some weird error messages and confusion if they don't know about this idiom. Also it can't quite do UFCS, because you cannot use UFCS with local symbols: void test(T1, T2, alias isIntegral = from!"std.traits".isIntegral, alias chop = from!"std.string".chop) (T1 t1, T2 t2) if (isIntegral!T1 && isIntegral!T2 && T1.stringof.chop() == "ubyt") //Error: no property 'chop' for type 'string' { }
Feb 14
prev sibling parent John Colvin <john.loughran.colvin gmail.com> writes:
On Thursday, 9 February 2017 at 05:40:01 UTC, Jonathan M Davis 
wrote:
 with(import std.datetime)
 auto foo(SysTime st1, SysTime st2, Duration d);
There is of course the middle way: with(from!q{std.datetime}) I would love to be able to use `with` and have the language accept it in a wider range of places (e.g. module scope, on expressions), but in its current form it's a statement and introduces a scope, the inconsistency would be unpleasant.
Feb 14