6
$\begingroup$

My question is very similar to https://stackoverflow.com/questions/5840313/how-to-get-all-definitions-associated-with-other-symbols except I am looking to find all definitions in which a symbol appears.

I.e. I want an ever more full definition than FullDefinition.

Taking their example:

g[x_] := x^3;
f[x_] := g[x^2];

I want something to return the definition of f[x_] when asking for the fullestDefinition[g]. (Also perhaps a better example would be if f was replaced by CenterDot since I also want to consider built-in functions.)


My attempt, which actually works better now than when I started asking this question, but errors are popping up when I start checking the RHS of rules ;) :

SetAttributes[otherValues,HoldFirst]

otherValues[sym_]:=With[{names=MakeExpression/@Names["*"] },
    Join[
        Cases[DownValues@@@names,HoldPattern[RuleDelayed[in_,out_]/;Not[FreeQ[in,sym]]],{2}],
        Cases[SubValues@@@names,HoldPattern[RuleDelayed[in_,out_]/;Not[FreeQ[in,sym]]],{2}],
        Cases[UpValues@@@names,HoldPattern[RuleDelayed[in_,out_]/;Not[FreeQ[in,sym]]],{2}],
        Cases[NValues@@@names,HoldPattern[RuleDelayed[in_,out_]/;Not[FreeQ[in,sym]]],{2}],
        Select[Join@@FormatValues@@@names,!FreeQ[#,HoldPattern@sym]&]]]

WReach suggested

Needs["GeneralUtilities`"];
DefinitionCases["Global`", g]

But in the example:

g[x_] := x^3;
CenterDot[x_] := g[x^2];
DefinitionCases["Global`", g]

This does not return the CenterDot definition containing g. I also tried DefinitionCases["*", g] but it returned an empty list.

However, we can search in System`:

DefinitionCases["System`", g]

which returns what we want (but also returns historic In and Output that contains the symbol it would be nice if we could exclude this.).

$\endgroup$
5
  • 4
    $\begingroup$ One way is to evaluate Needs["GeneralUtilities`"] followed by DefinitionCases["Global`", g]. Does this suit your purpose? $\endgroup$
    – WReach
    Mar 5 at 17:28
  • $\begingroup$ @WReach, that seems to be exactly what I need! (So I would also accept it as an answer.) (Oops no, spoke too soon. Doesn't seem to catch everything.) $\endgroup$
    – Kvothe
    Mar 5 at 18:03
  • $\begingroup$ @WReach, so if we replace f with CenterDot in the example above that definition is not returned. I tried changing the context to "*" since that works in Names but then it returns only an empty list. $\endgroup$
    – Kvothe
    Mar 5 at 18:13
  • $\begingroup$ Okay DefinitionCases["System`", g] does work for this. (The first time it required me to log in to Wolfram Cloud services for some reason during the command.) So searching in both Global` and System` should give me what I want. I do see it also returns history containing the pattern. This could potentially be problematic if it makes the search enormous. (I was worried the System search was already taking forever but the hang seems to have been caused by the weird Wolfram Cloud login requirement.) It would be nice perhaps if we could exclude In and Output from this search. $\endgroup$
    – Kvothe
    Mar 5 at 18:19
  • $\begingroup$ I have posted an answer for completeness but I wonder whether there are more caveats than benefits to using it for your purpose :( $\endgroup$
    – WReach
    Mar 5 at 19:06

1 Answer 1

4
$\begingroup$

One way is to use GeneralUtilities`DefinitionCases:

g[x_] := x^3
f[x_] := g[x^2]
CenterDot[x_] := g[x^2]

Needs["GeneralUtilities`"];
DefinitionCases["Global`", g]

(* {HoldPattern[f[x_]] :> g[x^2], HoldPattern[g[x_]] :> x^3} *)

DefinitionCases has some limitations. Notice how the definition for CenterDot was not listed. That is because the symbol is in the System context. We can scan the system context, but there are caveats:

(* not recommended, see discussion *)
Block[{In, Out}, DefinitionCases["System`", g]]

First, we had to block the In and Out symbols to suppress any references to g in the history. Second, and more important, there are a great many auto-loaded symbols in System which trigger side-effects such as connecting to Wolfram cloud, downloading content, etc. In practice, I find the reflection side-effects can be harmful so scanning the system context is not always practical. Beware that any strategy that ends up scanning all symbols can run afoul of these side-effects.

One can also specify DefinitionCases[All, ...] to scan all contexts but it suffers from the same issues as scanning the system context. And it can sometimes take quite a long time as well.

Finally, I will note that there also exists PrintDefinitionCases which produces a human-readable display, But this feature seems to have become neglected in recent releases and the display is not as pretty as it once was.

$\endgroup$
3
  • $\begingroup$ Thanks! Those seem to be some pretty serious caveats. I wonder what things I messed up by scanning over all System symbols. (Pretty bad design on Mathematica's part by the way.) I'd have to look better but perhaps the answer you linked contains a safer method to scan only over a subset that is safer to evaluate. $\endgroup$
    – Kvothe
    Mar 5 at 19:19
  • $\begingroup$ I don't think the side-effects have any permanent effect upon your installation although the current session could be left in an odd state. I use DefinitionCases from time to time with good effect but I mainly steer clear of larger contexts distributed by WRI. $\endgroup$
    – WReach
    Mar 5 at 19:41
  • $\begingroup$ It seems like there might have been long term damage actually. Even after restarting my computer. It takes much longer to start a kernel and Mathematica seems much slower and the WolframKernel is using a full CPU while I'm not evaluating anything. Might have to get rid of all temporary files again. (And sort out the customization that I made that I do want to keep.) $\endgroup$
    – Kvothe
    Mar 5 at 20:47

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.