Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 07, 2014 A Briefer Syntax for Using Concepts | ||||
---|---|---|---|---|
| ||||
Here is a question, is it possible for D, or any future language, to eventually take something like this... void foo(InputRange)(InputRange range) if(isInputRange!InputRange); ...and to instead be able to write it like this? void foo(InputRange range); Where the latter expands into something like the former, and InputRange is not a type. How to declare such a thing in the first place doesn't matter that much. There are many ways that could be done. I'm just wondering if the above is possible at all. |
May 07, 2014 Re: A Briefer Syntax for Using Concepts | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On Wednesday, 7 May 2014 at 11:57:51 UTC, w0rp wrote:
> Here is a question, is it possible for D, or any future language, to eventually take something like this...
>
> void foo(InputRange)(InputRange range) if(isInputRange!InputRange);
>
> ...and to instead be able to write it like this?
>
> void foo(InputRange range);
>
> Where the latter expands into something like the former, and InputRange is not a type. How to declare such a thing in the first place doesn't matter that much. There are many ways that could be done. I'm just wondering if the above is possible at all.
I sense a polymorphic compile-time-only type system.
|
May 07, 2014 Re: A Briefer Syntax for Using Concepts | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On Wednesday, 7 May 2014 at 11:57:51 UTC, w0rp wrote: > Here is a question, is it possible for D, or any future language, to eventually take something like this... > > void foo(InputRange)(InputRange range) if(isInputRange!InputRange); > > ...and to instead be able to write it like this? > > void foo(InputRange range); > > Where the latter expands into something like the former, and InputRange is not a type. How to declare such a thing in the first place doesn't matter that much. There are many ways that could be done. I'm just wondering if the above is possible at all. C++ concepts has similar syntax. http://isocpp.org/blog/2013/02/concepts-lite-constraining-templates-with-predicates-andrew-sutton-bjarne-s template<Sortable Cont> void sort(Cont& container); I don't think making InputRange behave as you suggest in void foo(InputRange range); is a valid options, since - how do you handle the situation when you want to accept 2 InputRanges of possibly distinct types? void foo(InputRange range1, InputRange range2); // how to specify that InputRange should be exactly the same type? or possibly distinct types? |
May 07, 2014 Re: A Briefer Syntax for Using Concepts | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On Wednesday, 7 May 2014 at 11:57:51 UTC, w0rp wrote:
> Here is a question, is it possible for D, or any future language, to eventually take something like this...
>
> void foo(InputRange)(InputRange range) if(isInputRange!InputRange);
>
> ...and to instead be able to write it like this?
>
> void foo(InputRange range);
>
> Where the latter expands into something like the former, and InputRange is not a type. How to declare such a thing in the first place doesn't matter that much. There are many ways that could be done. I'm just wondering if the above is possible at all.
I think Julia does something like this, under the hood. Julia functions are instantiated once for every concrete argument type tuple they are invoked with:
f(x) = x + 2
f(5) # Instantiation for Int64
f(5.0) # Instantiation for Float64
The assembly for these instantiations can be inspected by calling `code_native`. This works well for Julia because its runtime and type system are designed around being able to do this (JIT compilation, multiple dispatch, duck typing, immutable types).
Programmers try to use run-time and compile-time polymorphism for the same thing: expressing operations on abstract types. But, each approach has its own advantage (CT: speed; RT: dynamic dispatch). I think the key insight is that the optimal implementation (RT vs. CT) depends only on how the generic function is used, not how it is defined. So, the choice of implementation can, in theory, be left up to a sufficiently-sophisticated runtime/JIT compiler. This seems to be what Julia has done (possibly along with some other Lispy languages; I'm not sure).
However, this scheme can't entirely replace D-style templates (e.g. pattern matching). So, Julia still lets you define templates (which they call "objects with static parameters").
It would be great to have something like this in D (with compile-time semantics, of course).
|
May 07, 2014 Re: A Briefer Syntax for Using Concepts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergei Nosov | Sergei Nosov:
> void foo(InputRange range1, InputRange range2); // how to specify that InputRange should be exactly the same type? or possibly distinct types?
I think the Concepts lite proposal faces this problem too. Take a look.
But so far Andrei was against the idea of having lite concepts in D (I am not sure why).
Bye,
bearophile
|
May 07, 2014 Re: A Briefer Syntax for Using Concepts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergei Nosov | On Wednesday, 7 May 2014 at 12:47:29 UTC, Sergei Nosov wrote:
> void foo(InputRange range1, InputRange range2); // how to specify that InputRange should be exactly the same type? or possibly distinct types?
One thing to consider would be that InputRange wouldn't be a type itself, but range1 and range2 would have types. I suppose you do do things like if(typeof(range1) == typeof(range2)) and so on.
|
May 07, 2014 Re: A Briefer Syntax for Using Concepts | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On 5/7/14, w0rp via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> void foo(InputRange range);
How to make it accept multiple types? Simple, we already have template constraints, so this would be how to do it, where T is the element type of the input range:
void foo(T)(InputRange!T range);
|
May 07, 2014 Re: A Briefer Syntax for Using Concepts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Orvid King | > void foo(T)(InputRange!T range);
Clever. Shouldn't we all, including Phobos, use this shorter syntax instead?
Further, we could always do
alias R = InputRange!T;
or
alias R = typeof(range);
inside the body if needed.
|
May 07, 2014 Re: A Briefer Syntax for Using Concepts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Orvid King | > void foo(T)(InputRange!T range); Update: Ahh, it seems this syntax is currently accepted by DMD. Should it be? Original function: import std.range: isInputRange; bool allEqual(R)(R range) @safe pure nothrow if (isInputRange!R) { import std.algorithm: findAdjacent; import std.range: empty; return range.findAdjacent!("a != b").empty; } unittest { assert([11, 11].allEqual); } unittest { assert(![11, 12].allEqual); } unittest { int[] x; assert(x.allEqual); } compiles. New function: import std.range: InputRange; bool allEqual_(T)(InputRange!T range) @safe pure nothrow { import std.algorithm: findAdjacent; import std.range: empty; return range.findAdjacent!("a != b").empty; } unittest { assert([11, 11].allEqual_); } unittest { assert(![11, 12].allEqual_); } unittest { int[] x; assert(x.allEqual_); } fails as algorithm_ex.d(190,27): Error: template algorithm_ex.allEqual_ cannot deduce function from argument types !()(int[]), candidates are: algorithm_ex.d(184,6): algorithm_ex.allEqual_(T)(InputRange!T range) algorithm_ex.d(191,28): Error: template algorithm_ex.allEqual_ cannot deduce function from argument types !()(int[]), candidates are: algorithm_ex.d(184,6): algorithm_ex.allEqual_(T)(InputRange!T range) algorithm_ex.d(192,29): Error: template algorithm_ex.allEqual_ cannot deduce function from argument types !()(int[]), candidates are: algorithm_ex.d(184,6): algorithm_ex.allEqual_(T)(InputRange!T range) |
May 07, 2014 Re: A Briefer Syntax for Using Concepts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | > Ahh, it seems this syntax is currently accepted by DMD. Should it be?
Correction:
Ahh, it seems this syntax is currently *not* accepted by DMD.
Should
it be?
|
Copyright © 1999-2021 by the D Language Foundation