4
$\begingroup$

The code

Block[{f}, f := test; Definition[f]]

Outputs Null. Why? I would have expected it to output the definition of f, like f := test; Definition[f] does.


Does it have to do with Definition being an output form. If so how can I get a function that does the exact same thing but that really evaluates to the value shown as output?

$\endgroup$
1
  • $\begingroup$ it is because Definition and similar functions Print the definitions associated to the symbol, instead of giving them as output. Are you asking for a function that takes a symbol as input and gives the definitions as output? $\endgroup$
    – glS
    Jul 20, 2017 at 9:16

3 Answers 3

3
$\begingroup$

It does not work because Definition does not evaluate.

It is a wrapper which is formatted the way you are familiar with.

f:="test"

FullForm @ Definition[f]
Definition[f]

So during evaluation definitions are not (meant to be) collected, Block returns Definition[f] and later it is formatted to Null as our Block does not exist anymore.

Print workaround works because it forces print cell creation, so formatting and typesetting too, before Block is done. So definitions can be collected.

Another way to force formatting stage:

Block[{f}, f := test; ToString[Definition[f], InputForm]]

it is better than Print because the latter can be sent to the console, depending on your settings.

$\endgroup$
2
$\begingroup$

If you just need to get a cell that prints the definition of f while Blocked, you can use Print since Print will create the cell while f is still Blocked:

Block[{f}, f := test; Print[Definition[f]]]
$\endgroup$
2
$\begingroup$

I'm not entirely sure of what you are asking for, but here is a simple (and naive, it will probably not work on more complicated cases) way to convert the output of DownValues to a format similar to the output of Definition:

definitions[symb_Symbol] := DownValues @ symb /. {
    Verbatim[RuleDelayed][a_, b_] :> Hold[SetDelayed[a, b]]
    } /. Verbatim[HoldPattern][args__] :> args

for example:

foo[x_] := x + 2;
foo[x_List] := x + 3
foo[x_, y_] := x + y
definitions @ foo

produces

{Hold[foo[x_List] := x + 3], Hold[foo[x_] := x + 2], Hold[foo[x_, y_] := x + y]}

To also remove the Hold from the output you can use this other version:

definitions[symb_Symbol] := DownValues @ symb /. {
     Verbatim[RuleDelayed][a_, b_] :> Hold[SetDelayed[a, b]]
  } /. Verbatim[HoldPattern][args__] :> args /. {
     Hold[args__] :> Defer[args]
  }

Replacing DownValues with Definitions from GeneralUtilities should moreover generalise the function to also capture UpValues, OwnValues etc.

$\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.