digitalmars.D - A Briefer Syntax for Using Concepts
- w0rp (10/10) May 07 2014 Here is a question, is it possible for D, or any future language,
- John Colvin (2/13) May 07 2014 I sense a polymorphic compile-time-only type system.
- Sergei Nosov (12/23) May 07 2014 C++ concepts has similar syntax.
- bearophile (7/10) May 07 2014 I think the Concepts lite proposal faces this problem too. Take a
- w0rp (4/7) May 07 2014 One thing to consider would be that InputRange wouldn't be a type
- Mason McGill (26/37) May 07 2014 I think Julia does something like this, under the hood. Julia
- Orvid King via Digitalmars-d (5/6) May 07 2014 How to make it accept multiple types? Simple, we already have template
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (7/8) May 07 2014 Clever. Shouldn't we all, including Phobos, use this shorter
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (42/43) May 07 2014 Update:
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (4/6) May 07 2014 Correction:
- John Colvin (6/49) May 07 2014 std.range.InputRange is an interface template. int[] is not
- w0rp (4/13) May 07 2014 I am confused. The proposed syntax would already accept many
- H. S. Teoh via Digitalmars-d (12/25) May 07 2014 I believe the objection is that the proposed syntax can't tell the
- froglegs (6/19) May 07 2014 I believe Concepts lite in C++ works around this by allowing a
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
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
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
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
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
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 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
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
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
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
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?
May 07 2014
On Wednesday, 7 May 2014 at 16:04:39 UTC, Nordlöw wrote:std.range.InputRange is an interface template. int[] is not implicitly convertable to InputRange!(T[]), which is in fact an interface to a range with element type int[] (not int) std.range.isInputRange and std.range.InputRange are unrelated except that the latter satisfies the former.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
On Wednesday, 7 May 2014 at 14:49:17 UTC, Orvid King via Digitalmars-d wrote:On 5/7/14, w0rp via Digitalmars-d <digitalmars-d puremagic.com> wrote:I am confused. The proposed syntax would already accept many different types.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
On Wed, May 07, 2014 at 08:09:34PM +0000, w0rp via Digitalmars-d wrote:On Wednesday, 7 May 2014 at 14:49:17 UTC, Orvid King via Digitalmars-d wrote:I believe the objection is that the proposed syntax can't tell the difference between: void foo(R)(R range1, R range2) if (isInputRange!R) and void foo(R,S)(R range1, S range2) if (isInputRange!R && isInputRange!S) I.e. in the first case, the two ranges must be the same type, whereas in the second case they can be different types as long as they are both input ranges. T -- Не дорог подарок, дорога любовь.On 5/7/14, w0rp via Digitalmars-d <digitalmars-d puremagic.com> wrote:I am confused. The proposed syntax would already accept many different types.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
I believe Concepts lite in C++ works around this by allowing a syntax like this: void foo(InputRange{T} range1, InputRange{T2} range2) vs. void foo(InputRange range1, InputRange range2) If they are the same type.I believe the objection is that the proposed syntax can't tell the difference between: void foo(R)(R range1, R range2) if (isInputRange!R) and void foo(R,S)(R range1, S range2) if (isInputRange!R && isInputRange!S) I.e. in the first case, the two ranges must be the same type, whereas in the second case they can be different types as long as they are both input ranges. T
May 07 2014