Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 24, 2013 Mixin template parameters / mixin template literals | ||||
---|---|---|---|---|
| ||||
Consider: sort!("a > b")(array); This is almost perfect, except for "a > b" being a string instead of "real" code. If "a > b" was an actual block of code it could be syntax highlighted by the editor, directly grammar checked by compiler, etc. The only impediment to that is that a and b are declared in the sort() body scope, so "a > b" has to be mixed-in later in sort(). An alternative is using a lambda: sort!((a, b) => a > b)(array); Now we have code which is directly parsed and highlighted, but it is more verbose (is there any other difference? I suppose there's no performance penalty, because the templated sort() creates a function from the string "a > b" anyway). It would seem that the best of both worlds would be for sort() to specify that the "less" type parameter could be actual code, but that it should be mixed-in inside sort(). Well, since we have lazy parameters, I was wondering why couldn't we have mixin parameters. So I tried this, which works: // create our "a > b" as code (not string) that is mixed-in later mixin template Greater() { auto Greater = () => a > b; } // example of a sort which supports template mixins void foo_sort(alias G = Greater, Range)(Range r) { bool funG(Range)(ElementType!(Range) a, ElementType!(Range) b) { mixin G; return Greater(); // Greater() because G() doesn't work (unhelpful alias, see previous thread) } sort!(funG!(Range))(r); } void main() { int[] array = [3, 1, 5, 2, 7]; foo_sort!(Greater)(array); writefln("%s", array); } So, the infrastructure seems to be there, we just had to declare Greater() outside the sort() call site because we have neither mixin template parameters nor mixin template literals. If we had one of those we could do either: void foo_sort(mixin G, Range)(Range r) { ... } // or mixin template G foo_sort!(a > b)(array); or foo_sort!({a > b})(array); // some kind of mixin template literal Of course, this isn't anything specific to template functions and sort. This is a kind of macro, just like the lazy type specifier, so I it would be useful in other places. OK, so this is probably a bit crazy, but I had to share these thoughts. Feel free to proceed to demolish all of this ;-) |
April 24, 2013 Re: Mixin template parameters / mixin template literals | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | One way this could be done is by expanding on lazy parameters. Perhaps you could specify parameters for a lazy argument, so instead of always getting a delegate of type T delegate(), you could get one of type T delegate(U a, V b). For example, a parameter could be: void f(lazy bool exp(int a, int b)) { bool result = exp(1, 2); } Then when you call that: f(a < b) The names 'a' and 'b' come from the parameter list for 'f'. I would definitely vote for this as a feature! |
April 24, 2013 Re: Mixin template parameters / mixin template literals | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | On Wednesday, 24 April 2013 at 02:18:07 UTC, Luís Marques wrote: > Consider: > > sort!("a > b")(array); > how about? sort!(q{a > b})(array); http://dlang.org/lex.html#TokenString |
April 24, 2013 Re: Mixin template parameters / mixin template literals | ||||
---|---|---|---|---|
| ||||
Posted in reply to Diggory | On 04/24/2013 07:07 PM, Diggory wrote:
> One way this could be done is by expanding on lazy parameters. Perhaps
> you could specify parameters for a lazy argument, so instead of always
> getting a delegate of type T delegate(), you could get one of type T
> delegate(U a, V b).
>
> For example, a parameter could be:
> void f(lazy bool exp(int a, int b)) {
> bool result = exp(1, 2);
> }
>
> Then when you call that:
> f(a < b)
>
> The names 'a' and 'b' come from the parameter list for 'f'. I would
> definitely vote for this as a feature!
This is a little dangerous as it looks like an ordinary expression but has to somehow affect symbol scoping.
|
April 24, 2013 Re: Mixin template parameters / mixin template literals | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tove | Tove:
> how about?
> sort!(q{a > b})(array);
Today we usually write it this way:
array.sort!q{ a > b };
Bye,
bearophile
|
April 24, 2013 Re: Mixin template parameters / mixin template literals | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, 24 April 2013 at 20:50:31 UTC, bearophile wrote:
> Today we usually write it this way:
> array.sort!q{ a > b };
Thanks. (I just copied it from the docs)
|
April 24, 2013 Re: Mixin template parameters / mixin template literals | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Wednesday, 24 April 2013 at 20:32:16 UTC, Timon Gehr wrote:
> On 04/24/2013 07:07 PM, Diggory wrote:
>> One way this could be done is by expanding on lazy parameters. Perhaps
>> you could specify parameters for a lazy argument, so instead of always
>> getting a delegate of type T delegate(), you could get one of type T
>> delegate(U a, V b).
>>
>> For example, a parameter could be:
>> void f(lazy bool exp(int a, int b)) {
>> bool result = exp(1, 2);
>> }
>>
>> Then when you call that:
>> f(a < b)
>>
>> The names 'a' and 'b' come from the parameter list for 'f'. I would
>> definitely vote for this as a feature!
>
> This is a little dangerous as it looks like an ordinary expression but has to somehow affect symbol scoping.
Surely it's no more dangerous than lazy parameters already are. (they are already converted into a hidden delegate, it just happens to take no parameters at the moment)
|
April 24, 2013 Re: Mixin template parameters / mixin template literals | ||||
---|---|---|---|---|
| ||||
Posted in reply to Diggory | On 04/24/2013 11:03 PM, Diggory wrote:
> On Wednesday, 24 April 2013 at 20:32:16 UTC, Timon Gehr wrote:
>> On 04/24/2013 07:07 PM, Diggory wrote:
>>> One way this could be done is by expanding on lazy parameters. Perhaps
>>> you could specify parameters for a lazy argument, so instead of always
>>> getting a delegate of type T delegate(), you could get one of type T
>>> delegate(U a, V b).
>>>
>>> For example, a parameter could be:
>>> void f(lazy bool exp(int a, int b)) {
>>> bool result = exp(1, 2);
>>> }
>>>
>>> Then when you call that:
>>> f(a < b)
>>>
>>> The names 'a' and 'b' come from the parameter list for 'f'. I would
>>> definitely vote for this as a feature!
>>
>> This is a little dangerous as it looks like an ordinary expression but
>> has to somehow affect symbol scoping.
>
> Surely it's no more dangerous than lazy parameters already are. (they
> are already converted into a hidden delegate, it just happens to take no
> parameters at the moment)
It surely is. 'lazy' parameters do not affect symbol lookup in the passed expressions.
|
April 24, 2013 Re: Mixin template parameters / mixin template literals | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Wednesday, 24 April 2013 at 20:32:16 UTC, Timon Gehr wrote: >> Then when you call that: >> f(a < b) > This is a little dangerous as it looks like an ordinary expression but has to somehow affect symbol scoping. That's true, and that was one reason I suggested some kind of template mixin literal. On the other hand, that's just an extreme version of what happens with lazy, where at the call site you can't tell that the argument side effects are not produced immediately. Without experience with features like this it's hard to tell if their usefulness pays for their cost, but it seems to me that something like this could make for very powerful macros. On Wednesday, 24 April 2013 at 17:38:34 UTC, Tove wrote: > how about? > sort!(q{a > b})(array); > > http://dlang.org/lex.html#TokenString I was not aware of the token strings, is that new? Boy, I really should spend more time around here. That's an excellent suggestion, although I think these "mixin parameters" we are discussing are more like mixin template parameters than mixin string parameters. |
April 24, 2013 Re: Mixin template parameters / mixin template literals | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | > Consider:
>
> sort!("a > b")(array);
>
> This is almost perfect, except for "a > b" being a string instead of "real" code. If "a > b" was an actual block of code it could be syntax highlighted by the editor, directly grammar checked by compiler, etc.
Is changing the language the right approach to this or would smarter IDEs possibly be a better direction?
|
Copyright © 1999-2021 by the D Language Foundation