John Fredsted posted some interesting code dealing with permutations, and I suggested a small improvement.  Here, I want to continue the story of that improvement.  First, let us focus one particular line of code:

  posMaps,negMaps := seq(map((perm::list) ->
		(x::list) -> [seq(op(perm[i],x),i=1..nops(perm))]
	,perms),perms in [posPerms,negPerms]);

which uses a lexically scoped procedure to perform the permutations. The first thing to notice is that op(perm[i],x) is really equivalent to x[perm[i]]. Now that we have that perky op gone, we see that the resulting code expression will return unevaluated if x is unknown, unlike op which throws an error message (correctly so!). So now instead of using scoping, we can let Maple actually evaluate the inner perm[i] calls, and use unapply to recover a routine. Putting that together gives us my suggestion:

posMaps,negMaps := seq(map((perm::list) -> unapply([seq(x[perm[i]],i=1..nops(perm))],x),perms), 
perms in [posPerms,negPerms]);

But now we see that we are using a seq over an integer range where we could have simply done

seq(x[p],p in perm)

which is clearer indeed. Now we can really get tricky: we notice the seq builds a list, but perm is a list, so shouldn't we use map? We sure can! Our first try is

map(y -> x[y], perm)

which works. But it still needs a function. Can we get fancy and replace it too? Yes! We can do:

map2(`?[]`, x, map(`[]`,perm))

Ok, that sure was fun. But that last step was too much. The problem is that the inline version of table selection wants a list as a second argument, and that makes things less clear. So let's go back one step, and stare at what we have next:

map((perm::list) -> unapply(map(y->x[y],perm),x),perms)

Can we do anything we that? I don't see anything obvious. Looking at the whole code, there does not seem to be other available 'simplifications'. There are transformations one might do, but none of them seem to be an actual improvement. What is my favourite version? This one:

posMaps,negMaps := seq({seq}(unapply(map2(`?[]`,x,map(`[]`,perm)),x),perm in perms),
perms in [posPerms,negPerms]);

There are lots and lots of loops and function applications going on, but no inline functions in sight. I would not use this exact version in production code, but it is still my favourite.


Please Wait...