Re: Can you explain this?

2014-08-21 Thread Colin via Digitalmars-d-learn

On Wednesday, 20 August 2014 at 20:18:15 UTC, Dicebot wrote:

On Wednesday, 20 August 2014 at 20:01:05 UTC, Colin wrote:

I see 3 distinct parts playing a role in my confusion:
A) The 'is' keyword. What does it do when you have 
is(expression);


http://dlang.org/expression.html#IsExpression

It is a tool for type checking. It has many options but plain 
`is(T)` checks if `T` is a valid type and returns `true` if it 
is. `void` is considered a valid type.


B) typeof( expression ); whats this doing? Particularly when 
the expression its acting on is a closure that returns 
nothing? (at least as far as I can see)


typeof(() {}) evaluates to void:

static assert(is(typeof(() {}) == void));

However, if any compilation errors happen inside the delegate, 
it evaluates to special invalid type which yield `false` when 
supplied to `is` expression.


Thus `is(typeof(expr))` is a way to express a concept "if 
`expr` compiles". Delegate is necessary to test statements 
because `typeof` only accepts expressions.



C) The closure expression:
(inout int = 0) {
  // Check to see if I can do InputRangy stuff...
}
Why is there a need for that inout int = 0 clause at the start 
of it?


Now this is a really weird one. This is necessary for input 
ranges with `inout` functions to fit the trait because `inout` 
variables can be declared only inside `inout` functions. See 
this bug report for details : 
https://issues.dlang.org/show_bug.cgi?id=7824


It is one of surprising feature inter-operation cases you don't 
expect when designing features :)


Thanks all, that explains it.

It is weird looking code alright, but I guess it has its uses.

I think I prefer the __traits(compiles,...) construct, as it is a 
bit more obvious as to what I'm checking. So will use that I 
suspect.


Cheers!


Re: Can you explain this?

2014-08-20 Thread Jonathan M Davis via Digitalmars-d-learn

On Wednesday, 20 August 2014 at 21:06:49 UTC, monarch_dodra wrote:
On Wednesday, 20 August 2014 at 20:39:42 UTC, Jonathan M Davis 
wrote:
is(typeof(foo)) and __traits(compiles, foo) are not the same. 
The first tests for the existence of the symbol, whereas the 
second checks whether the code will actually compile.


Is that even true? I mean, are you just repeating something 
you've heard, or have you checked? "is(typeof(foo))" has always 
failed for me merelly if "foo" fails to compile. "foo" being an 
existing (but private) symbol is enough.


Test case:
//
module foo;

struct S
{
private int i;
}
//
import foo;

void main(string[] args)
{
S s;
writeln(is(typeof(s.i)));
writeln(__traits(compiles, s.i));
}
//

This says false, false.

I've yet to find a usecase where "is(typeof(...))" and 
"__traits(compiles, ...)" aren't interchangeable.


I mean, I may have missed something, but it seems the whole 
"private" thing is just miss-information.


Well, hereas an example of them not being the same:

---
import std.stdio;

struct S
{
static void foo()
{
writeln(is(typeof(this)));
writeln(__traits(compiles, this));
}
}

void main()
{
S.foo();
}
---

I originally found out about it from Don here: 
https://issues.dlang.org/show_bug.cgi?id=8339


I don't know why your example doesn't show them as different. But 
we should probably change it so that they _are_ the same - either 
that or document their differences explicitly and clearly, but I 
don't know why the is(typeof.. behavior here would be desirable. 
Maybe so that we could do type(this) to declare a local variable 
of the class type generically? I don't know. They're _almost_ the 
same but not quite, and I don't know what the exact differences 
are. Pretty much all I have to go on is Don's explanation in that 
bug report.


- Jonathan M Davis


Re: Can you explain this?

2014-08-20 Thread monarch_dodra via Digitalmars-d-learn
On Wednesday, 20 August 2014 at 20:39:42 UTC, Jonathan M Davis 
wrote:
is(typeof(foo)) and __traits(compiles, foo) are not the same. 
The first tests for the existence of the symbol, whereas the 
second checks whether the code will actually compile.


Is that even true? I mean, are you just repeating something 
you've heard, or have you checked? "is(typeof(foo))" has always 
failed for me merelly if "foo" fails to compile. "foo" being an 
existing (but private) symbol is enough.


Test case:
//
module foo;

struct S
{
private int i;
}
//
import foo;

void main(string[] args)
{
S s;
writeln(is(typeof(s.i)));
writeln(__traits(compiles, s.i));
}
//

This says false, false.

I've yet to find a usecase where "is(typeof(...))" and 
"__traits(compiles, ...)" aren't interchangeable.


I mean, I may have missed something, but it seems the whole 
"private" thing is just miss-information.


Re: Can you explain this?

2014-08-20 Thread Jonathan M Davis via Digitalmars-d-learn

On Wednesday, 20 August 2014 at 20:12:58 UTC, Justin Whear wrote:

On Wed, 20 Aug 2014 20:01:03 +, Colin wrote:


It looks veryhacky.

I see 3 distinct parts playing a role in my confusion:
A) The 'is' keyword. What does it do when you have 
is(expression);
B) typeof( expression ); whats this doing? Particularly when 
the
expression its acting on is a closure that returns nothing? 
(at least as

far as I can see)
C) The closure expression:
(inout int = 0) {
// Check to see if I can do InputRangy stuff...
}
Why is there a need for that inout int = 0 clause at the start 
of it?


Sorry for the long question!

Thanks,
Colin


Before the introduction of __traits(compiles, ...), 
`is(typeof(...))` was used.


is(typeof(foo)) and __traits(compiles, foo) are not the same. The 
first tests for the existence of the symbol, whereas the second 
checks whether the code will actually compile. In most cases, 
there's no real difference, but if you're trying to use a symbol 
in a context where it's not legal (e.g. using a private variable 
that you don't have access to), then the is expression will pass, 
whereas the _traits(compiles.. will fail. At least in Phobos, 
is(typeof... is used far more freqently than __traits(compiles... 
The trait is used almost exclusively in unit tests, not in 
template constraints or in user-defined traits such as 
isInputRange.


- Jonathan M Davis


Re: Can you explain this?

2014-08-20 Thread Dicebot via Digitalmars-d-learn

On Wednesday, 20 August 2014 at 20:01:05 UTC, Colin wrote:

I see 3 distinct parts playing a role in my confusion:
A) The 'is' keyword. What does it do when you have 
is(expression);


http://dlang.org/expression.html#IsExpression

It is a tool for type checking. It has many options but plain 
`is(T)` checks if `T` is a valid type and returns `true` if it 
is. `void` is considered a valid type.


B) typeof( expression ); whats this doing? Particularly when 
the expression its acting on is a closure that returns nothing? 
(at least as far as I can see)


typeof(() {}) evaluates to void:

static assert(is(typeof(() {}) == void));

However, if any compilation errors happen inside the delegate, it 
evaluates to special invalid type which yield `false` when 
supplied to `is` expression.


Thus `is(typeof(expr))` is a way to express a concept "if `expr` 
compiles". Delegate is necessary to test statements because 
`typeof` only accepts expressions.



C) The closure expression:
(inout int = 0) {
   // Check to see if I can do InputRangy stuff...
}
Why is there a need for that inout int = 0 clause at the start 
of it?


Now this is a really weird one. This is necessary for input 
ranges with `inout` functions to fit the trait because `inout` 
variables can be declared only inside `inout` functions. See this 
bug report for details : 
https://issues.dlang.org/show_bug.cgi?id=7824


It is one of surprising feature inter-operation cases you don't 
expect when designing features :)


Re: Can you explain this?

2014-08-20 Thread Justin Whear via Digitalmars-d-learn
On Wed, 20 Aug 2014 20:01:03 +, Colin wrote:

> It looks veryhacky.
> 
> I see 3 distinct parts playing a role in my confusion:
> A) The 'is' keyword. What does it do when you have is(expression);
> B) typeof( expression ); whats this doing? Particularly when the
> expression its acting on is a closure that returns nothing? (at least as
> far as I can see)
> C) The closure expression:
> (inout int = 0) {
> // Check to see if I can do InputRangy stuff...
> }
> Why is there a need for that inout int = 0 clause at the start of it?
> 
> Sorry for the long question!
> 
> Thanks,
> Colin

Before the introduction of __traits(compiles, ...), `is(typeof(...))` was used.
It works because the is expression evaluates to false if the contents don't have
a type or are semantically invalid.  So this code creates a delegate to test 
the various properties--if it would compile, the delegate has a type and `is`
returns true. 
The inout int parameter is very hacky, see this thread: 
http://forum.dlang.org/thread/opykgvxbqqeleuikt...@forum.dlang.org#post-mailman.102.1396007039.25518.digitalmars-d-learn:40puremagic.com


Can you explain this?

2014-08-20 Thread Colin via Digitalmars-d-learn

Hi,

I'm implementing some template checks on some types I'm using in 
a project, and went to phobos for some indications on how to use 
them.


In std.range, I see this construct quite a bit:

template isInputRange(R)
{
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
}));
}

Can anyone explain the:
 is(typeof(
(inout int = 0) {}
  );

section to me?

It looks veryhacky.

I see 3 distinct parts playing a role in my confusion:
A) The 'is' keyword. What does it do when you have is(expression);
B) typeof( expression ); whats this doing? Particularly when the 
expression its acting on is a closure that returns nothing? (at 
least as far as I can see)

C) The closure expression:
(inout int = 0) {
   // Check to see if I can do InputRangy stuff...
}
Why is there a need for that inout int = 0 clause at the start of 
it?


Sorry for the long question!

Thanks,
Colin