Say I have a function with a few definitions that also implements memoization:

f[x_] := f[x] = x^2
f[x_, y_] := f[x, y] = x^2 + y^2

I then apply the function to some data:

f /@ {1, 2, 3}
f @@@ {{1, 2}, {3, 4}}

Now the function will have a bunch of DownValues both for the stored results and for the pattern based definitions. Is there some easy way to retrieve only all the stored result, leaving out the pattern based definitions?

  • $\begingroup$ Possible duplicates: (7972), (9440), and one on StackOverflow. $\endgroup$
    – Mr.Wizard
    Feb 14 '13 at 1:09
  • $\begingroup$ one way of extracting the inputs/outputs: Cases[DownValues[f], (_[Verbatim[f][value : Except[_Pattern]]] :> result_) :> (value -> result)] (general note: i figure this out by using FullForm. e.g. FullForm[x_] => Pattern[x, Blank[]]) $\endgroup$
    – amr
    Dec 31 '13 at 23:29

You can use FreeQ and select only those down-values that are free of Pattern:

Select[DownValues@f, FreeQ[#, Pattern] &]
(* {HoldPattern[f[1]] :> 1, HoldPattern[f[2]] :> 4, HoldPattern[f[3]] :> 9, 
    HoldPattern[f[1, 2]] :> 5, HoldPattern[f[3, 4]] :> 25} *)
  • $\begingroup$ R.M please see my comment above. Do you think this is a duplicate? It's not exact but I think the earlier answer also answer this one. $\endgroup$
    – Mr.Wizard
    Feb 14 '13 at 1:11
  • 1
    $\begingroup$ @Mr.Wizard I don't think it's a duplicate, because Simon's question was about clearing DVs with exactly $n$ arguments. It so happens that your code (with slight modification) would do this, but I don't think it would be obvious to a user who reads it thinking it's a dupe. Simon's (the Aussie one) question on SO though, is an almost dupe — if it had been on this site, I would've probably closed as a duplicate w/ a comment explaining the minor change needed. In any case, if this eventually gets closed, so be it :) $\endgroup$
    – rm -rf
    Feb 14 '13 at 1:27
  • $\begingroup$ +1 on Q&A in light of this not being a proper duplicate. $\endgroup$
    – Mr.Wizard
    Feb 14 '13 at 5:24
  • 2
    $\begingroup$ Depending on how you interpret the question, you could potentially use Free[#[[1]],Pattern]& to only select the patterns that don't involve pattern-matching, and not sort out those that might return a pattern or use a pattern in it's definition. For instance `f[b]=a_:>a $\endgroup$
    – jVincent
    Feb 14 '13 at 9:30
  • $\begingroup$ Nice! This also seems to be the faster solution when the number and size of the DownValues get big. $\endgroup$
    – Mr Alpha
    Feb 14 '13 at 10:51

An alternative

SetAttributes[getImmediateDownvalues, {HoldFirst, Listable}];
getImmediateDownvalues[sym_Symbol] := 
   PrependTo[DownValues[sym], HoldPattern[sym[] /; tag] :> Null];
     sym], ! MatchQ[#, Verbatim@HoldPattern[sym[] /; tag] :> _] &]]]


(* {HoldPattern[f[1]] :> 1, HoldPattern[f[2]] :> 4, 
 HoldPattern[f[3]] :> 9, HoldPattern[f[1, 2]] :> 5, 
 HoldPattern[f[3, 4]] :> 25} *)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.