I recently ran into an interesting twist on the infamous Maple anti-pattern:

# A very garbagey way to build a list
l := [];
for i from 1 to 10000 by 100 do
l := [op(l), isqrt(abs(floor((5000-i)/2)))];
end do;

A lot of users fall prey to this method of building a list rather than using :

# generate a list without extraneous garbage
l := [seq(isqrt(abs(floor((5000-i)/2))),i=1..10000,100)];

So, now the twist. The same problem can also crop up in taking a list apart.

# A very garbagey way to find the min in a list
while nops(l) > 1 do
if l[1] > l[2] then
l := subsop(1=NULL, l);
else
l := subsop(2=NULL, l);
end if;
end do;
op(l);

Upon first glance this code is pretty clever, but in fact, it has exactly all the bad features of constructing a list in a loop, namely, for a list of length N, the loop uses memory O(N^2). In this case, the boring method is much better:

# find the min without extra garbage
m := l[1];
for i in l do
if m > i then
m := i;
end if;
end do;
m;

Of course, you should really use min, but in this case the user was implementing with a custom comparator like the two argument version of sort.

These code snippets are also good arguments for programming in a font that allows one to distinguish between 1, l, and i (and I and |) at glance. (Bad even in <tt> for my browser font: )


Please Wait...