www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - __traits(compiles,...) <=> ? is(typeof(...))

reply "Zhenya" <zheny list.ru> writes:
Hi!

Tell me please,in this code first and second static if,are these 
equivalent?
with arg = 1, __traits(compiles,"check(arg);") = true, 
is(typeof(check(arg))) = false.

template ArgType(alias arg)
{
	void check(T)(ref T t) {};
//	static if(__traits(compiles,"check(arg);"))
	static if(is(typeof(check(arg))))
	{
		struct ArgType
		{
			typeof(arg)* m_ptr;
			this(ref typeof(arg) r)
			{
				m_ptr = &r;
			}
			 property ref typeof(arg) get()
			{
				return *m_ptr;
			}
			alias get this;
		}
	}
	else
		alias typeof(arg) ArgType;
}
Oct 29 2012
next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
 Tell me please,in this code first and second static if,are these equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

__traits(compiles, ...) takes an expression, not a string. From the spec: "The arguments can be symbols, types, or expressions that are syntactically correct. The arguments cannot be statements or declarations." (http://dlang.org/traits.html#compiles) So, in your case, that would be: __traits(compiles, {check(arg);}) Note that you can also use the type of arg: __traits(compiles, {check(typeof(arg).init);}) or is(typeof({ check(typeof(arg).init);})
Oct 29 2012
prev sibling next sibling parent "Zhenya" <zheny list.ru> writes:
On Monday, 29 October 2012 at 10:58:51 UTC, Philippe Sigaud wrote:
 Tell me please,in this code first and second static if,are 
 these equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

__traits(compiles, ...) takes an expression, not a string. From the spec: "The arguments can be symbols, types, or expressions that are syntactically correct. The arguments cannot be statements or declarations." (http://dlang.org/traits.html#compiles) So, in your case, that would be: __traits(compiles, {check(arg);}) Note that you can also use the type of arg: __traits(compiles, {check(typeof(arg).init);}) or is(typeof({ check(typeof(arg).init);})

Oct 29 2012
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, October 29, 2012 11:42:59 Zhenya wrote:
 Hi!
 
 Tell me please,in this code first and second static if,are these
 equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

In principle, is(typeof(code)) checks whether the code in there is syntatically and semantically valid but does _not_ check whether the code actually compiles. For instance, it checks for the existence of the symbols that you use in it, but it doesn't check whether you can actually use the symbol (e.g. it's private in another module). __traits(compiles, code) on the other hand specifically checks whether the code will compile (so it takes stuff like access level into account). In general, they're identical, but depending on the symbols used in them, they can be subtly different. And as Philippe points out, neither of them is intended to take strings. They'll pass with the string, but all they'll be checking is that it's a valid string, which would be pretty useless. - Jonathan M Davis
Oct 29 2012
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10/29/2012 12:03 PM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 11:42:59 Zhenya wrote:
 Hi!

 Tell me please,in this code first and second static if,are these
 equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

In principle, is(typeof(code)) checks whether the code in there is syntatically and semantically valid but does _not_ check whether the code actually compiles. For instance, it checks for the existence of the symbols that you use in it, but it doesn't check whether you can actually use the symbol (e.g. it's private in another module). ...

Accessing private symbols is always illegal, even within typeof expressions.
Oct 29 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10/30/2012 12:17 AM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 23:38:34 Timon Gehr wrote:
 On 10/29/2012 12:03 PM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 11:42:59 Zhenya wrote:
 Hi!

 Tell me please,in this code first and second static if,are these
 equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

In principle, is(typeof(code)) checks whether the code in there is syntatically and semantically valid but does _not_ check whether the code actually compiles. For instance, it checks for the existence of the symbols that you use in it, but it doesn't check whether you can actually use the symbol (e.g. it's private in another module). ...

Accessing private symbols is always illegal, even within typeof expressions.

As I understand it, that's not supposed to be the case. is(typeof(T.init)) tests for existance not for compilability, and private symbols are fully visible by everything that imports the module that they're in. They're just not accessible. I completely agree that it would be better for them to be hidden as well, but it doesn't work that way right now, and no one has been able to convince Walter that it should. ...

That is a different issue.
Oct 29 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10/30/2012 01:43 AM, Jonathan M Davis wrote:
 On Tuesday, October 30, 2012 00:29:22 Timon Gehr wrote:
 On 10/30/2012 12:17 AM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 23:38:34 Timon Gehr wrote:
 On 10/29/2012 12:03 PM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 11:42:59 Zhenya wrote:
 Hi!

 Tell me please,in this code first and second static if,are these
 equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

In principle, is(typeof(code)) checks whether the code in there is syntatically and semantically valid but does _not_ check whether the code actually compiles. For instance, it checks for the existence of the symbols that you use in it, but it doesn't check whether you can actually use the symbol (e.g. it's private in another module). ...

Accessing private symbols is always illegal, even within typeof expressions.>

tests for existance not for compilability, and private symbols are fully visible by everything that imports the module that they're in. They're just not accessible. I completely agree that it would be better for them to be hidden as well, but it doesn't work that way right now, and no one has been able to convince Walter that it should. ...

That is a different issue.

But as long as private symbols are visible, they should work with is(typeof(blah)), because it's testing for their existence, not whether they can be used or not.. - Jonathan M Davis

wtf.
Oct 29 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10/30/2012 02:53 AM, Jonathan M Davis wrote:
 On Tuesday, October 30, 2012 02:22:42 Timon Gehr wrote:
 On 10/30/2012 01:43 AM, Jonathan M Davis wrote:
 On Tuesday, October 30, 2012 00:29:22 Timon Gehr wrote:
 On 10/30/2012 12:17 AM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 23:38:34 Timon Gehr wrote:
 On 10/29/2012 12:03 PM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 11:42:59 Zhenya wrote:
 Hi!

 Tell me please,in this code first and second static if,are these
 equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

In principle, is(typeof(code)) checks whether the code in there is syntatically and semantically valid but does _not_ check whether the code actually compiles. For instance, it checks for the existence of the symbols that you use in it, but it doesn't check whether you can actually use the symbol (e.g. it's private in another module). ...

Accessing private symbols is always illegal, even within typeof expressions.>

As I understand it, that's not supposed to be the case. is(typeof(T.init)) tests for existance not for compilability, and private symbols are fully visible by everything that imports the module that they're in. They're just not accessible. I completely agree that it would be better for them to be hidden as well, but it doesn't work that way right now, and no one has been able to convince Walter that it should. ...

That is a different issue.

But as long as private symbols are visible, they should work with is(typeof(blah)), because it's testing for their existence, not whether they can be used or not.. - Jonathan M Davis

wtf.

??? Nothing else would make sense. As long as private symbols are visible, then typeof should interact with them like it interacts with all other visible symbols. It's not testing for compilability, just existence. It would be very inconsistent for it to consider private variables as non-existent when they're visible.

Even if there was no difference between accessibility in an information hiding context and accessibility related to existence of a suitable frame pointer, and therefore, an actual inconsistency, it would not be very clever to fix an inconsistency by generalising the stupid bits instead of the parts that are sane. You are arguing for a "language change" in either case.
 Everything else considers them to exist. It's just that nothing
 outside of the module that they're declared in can use them. The _only_ thing
 that private affects at this point is whether a symbol can be used. So, it
 should definitely affect __traits(compiles, foo), but since is(typeof(foo))
only
 cares about existence, not compilability, it should work with private
 variables.

Well, define 'work'. It should evaluate to 'false'. typeof(foo) should not compile if foo refers to a private declaration in a different module. Is that not obvious?
 Things change if/when private variable become invisible outside of their
 module, but for now, they're not.

I do not care whether they are invisible or not. In fact, this can become an implementation detail. What needs fixing is the symbol conflicts involving inaccessible symbols situation. It is ridiculous.
Oct 30 2012
prev sibling parent Don Clugston <dac nospam.com> writes:
On 29/10/12 12:03, Jonathan M Davis wrote:
 On Monday, October 29, 2012 11:42:59 Zhenya wrote:
 Hi!

 Tell me please,in this code first and second static if,are these
 equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

In principle, is(typeof(code)) checks whether the code in there is syntatically and semantically valid but does _not_ check whether the code actually compiles. For instance, it checks for the existence of the symbols that you use in it, but it doesn't check whether you can actually use the symbol (e.g. it's private in another module).

Not even that. It checks if the expression has a type. That's all. The expression has be syntactically valid or it won't compile at all. But inside is(typeof()) it is allowed to be semantically invalid. I started using is(typeof()) as a check for compilability, and other people used the idea as well. But it only works if you can convert "compilable" into "has a type".
Oct 30 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Monday, October 29, 2012 23:38:34 Timon Gehr wrote:
 On 10/29/2012 12:03 PM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 11:42:59 Zhenya wrote:
 Hi!
 
 Tell me please,in this code first and second static if,are these
 equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

In principle, is(typeof(code)) checks whether the code in there is syntatically and semantically valid but does _not_ check whether the code actually compiles. For instance, it checks for the existence of the symbols that you use in it, but it doesn't check whether you can actually use the symbol (e.g. it's private in another module). ...

Accessing private symbols is always illegal, even within typeof expressions.

As I understand it, that's not supposed to be the case. is(typeof(T.init)) tests for existance not for compilability, and private symbols are fully visible by everything that imports the module that they're in. They're just not accessible. I completely agree that it would be better for them to be hidden as well, but it doesn't work that way right now, and no one has been able to convince Walter that it should. Another example would be the init property of a type where you can't use its init property (as occurs with non-static Voldemort types). Assuming that it works properly, is(typeof(T.init)) will be true, but __traits(compiles, T.init) won't. There's a discussion on it in this bug report: http://d.puremagic.com/issues/show_bug.cgi?id=8339 - Jonathan M Davis
Oct 29 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, October 30, 2012 00:29:22 Timon Gehr wrote:
 On 10/30/2012 12:17 AM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 23:38:34 Timon Gehr wrote:
 On 10/29/2012 12:03 PM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 11:42:59 Zhenya wrote:
 Hi!
 
 Tell me please,in this code first and second static if,are these
 equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

In principle, is(typeof(code)) checks whether the code in there is syntatically and semantically valid but does _not_ check whether the code actually compiles. For instance, it checks for the existence of the symbols that you use in it, but it doesn't check whether you can actually use the symbol (e.g. it's private in another module). ...

Accessing private symbols is always illegal, even within typeof expressions.>

tests for existance not for compilability, and private symbols are fully visible by everything that imports the module that they're in. They're just not accessible. I completely agree that it would be better for them to be hidden as well, but it doesn't work that way right now, and no one has been able to convince Walter that it should. ...

That is a different issue.

But as long as private symbols are visible, they should work with is(typeof(blah)), because it's testing for their existence, not whether they can be used or not.. - Jonathan M Davis
Oct 29 2012
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, October 30, 2012 02:22:42 Timon Gehr wrote:
 On 10/30/2012 01:43 AM, Jonathan M Davis wrote:
 On Tuesday, October 30, 2012 00:29:22 Timon Gehr wrote:
 On 10/30/2012 12:17 AM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 23:38:34 Timon Gehr wrote:
 On 10/29/2012 12:03 PM, Jonathan M Davis wrote:
 On Monday, October 29, 2012 11:42:59 Zhenya wrote:
 Hi!
 
 Tell me please,in this code first and second static if,are these
 equivalent?
 with arg = 1, __traits(compiles,"check(arg);") = true,
 is(typeof(check(arg))) = false.

In principle, is(typeof(code)) checks whether the code in there is syntatically and semantically valid but does _not_ check whether the code actually compiles. For instance, it checks for the existence of the symbols that you use in it, but it doesn't check whether you can actually use the symbol (e.g. it's private in another module). ...

Accessing private symbols is always illegal, even within typeof expressions.>

As I understand it, that's not supposed to be the case. is(typeof(T.init)) tests for existance not for compilability, and private symbols are fully visible by everything that imports the module that they're in. They're just not accessible. I completely agree that it would be better for them to be hidden as well, but it doesn't work that way right now, and no one has been able to convince Walter that it should. ...

That is a different issue.

But as long as private symbols are visible, they should work with is(typeof(blah)), because it's testing for their existence, not whether they can be used or not.. - Jonathan M Davis

wtf.

??? Nothing else would make sense. As long as private symbols are visible, then typeof should interact with them like it interacts with all other visible symbols. It's not testing for compilability, just existence. It would be very inconsistent for it to consider private variables as non-existent when they're visible. Everything else considers them to exist. It's just that nothing outside of the module that they're declared in can use them. The _only_ thing that private affects at this point is whether a symbol can be used. So, it should definitely affect __traits(compiles, foo), but since is(typeof(foo)) only cares about existence, not compilability, it should work with private variables. Things change if/when private variable become invisible outside of their module, but for now, they're not. - Jonathan M Davis
Oct 29 2012