February 13, 2017
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

February 14, 2017
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'
{
}
February 14, 2017
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.
1 2 3 4 5
Next ›   Last »