# Memoization only under certain conditions

I have a function that takes in sequences of values (as a list), and recursively removes the largest element from that sequence as part of its computation. Some of these sequences can be quite large, but I suspect that they often have common subsequences. So I want to memoize my function, but I don't want to memoize it for very large sequences, only smaller sequences which these larger sequences might have in common. I tried something like this,

f[sequence_?Length[#] < 16 &] := f[sequence] = f[sequence]


where f is already defined elsewhere. Probably I would need to memoize for larger sequences, but that's the idea of it. However, I hit the recursion limit when I call this function.

• Is the second f[sequence] on the right-hand side actually some expression involving sequence? And as far as the left-hand side goes, I think you need to do f[sequence_?(Length[#] < 16 &)] because of operator precedence issues. Commented Aug 2, 2016 at 23:11
• The second f[sequence] on the right hand side is defined like f[sequence_] := .... Adding parenthesis doesn't change the error I get. Commented Aug 2, 2016 at 23:12
• This feels like an xy problem - why not show an example of what it is you're trying to get to, and why - there's probably a succinct and efficient way to do it...
– ciao
Commented Aug 2, 2016 at 23:16
• By the way, it is a good idea to wait for at least a day before accepting an answer. That way, you will likely attract more answers, and they might be more to your liking (that green check-mark can be a deterrent to new answers!). In addition, @ciao's point is well-taken: you might consider outlining your actual problem (although I like the particular question of sometimes-memoization, although now that I think about it, I suspect this might be a duplicate...) Commented Aug 2, 2016 at 23:29
• @march, Thanks, I'll keep that in mind. Also with regards to being a duplicate, I searched but couldn't find anything on this. Commented Aug 2, 2016 at 23:43

Define the function twice, once without the memoization, and once with the memoization and your condition.

Consider this simple example:

Clear@f
f[{}] = {};
f[a_List] := Rest@a
f[a_List /; Length@a <= 3] := f[a] = Rest@a


If we run

FixedPointList[f, Range[5]]
(* {{1, 2, 3, 4, 5}, {2, 3, 4, 5}, {3, 4, 5}, {4, 5}, {5}, {}, {}} *)


then

Notice that it has saved only those lists of length less than 4.

Alternatively, if it is annoying to define the function twice, do this instead. It works the same.

Clear@f
f[{}] = {};
f[a_List] := If[Length@a > 3, #, f[a] = #]&@Rest@a

• This does indeed fix my problem. I just wish there was an elegant way to do it, without all the code repetition. Commented Aug 2, 2016 at 23:19
• @JordyDickinson. In my opinion, this sort of construction is elegant, and is very Mathematica-idiomatic. But I have posted an alternative solution. Commented Aug 2, 2016 at 23:22