5
$\begingroup$

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?

$\endgroup$
2
  • $\begingroup$ Possible duplicates: (7972), (9440), and one on StackOverflow. $\endgroup$
    – Mr.Wizard
    Feb 14, 2013 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, 2013 at 23:29

2 Answers 2

7
$\begingroup$

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} *)
$\endgroup$
5
  • $\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, 2013 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, 2013 at 1:27
  • $\begingroup$ +1 on Q&A in light of this not being a proper duplicate. $\endgroup$
    – Mr.Wizard
    Feb 14, 2013 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, 2013 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, 2013 at 10:51
3
$\begingroup$

An alternative

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

So

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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