digitalmars.D.bugs - [Issue 14037] New: Problem with BigInt and std.functional.memoize
- via Digitalmars-d-bugs (84/84) Jan 24 2015 https://issues.dlang.org/show_bug.cgi?id=14037
https://issues.dlang.org/show_bug.cgi?id=14037 Issue ID: 14037 Summary: Problem with BigInt and std.functional.memoize Product: D Version: D2 Hardware: x86 OS: Windows Status: NEW Severity: regression Priority: P1 Component: Phobos Assignee: nobody puremagic.com Reporter: bearophile_hugs eml.cc This seems a regression. Now std.functional.memoize has problems with functions that return a BigInt: import std.bigint: BigInt; import std.functional: memoize; uint fibonacci1(uint n) { alias mFib = memoize!fibonacci1; // OK if (n < 2) return 1; else return mFib(n - 1) + mFib(n - 2); } BigInt fibonacci2(uint n) { alias mFib = memoize!fibonacci2; // Error if (n < 2) return BigInt(1); else return mFib(n - 1) + mFib(n - 2); } void main() {} dmd 2.067alpha gives: ...\dmd2\src\phobos\std\functional.d(991,9): Error: return expression expected test.d(13,18): Error: template instance std.functional.memoize!(fibonacci2) error instantiating I have seen that the problem can be fixed changing memoize, from this: template memoize(alias fun) { // alias Args = ParameterTypeTuple!fun; // Bugzilla 13580 ReturnType!fun memoize(ParameterTypeTuple!fun args) { alias Args = ParameterTypeTuple!fun; import std.typecons : Tuple; static ReturnType!fun[Tuple!Args] memo; auto t = Tuple!Args(args); if (auto p = t in memo) return *p; return memo[t] = fun(args); } } To this: template memoize(alias fun) { // alias Args = ParameterTypeTuple!fun; // Bugzilla 13580 ReturnType!fun memoize(ParameterTypeTuple!fun args) { alias Args = ParameterTypeTuple!fun; import std.typecons : Tuple; static ReturnType!fun[Tuple!Args] memo; auto t = Tuple!Args(args); if (auto p = t in memo) return *p; auto result = fun(args); memo[t] = result; return result; } } But it looks like a problem of BigInt: void main() { import std.bigint: BigInt; int[int] aa1; int r1 = aa2[1] = 1; // OK BigInt[int] aa2; BigInt r2 = aa2[1] = BigInt(1); // Error } Gives: test.d(4,14): Error: undefined identifier aa2, did you mean variable aa1? test.d(6,24): Error: expression BigInt __aaval1426 = __aaval1426 = BigInt , __aaval1426.this(1); , 1 in aa2 ? aa2[1].opAssign(__aaval1426) : cast(void)(aa2[1] = __aaval1426) is void and has no value So perhaps fixing BigInt suffices. --
Jan 24 2015