![]() |
  |
|
4.9.1.3 A way out in some cases As another example of the similar kind, consider a following one: we are given some function , say < f >, and two lists , say {1, 2} and {3, 4, 5}, and wish the output be a list : {f[1, {3, 4, 5}], f[2, {3, 4, 5}]} - that is, to thread < f > over the first list but not the second. For the same reason as above, the straightforward attempt to assign a listable attribute to < f > will fail :
I can' t help showing here a hack which solves this sort of problems and which is related to the use of Listable SubValues, although it is perhaps a bit too advanced at this point.The idea is that we will create a higher - order function which will take < f >, and both of our lists as parameters. Here is the code :
Check :
What happens here is that an auxiliary function is defined inside Module, but if you look carefully at its definition you will realize that it corresponds to global rules stored in SubValues rather than DownValues (section 2.2.5), because the function <auxf[x]>, considered as a function of <y>, has a composite (non-atomic) head. Setting the Listable attribute to < auxf > will then only affect the "first" argument < x >, but not < y > . Note also that neither <t> nor <z> needs to be localized since SetDelayed is used in the definition, and thus they are local to the auxiliary function scope automatically. The Through operator is needed here as well - it is covered at the end of chapter V. This trick is trivial to generalize to the total <n> number of arguments, out of which you need your function to be Listable on <k>: just place these <k> first - in the place of our <t>, and the rest - in the place of <z>: auxf[arg1...argk][arg(k+1)...argn].
|
|||||||||||||||||