Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 21, 2015 how does isInputRange(T) actually work? | ||||
---|---|---|---|---|
| ||||
enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); ... is the current implementation in Phobos. But I can't seem to understand this syntax. What is (inout int = 0)? Why can a block follow it? My guess is that this is declaring some sort of function and testing if it is syntactically valid, but this is still strange to me. |
April 21, 2015 Re: how does isInputRange(T) actually work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kevin | On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote:
> enum bool isInputRange = is(typeof(
> (inout int = 0)
> {
> R r = R.init; // can define a range object
> if (r.empty) {} // can test for empty
> r.popFront(); // can invoke popFront()
> auto h = r.front; // can get the front of the range
> }));
>
>
> ... is the current implementation in Phobos. But I can't seem to understand this syntax. What is (inout int = 0)? Why can a block follow it?
>
> My guess is that this is declaring some sort of function and testing if it is syntactically valid, but this is still strange to me.
It's defining a lambda function and checking that it is *semantically* valid.
No idea what the `(inout int = 0)` is there for, I would have thought it would be fine without it.
|
April 21, 2015 Re: how does isInputRange(T) actually work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Tuesday, 21 April 2015 at 19:11:43 UTC, John Colvin wrote:
> On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote:
>> enum bool isInputRange = is(typeof(
>> (inout int = 0)
>> {
>> R r = R.init; // can define a range object
>> if (r.empty) {} // can test for empty
>> r.popFront(); // can invoke popFront()
>> auto h = r.front; // can get the front of the range
>> }));
>>
>>
>> ... is the current implementation in Phobos. But I can't seem to understand this syntax. What is (inout int = 0)? Why can a block follow it?
>>
>> My guess is that this is declaring some sort of function and testing if it is syntactically valid, but this is still strange to me.
>
> It's defining a lambda function and checking that it is *semantically* valid.
>
> No idea what the `(inout int = 0)` is there for, I would have thought it would be fine without it.
`inout int = 0` is just `inout int n = 0` without the variable name, which is just `inout int n` with a default argument of 0.
|
April 21, 2015 Re: how does isInputRange(T) actually work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Tuesday, 21 April 2015 at 19:13:34 UTC, Meta wrote:
> On Tuesday, 21 April 2015 at 19:11:43 UTC, John Colvin wrote:
>> On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote:
>>> enum bool isInputRange = is(typeof(
>>> (inout int = 0)
>>> {
>>> R r = R.init; // can define a range object
>>> if (r.empty) {} // can test for empty
>>> r.popFront(); // can invoke popFront()
>>> auto h = r.front; // can get the front of the range
>>> }));
>>>
>>>
>>> ... is the current implementation in Phobos. But I can't seem to understand this syntax. What is (inout int = 0)? Why can a block follow it?
>>>
>>> My guess is that this is declaring some sort of function and testing if it is syntactically valid, but this is still strange to me.
>>
>> It's defining a lambda function and checking that it is *semantically* valid.
>>
>> No idea what the `(inout int = 0)` is there for, I would have thought it would be fine without it.
>
> `inout int = 0` is just `inout int n = 0` without the variable name, which is just `inout int n` with a default argument of 0.
Thanks for your responses. Don't lambdas need a => token? Also, what is the purpose of typeof? I would have expected a simple is() to work just fine.
|
April 21, 2015 Re: how does isInputRange(T) actually work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On 4/21/15 3:11 PM, John Colvin wrote:
> On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote:
>> enum bool isInputRange = is(typeof(
>> (inout int = 0)
>> {
>> R r = R.init; // can define a range object
>> if (r.empty) {} // can test for empty
>> r.popFront(); // can invoke popFront()
>> auto h = r.front; // can get the front of the range
>> }));
>>
>>
>> ... is the current implementation in Phobos. But I can't seem to
>> understand this syntax. What is (inout int = 0)? Why can a block
>> follow it?
>>
>> My guess is that this is declaring some sort of function and testing
>> if it is syntactically valid, but this is still strange to me.
>
> It's defining a lambda function and checking that it is *semantically*
> valid.
>
> No idea what the `(inout int = 0)` is there for, I would have thought it
> would be fine without it.
inout has a rule that you can't declare a type of inout as a local variable unless there is an inout parameter/return. I'm not sure if this rule still exists (it causes weird shit like the above to be required). I know some inout rules that I devised have been relaxed for the benefit of generic function sanity.
The inout int = 0 gives the lambda an inout parameter, in case you are doing isInputRange!(inout(int)[]), then you can validly declare a range of type R inside your function.
Alternatively, you could have the lambda take an R as a parameter. Or fix the semantics so that inout local variable acts like immutable inside a non-inout function.
-Steve
|
April 21, 2015 Re: how does isInputRange(T) actually work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kevin | On Tuesday, 21 April 2015 at 19:17:56 UTC, kevin wrote: > On Tuesday, 21 April 2015 at 19:13:34 UTC, Meta wrote: >> On Tuesday, 21 April 2015 at 19:11:43 UTC, John Colvin wrote: >>> On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote: >>>> enum bool isInputRange = is(typeof( >>>> (inout int = 0) >>>> { >>>> R r = R.init; // can define a range object >>>> if (r.empty) {} // can test for empty >>>> r.popFront(); // can invoke popFront() >>>> auto h = r.front; // can get the front of the range >>>> })); [...] > Don't lambdas need a => token? No, D has two variants of function/delegate literal or lambda syntax: 1) with "=>": parameters => expression Some examples: (int a) => a + 2 a => a + 2 (a, b) => a + b () => 2 2) with braces: (parameters) {statements} Same examples as above: (int a) {return a + 2;} (a) {return a + 2;} (a, b) {return a + b;} {return 2;} As you can see, a lot is optional there. In the spec: http://dlang.org/expression.html#FunctionLiteral > Also, what is the purpose of typeof? I would have expected a simple is() to work just fine. (In this most simple form,) `is` evaluates to true if the argument is a valid type. A function/delegate literal isn't a type. If you passed the lambda expression itself to `is`, the result would always be false. As it is, the result is true when the lambda expression compiles (so it has a valid type). More about the IsExpression: http://dlang.org/expression.html#IsExpression |
April 21, 2015 Re: how does isInputRange(T) actually work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kevin | On 04/21/2015 12:06 PM, kevin wrote: > enum bool isInputRange = is(typeof( > (inout int = 0) > { > R r = R.init; // can define a range object > if (r.empty) {} // can test for empty > r.popFront(); // can invoke popFront() > auto h = r.front; // can get the front of the range > })); > > > ... is the current implementation in Phobos. But I can't seem to > understand this syntax. What is (inout int = 0)? Why can a block follow it? > > My guess is that this is declaring some sort of function and testing if > it is syntactically valid, but this is still strange to me. I try to explain that syntax here: http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.named%20template%20constraint Ali |
April 22, 2015 Re: how does isInputRange(T) actually work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Tuesday, 21 April 2015 at 19:42:42 UTC, anonymous wrote:
> On Tuesday, 21 April 2015 at 19:17:56 UTC, kevin wrote:
>> On Tuesday, 21 April 2015 at 19:13:34 UTC, Meta wrote:
>>> On Tuesday, 21 April 2015 at 19:11:43 UTC, John Colvin wrote:
>>>> On Tuesday, 21 April 2015 at 19:06:39 UTC, kevin wrote:
>>>>> enum bool isInputRange = is(typeof(
>>>>> (inout int = 0)
>>>>> {
>>>>> R r = R.init; // can define a range object
>>>>> if (r.empty) {} // can test for empty
>>>>> r.popFront(); // can invoke popFront()
>>>>> auto h = r.front; // can get the front of the range
>>>>> }));
>> [...]
>> Also, what is the purpose of typeof? I would have expected a simple is() to work just fine.
>
> (In this most simple form,) `is` evaluates to true if the argument is a valid type. A function/delegate literal isn't a type.
>
> If you passed the lambda expression itself to `is`, the result would always be false. As it is, the result is true when the lambda expression compiles (so it has a valid type).
>
> More about the IsExpression: http://dlang.org/expression.html#IsExpression
That makes sense. It seems to me that D has very... special but effective syntax. I'm having a hard time remembering all the keywords and expression forms (especially of IsExpression) but it's definitely a vast improvement over C++'s half baked pile of whatever. Thanks for the help, everyone.
|
April 22, 2015 Re: how does isInputRange(T) actually work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kevin | > That makes sense. It seems to me that D has very... special but effective syntax. I'm having a hard time remembering all the keywords and expression forms (especially of IsExpression) but it's definitely a vast improvement over C++'s half baked pile of whatever. Thanks for the help, everyone.
The `is` expression is complicated and has a bunch of different usage syntax, but it's like one of those little multitools. Complicated to figure out how to use, but extremely flexible and able to do a lot of cool things.
|
April 23, 2015 Re: how does isInputRange(T) actually work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Wednesday, 22 April 2015 at 21:22:43 UTC, Meta wrote:
>> That makes sense. It seems to me that D has very... special but effective syntax. I'm having a hard time remembering all the keywords and expression forms (especially of IsExpression) but it's definitely a vast improvement over C++'s half baked pile of whatever. Thanks for the help, everyone.
>
> The `is` expression is complicated and has a bunch of different usage syntax, but it's like one of those little multitools. Complicated to figure out how to use, but extremely flexible and able to do a lot of cool things.
Yeah, the `is` expression is one of my favorite D features.
import std.container;
template Substitute (T, U) {
static if (is (T == F!V, alias F, V))
alias Substitute = F!U;
}
alias List = SList!int;
static assert (is (Substitute!(List, char) == SList!char));
It's the little things.
|
Copyright © 1999-2021 by the D Language Foundation