01-04-2018, 04:40 PM
I unintentionally implemented an infinite recursion of a function taking a list which should return a real integer (the number of items counter in the list).
The infinite recursion behaved unexpectedly.
The Prime only limits recursion depth in the CAS.
But instead of crashing, the code that should never return an integer, instead returns tthe input list and continues to execute (after several seconds).
(A fragment from my List V1.2 code, before bug fix. The intended return procedurename should be ..._SORTED)
Instead of printing C and erroring, the code fragment prints
C
{Input list}
D
At the point where D is printed, the count contains a list instead of an integer, which could lead to subsequent bugs in the user code...It would be better if the recursion were trapped and subsequent code not executed.
The infinite recursion behaved unexpectedly.
The Prime only limits recursion depth in the CAS.
But instead of crashing, the code that should never return an integer, instead returns tthe input list and continues to execute (after several seconds).
Code:
//Forward
ListCOUNTANYDUPLICATES_SORTED(SORTEDLST);
LOCAL ListANS;//OUTPUT LIST(WHEN NOT RETURNED)
//Also, useful temporary results
EXPORT ListCOUNTANYDUPLICATES (LST)
//Preferred-SORTED
BEGIN
ListANS:=ListSORT(LST);
RETURN ListCOUNTANYDUPLICATES(ListANS);//UNINTENDED RECURSION
END;
EXPORT ListCOUNTANYDUPLICATES_SLOW(LST)
//Caution ऊਉऊ be much slower but may be faster
//REAL LST NO DUPS:5s
//INT LST 8000 DUPS:0.2s
BEGIN
RETURN SIZE(LST)-SIZE(ListREMOVEDUPLICATES(LST));
END;
EXPORT ListCOUNTANYDUPLICATES_SORTED(SortedLST)
//Count how many duplicates in a sortedlist,Return a REAL INT
//({1,9,9}=1 dup, {1,2,2,3,3,3}=3 dup)
//Timings consistent 0.3s
BEGIN
LOCAL II;
LOCAL DUPCOUNT:=0;
IF SIZE(SortedLST)>1 THEN
FOR II FROM 1 TO SIZE(SortedLST)-1 DO
IF SortedLST(II) ==SortedLST(II+1) THEN
DUPCOUNT:=DUPCOUNT+1;
END;//IF
END;//FOR
//ELSE:SMALL LISTS HAVE NO DUPLICATES
END;//IF
RETURN DUPCOUNT;
END;
EXPORT ListExamples()
//In real use, use XXX:=List...()
BEGIN
LOCAL LL:={1,2,3,4,5,6,7,8,9};
PRINT();
PRINT("C");
PRINT("SLOW?");
PRINT(ListCOUNTANYDUPLICATES({0,2,2,2}));//INFINITE RECURSION COMPLETES
//SHOULD RETURN INTEGER (IF RECURSION CORRECTED) BUT RETURNS INPUT LIST
PRINT("D");
PRINT("Exampled");
//RETURN 0;
END;
EXPORT LBUG()
BEGIN
ListExamples();
END;
Instead of printing C and erroring, the code fragment prints
C
{Input list}
D
At the point where D is printed, the count contains a list instead of an integer, which could lead to subsequent bugs in the user code...It would be better if the recursion were trapped and subsequent code not executed.