digitalmars.D - "instanceOf" trait for conditional implementations
- monarch_dodra (82/82) Oct 04 2012 One of the issues I've been running into more or less frequently
- monarch_dodra (12/13) Oct 04 2012 You know what? Forget I said anything? Using lambdas is an
- so (11/21) Oct 04 2012 OT - Is there any reason for disabling UFCS for this?
- monarch_dodra (10/32) Oct 04 2012 Because typeof is a keyword, and is is a declaration.
- Marco Leise (5/16) Oct 10 2012 Yoda says: "This proposal a special type of is!"
- kenji hara (5/16) Oct 04 2012 IMO, this is just a compiler bug. If a variable has VoidInitializer,
- David Nadlinger (4/8) Oct 04 2012 What would be the semantics of T.init for a type with @disable
- Simen Kjaeraas (15/27) Oct 04 2012 [snip: Good stuff]
- monarch_dodra (8/11) Oct 04 2012 Awesome! It is much more robust too! I still don't understand how
- monarch_dodra (3/4) Oct 05 2012 An ER has been opened.
One of the issues I've been running into more or less frequently lately is the inability to extract an instance of a type when trying to do conditional implementation specification. Let me explain myself. Using T.init is a no go, because: a) T might be " disabled this()", making T.init illegal syntax (in theory, currently "buggy") b) T.init is NOT an LValue, making code such is "is(typeof(T.init = 5))" invalid c) You can try to use "T t = void", but you may also run into problems: c)1) If T is immutable, that's illegal. c)2) The compiler may complain if you use t, due to access to uninitialized. This makes it a pain in the ass, as shown in this thread: http://forum.dlang.org/thread/mailman.224.1348358069.5162.digitalmars-d-learn puremagic.com Or this pull request: https://github.com/D-Programming-Language/phobos/pull/832 The current implementation for "isAssignable" is //---- template isAssignable(Lhs, Rhs) { enum bool isAssignable = is(typeof({ Lhs l = void; void f(Rhs r) { l = r; } return l; })); } //---- The code is correct, but when you have to jump through that many loops, you have to admit there is probably something wrong. Imagine you are writting a template "Foo" that only works if it is legal to pass an instance of T to a function Bar. Are you *really* going to write the same thing as above, inside a single conditional if?! //****************************************** I'd like to propose an "instanceOf(T)" traits template, that would return an LValue instance of T. It would be used (strictly) for evaluating conditional implementations, or for the implementation of traits types. //---- template instanceOf(T) { static if (is(typeof({T t;}))) T instanceOf; else T instanceOf = void; } //---- Now, watch this //---- template isAssignable(T, U) { enum bool isAssignable = is(typeof(instanceOf!T = instanceOf!U)); } struct S { disable this(); } void main() { static assert( isAssignable!(int, int)); static assert( isAssignable!(int, immutable(int))); static assert(!isAssignable!(immutable(int), int)); static assert( isAssignable!(S, immutable(S))); //Tricky test BTW } //---- See? Easy peasy. And this is just a "simple" test case: assign-ability. There are a bunch of other traits templates which would benefit here. And that's the "tip of the iceberg": There are a TON of algorithms that use .init in their implementation restrictions: "if (Range.init.front ...)" instanceOf would be a convenient way to support any type, regardless of construct-ability (or lack thereof). //-------- That's my idea anyways, they've been consistently destroyed recently, so I don't mind again if you think it is a bad idea, or the approach is wrong. I *do* think that being able to extract an instance of a type without worrying about how to actually acquire one...
Oct 04 2012
On Thursday, 4 October 2012 at 09:43:08 UTC, monarch_dodra wrote:[SNIP]You know what? Forget I said anything? Using lambdas is an incredibly good workaround for all the problems stated above, making the initial point moot. Lamba if: template isAssignable(T, U) { enum bool isAssignable = is(typeof((ref T t, ref U u) => {t = u;})); } This allow testing on t and u, without ever having to construct/acquire them. Neat-o!!!
Oct 04 2012
On Thursday, 4 October 2012 at 09:43:08 UTC, monarch_dodra wrote:The current implementation for "isAssignable" is //---- template isAssignable(Lhs, Rhs) { enum bool isAssignable = is(typeof({ Lhs l = void; void f(Rhs r) { l = r; } return l; })); }OT - Is there any reason for disabling UFCS for this? template isAssignable(Lhs, Rhs) { enum bool isAssignable = { Lhs l = void; void f(Rhs r) { l = r; } return l; }.typeof.is; }
Oct 04 2012
On Thursday, 4 October 2012 at 12:48:51 UTC, so wrote:On Thursday, 4 October 2012 at 09:43:08 UTC, monarch_dodra wrote:Because typeof is a keyword, and is is a declaration. There are two open ER to allow typeof to be used as a property: While not strictly EFCS, it would be convenient. Regarding is, There are no open requests. But I guess it would be fun to write if( T.is(U) ). But where would it end? Make if UFCS too? T.is(U).if() IMO, I can see typeof being a property, but not is.The current implementation for "isAssignable" is //---- template isAssignable(Lhs, Rhs) { enum bool isAssignable = is(typeof({ Lhs l = void; void f(Rhs r) { l = r; } return l; })); }OT - Is there any reason for disabling UFCS for this? template isAssignable(Lhs, Rhs) { enum bool isAssignable = { Lhs l = void; void f(Rhs r) { l = r; } return l; }.typeof.is; }
Oct 04 2012
Am Thu, 04 Oct 2012 14:43:00 +0200 schrieb "so" <so so.so>:OT - Is there any reason for disabling UFCS for this? template isAssignable(Lhs, Rhs) { enum bool isAssignable = { Lhs l = void; void f(Rhs r) { l = r; } return l; }.typeof.is; }Yoda says: "This proposal a special type of is!" -- Marco
Oct 10 2012
2012/10/4 monarch_dodra <monarchdodra gmail.com>:One of the issues I've been running into more or less frequently lately is the inability to extract an instance of a type when trying to do conditional implementation specification. Let me explain myself. Using T.init is a no go, because: a) T might be " disabled this()", making T.init illegal syntax (in theory, currently "buggy")I think T.init should always legal.b) T.init is NOT an LValue, making code such is "is(typeof(T.init = 5))" invalidc) You can try to use "T t = void", but you may also run into problems: c)1) If T is immutable, that's illegal. c)2) The compiler may complain if you use t, due to access to uninitialized.IMO, this is just a compiler bug. If a variable has VoidInitializer, it should always become a runtime value. Kenji Hara
Oct 04 2012
On Thursday, 4 October 2012 at 17:44:48 UTC, kenji hara wrote:What would be the semantics of T.init for a type with disable this()? It isn't a valid value, for sure... Davida) T might be " disabled this()", making T.init illegal syntax (in theory, currently "buggy")I think T.init should always legal.
Oct 04 2012
On 2012-37-04 11:10, monarch_dodra <monarchdodra gmail.com> wrote:One of the issues I've been running into more or less frequently lately is the inability to extract an instance of a type when trying to do conditional implementation specification. Let me explain myself. Using T.init is a no go, because: a) T might be " disabled this()", making T.init illegal syntax (in theory, currently "buggy") b) T.init is NOT an LValue, making code such is "is(typeof(T.init = 5))" invalid c) You can try to use "T t = void", but you may also run into problems: c)1) If T is immutable, that's illegal. c)2) The compiler may complain if you use t, due to access to uninitialized.[snip: Good stuff] I like this, and have had the exact same thought. There is one thing I don't like, and that is your instanceOf could be used to create an uninitialized T. In the interest of that (and brevity) let me present my solution: property T instanceOf( T )( ); It works great in static if, and fails at link-time. The error message is however far from perfect: Error 42: Symbol Undefined _D3foo24__T10instanceOfTS3foo1SZ10instanceOfFNdZS3foo1S But I think that is better than giving developers a tool for instantiating types that are not meant to be instantiated. -- Simen
Oct 04 2012
On Thursday, 4 October 2012 at 17:57:51 UTC, Simen Kjaeraas wrote:[SNIP] property T instanceOf( T )( ); [SNIP]Awesome! It is much more robust too! I still don't understand how *my* instanceOf!(immutable(S)) works :/ I'd just change it to: property ref T instanceOf( T )( ); So that instanceOf acts as an LValue. Having a link error is great too. A compile error would be best, but unachievable actually, so still pretty good.
Oct 04 2012
On Thursday, 4 October 2012 at 09:43:08 UTC, monarch_dodra wrote:[SNIP]An ER has been opened. http://d.puremagic.com/issues/show_bug.cgi?id=8762
Oct 05 2012