Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have written a Mathematica script in which I define functions and variables. Here is a vastly simplified example:

myFunA[int_Integer] := int + 1
myFunB[int_Integer] := int * 2
myFunC[int_Integer] := int - 3

myVarA = 1;
myVarB = 2;
myVarC = 3;

(In my actual script, the function and variable names vary; they do not follow the form myFunX, myVarX, etc.)

I would like to Clear (or otherwise delete) all of the variables (myVarA, myVarB, myVarC) but not the functions (myFunA, myFunB, myFunC). Is this possible (without explicitly Clearing each of the many variables, since my actual script defines several dozen variables)? Thank you for your time.

share|improve this question
add comment

1 Answer 1

up vote 15 down vote accepted

Automatic way based on Names

Here is a simple modification of the recent answer of @R.M, which is based on the definiton of a variable as a symbol which has an OwnValue defined:

Clear @@ 
   Select[
      Names["Global`*"], 
      ToExpression[#, StandardForm, 
         Function[sym, OwnValues[sym] =!= {}, HoldAll]
      ] &
   ]

If your code is in some context other than Global` (which is what I'd recommend), you can put that context in place of Global` above.

Automation based on custom assignment operator

As an alternative, and IMO more systematic way, you may define a custom assignment operator which you'd use when defining a variable:

ClearAll[defVar, $variables, clearVars];

$variables = Hold[];

SetAttributes[defVar, HoldAll];
defVar[def : ((Set | SetDelayed)[lhs_Symbol, rhs_])] :=
  With[{result = def},
    $variables = Append[$variables, Unevaluated[lhs]];
    result];

clearVars[] := $variables /. Hold[vars__] :> Clear[vars];

Now, you use this as

myFunA[int_Integer] := int + 1
myFunB[int_Integer] := int*2
myFunC[int_Integer] := int - 3

defVar[myVarA = 1];
defVar[myVarB = 2];
defVar[myVarC = 3];

And then,

clearVars[]

A digression: evaluation leak in AppendTo

Interestingly, in the line $variables = Append[$variables, Unevaluated[lhs]], you can not use AppendTo instead, at least not in the form one would expect it to work. The reason is rather subtle: AppendTo seems to be implemented in the top-level code, but more importantly, it leaks evaluation:

vars = vars1 = Hold[];
a=1;
AppendTo[vars,Unevaluated[a]];
AppendTo[vars1,Unevaluated@Unevaluated[a]];
{vars,vars1}

(* {Hold[1],Hold[a]} *)

You see that an extra layer of Unevaluated is necessary to counter the evaluation leak. I would think this is a wrong behavior for AppendTo, but can not state with definiteness that this is a bug.

Remarks

Which way to choose depends on the situation. The first method is fully automatic and will work best if you keep all your work in a specific context distinct from Global`. The second way requires more discipline but works regardless of the contexts you are using.

share|improve this answer
1  
Using OwnValues as suggested has one possible drawback: it would select, among other entities, a symbol defined to be a pure function. –  murray Sep 27 '12 at 15:05
    
@murray That the symbol contains a value that happens to be a pure function does not make that symbol be not a variable. Rather, it confirms that Mathematica is a functional language (or, rather, an emulation, but often we don't have to make a difference), where functions are values, as well as other types. Only my opinion, of course. And I agree with you that this creates an ambiguity in the question, but then the question itself has to be better formulated to cover this case. –  Leonid Shifrin Sep 27 '12 at 16:12
1  
@murray Actually, I really agree with you that the type of automation provided by the first method may be too dangerous since it takes a rather cavalier approach towards variable clearing. This was the whole reason why I described the second one, where you have a choice to not wrap defVar around an assignment if you don't want to treat the symbol there as a variable. –  Leonid Shifrin Sep 27 '12 at 16:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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