digitalmars.D - :? in templates
- Bill Baxter (9/9) Nov 18 2009 Didn't this used to work?
- retard (4/15) Nov 18 2009 There's probably a confusion here. It evaluates lazily the value of
- Bill Baxter (6/21) Nov 18 2009 That makes sense. I guess the ?: op is defined to do that in all
- retard (5/27) Nov 18 2009 so
- Bill Baxter (8/35) Nov 18 2009 n
- Denis Koroskin (5/44) Nov 18 2009 The simplest solution is probably to give the compiler a hint:
- Stewart Gordon (9/18) Nov 18 2009 That would lead to expressions changing type in unexpected circumstances...
- Max Samukha (26/35) Nov 18 2009 While we are at it, binary logical operators has the same issue:
Didn't this used to work? template factorial(int i) { enum factorial = (i==0) ? 1 : i*factorial!(i-1); } With DMD 2.036 I'm getting: Error: template instance factorial!(-495) recursive expansion Seems like it expands both branches regardless of the condition. And seems to me like it shouldn't. --bb
Nov 18 2009
Wed, 18 Nov 2009 03:10:57 -0800, Bill Baxter wrote:Didn't this used to work? template factorial(int i) { enum factorial = (i==0) ? 1 : i*factorial!(i-1); } With DMD 2.036 I'm getting: Error: template instance factorial!(-495) recursive expansion Seems like it expands both branches regardless of the condition. And seems to me like it shouldn't.There's probably a confusion here. It evaluates lazily the value of factorial!(), but its type (which happens to be infinitely recursive must be evaluated eagerly in order to infer the type of the ternary op.
Nov 18 2009
On Wed, Nov 18, 2009 at 3:16 AM, retard <re tard.com.invalid> wrote:Wed, 18 Nov 2009 03:10:57 -0800, Bill Baxter wrote:That makes sense. I guess the ?: op is defined to do that in all cases. Might be nice though if it didn't do that in cases where the condition was statically known. Or if we just had a separate "static if" version of ?: --bbDidn't this used to work? template factorial(int i) { =A0 =A0 enum factorial =3D (i=3D=3D0) ? 1 : i*factorial!(i-1); } With DMD 2.036 I'm getting: =A0 Error: template instance factorial!(-495) recursive expansion Seems like it expands both branches regardless of the condition. And seems to me like it shouldn't.There's probably a confusion here. It evaluates lazily the value of factorial!(), but its type (which happens to be infinitely recursive must be evaluated eagerly in order to infer the type of the ternary op.
Nov 18 2009
Wed, 18 Nov 2009 03:31:11 -0800, Bill Baxter wrote:On Wed, Nov 18, 2009 at 3:16 AM, retard <re tard.com.invalid> wrote:so int foo = (1==1) ? 6 : "haha"; would work, too? I think it would still need to check that the types of both branches match.Wed, 18 Nov 2009 03:10:57 -0800, Bill Baxter wrote:That makes sense. I guess the ?: op is defined to do that in all cases. Might be nice though if it didn't do that in cases where the condition was statically known.Didn't this used to work? template factorial(int i) { enum factorial = (i==0) ? 1 : i*factorial!(i-1); } With DMD 2.036 I'm getting: Error: template instance factorial!(-495) recursive expansion Seems like it expands both branches regardless of the condition. And seems to me like it shouldn't.There's probably a confusion here. It evaluates lazily the value of factorial!(), but its type (which happens to be infinitely recursive must be evaluated eagerly in order to infer the type of the ternary op.
Nov 18 2009
On Wed, Nov 18, 2009 at 3:36 AM, retard <re tard.com.invalid> wrote:Wed, 18 Nov 2009 03:31:11 -0800, Bill Baxter wrote:s.On Wed, Nov 18, 2009 at 3:16 AM, retard <re tard.com.invalid> wrote:Wed, 18 Nov 2009 03:10:57 -0800, Bill Baxter wrote:That makes sense. =A0I guess the ?: op is defined to do that in all case=Didn't this used to work? template factorial(int i) { =A0 =A0 enum factorial =3D (i=3D=3D0) ? 1 : i*factorial!(i-1); } With DMD 2.036 I'm getting: =A0 Error: template instance factorial!(-495) recursive expansion Seems like it expands both branches regardless of the condition. And seems to me like it shouldn't.There's probably a confusion here. It evaluates lazily the value of factorial!(), but its type (which happens to be infinitely recursive must be evaluated eagerly in order to infer the type of the ternary op.n=A0Might be nice though if it didn't do that in cases where the conditio=Yeh, that could be confusing. Actually it would break a lot of code, too, now that I think of it. People use typeof(true?a:b) to get the common type. That's why it probably needs to be a distinct thing, a static ?:. --bbwas statically known.so =A0int foo =3D (1=3D=3D1) ? 6 : "haha"; would work, too? I think it would still need to check that the types of both branches match.
Nov 18 2009
On Wed, 18 Nov 2009 14:50:42 +0300, Bill Baxter <wbaxter gmail.com> wrote:On Wed, Nov 18, 2009 at 3:36 AM, retard <re tard.com.invalid> wrote:The simplest solution is probably to give the compiler a hint: enum foo = someStaticCondition ? cast(Foo)SomeTemplate!() : cast(Foo)SomeOtherTemplate!(); Looks a bit hackish (and doesn't currently work), though.Wed, 18 Nov 2009 03:31:11 -0800, Bill Baxter wrote:Yeh, that could be confusing. Actually it would break a lot of code, too, now that I think of it. People use typeof(true?a:b) to get the common type. That's why it probably needs to be a distinct thing, a static ?:. --bbOn Wed, Nov 18, 2009 at 3:16 AM, retard <re tard.com.invalid> wrote:so int foo = (1==1) ? 6 : "haha"; would work, too? I think it would still need to check that the types of both branches match.Wed, 18 Nov 2009 03:10:57 -0800, Bill Baxter wrote:That makes sense. I guess the ?: op is defined to do that in all cases. Might be nice though if it didn't do that in cases where the condition was statically known.Didn't this used to work? template factorial(int i) { enum factorial = (i==0) ? 1 : i*factorial!(i-1); } With DMD 2.036 I'm getting: Error: template instance factorial!(-495) recursive expansion Seems like it expands both branches regardless of the condition. And seems to me like it shouldn't.There's probably a confusion here. It evaluates lazily the value of factorial!(), but its type (which happens to be infinitely recursive must be evaluated eagerly in order to infer the type of the ternary op.
Nov 18 2009
Bill Baxter wrote:On Wed, Nov 18, 2009 at 3:16 AM, retard <re tard.com.invalid> wrote:<snip>That would lead to expressions changing type in unexpected circumstances. But what if we made it depend on whether the context requires a compile-time constant?There's probably a confusion here. It evaluates lazily the value of factorial!(), but its type (which happens to be infinitely recursive must be evaluated eagerly in order to infer the type of the ternary op.That makes sense. I guess the ?: op is defined to do that in all cases. Might be nice though if it didn't do that in cases where the condition was statically known.Or if we just had a separate "static if" version of ?:Maybe make ?? a compile-time version, which selects the type as well as the value? ("static ?" would also fit into the grammar without adding ambiguity, but I'm not sure that it looks as nice.) Stewart.
Nov 18 2009
On Wed, 18 Nov 2009 03:10:57 -0800, Bill Baxter <wbaxter gmail.com> wrote:Didn't this used to work? template factorial(int i) { enum factorial = (i==0) ? 1 : i*factorial!(i-1); } With DMD 2.036 I'm getting: Error: template instance factorial!(-495) recursive expansion Seems like it expands both branches regardless of the condition. And seems to me like it shouldn't. --bbWhile we are at it, binary logical operators has the same issue: static if (foo!() && bar!()) { } else { } bar is instantiated even if 'foo!()' results in false. To work around it, you have to add another 'static if' and duplicate the 'else' block: static if (foo!()) { static if (bar!()) { } else { } } else { } I've encountered the problem several times and would be happy to have it fixed, if possible.
Nov 18 2009