Bug 14037 – Problem with BigInt and std.functional.memoize

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-01-24T21:49:00Z
Last change time
2015-02-04T11:22:27Z
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2015-01-24T21:49:38Z
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.
Comment #1 by sinkuupump — 2015-01-31T16:06:48Z
Error on assigning to AA of BigInt seems a compiler problem: https://issues.dlang.org/show_bug.cgi?id=14089 However, memoize shouldn't assume that an overloaded opAssign returns the object. So I think your fix to memoize is necessary.
Comment #2 by sinkuupump — 2015-02-04T11:22:27Z
The compiler problem was fixed. Closing. > However, memoize shouldn't assume that an overloaded opAssign returns the object. So I think your fix to memoize is necessary. Ignore this. I didn't know that AA assignment expression always returns object on rhs.