3
$\begingroup$

For example, I wrote a function like this:

inversions[list_] := Complement[
  Subsets[{1, 2, 3, 8, 4, 7, 6, 5}, {2}],
  Subsets[list, {2}]
  ]

But as you see, every time I call inversions[list], the large constant expression Subsets[{1, 2, 3, 8, 4, 7, 6, 5}, {2}] is re-computed, which should've been avoided. Of course, I can achieve this by storing it as a global variable, like:

SUBSETS = Subsets[{1, 2, 3, 8, 4, 7, 6, 5}, {2}];
inversions[list_] := Complement[
  SUBSETS,
  Subsets[list, {2}]
  ]

But this variable SUBSETS is used for only the function inversions, and thus should've been bound to this function, instead of dangling in the global scope like this. How can I do better to avoid the scope pollution?

$\endgroup$
4
$\begingroup$

Use With. It will inject the pre-calculated value of the larger Subsets expression in your definition, but without “messing up” the readability of your code:

ClearAll[inversions]
With[
 {SUBSETS = Subsets[{1, 2, 3, 8, 4, 7, 6, 5}, {2}]},
 inversions[list_] := Complement[SUBSETS,Subsets[list, {2}]]
]

You can check that downvalues (i.e. the definition) of inversions includes the pre-calculated expression using ?inversions.

SUBSETS is treated like a macro in this context and it is never created as a symbol or given a definition, so it won’t “leak”.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Wow! I've never thought of putting a global definition inside a With. That should solve the problem. :-) $\endgroup$ – SneezeFor16Min Jun 22 at 4:30
2
$\begingroup$

But this variable SUBSETS is used for only the function inversions, and thus should've been bound to this function, instead of dangling in the global scope like this

You could put the stuff inside some new context? From clean Kernel

Begin["myStuff`"]
SUBSETS = Subsets[{1, 2, 3, 8, 4, 7, 6, 5}, {2}];
inversions[list_] := Complement[SUBSETS, Subsets[list, {2}]];
End[]

And now no one can access it by accident. It is not in Global context any more.

Mathematica graphics

To access anything in there, must use myStuff to see it.

 myStuff`inversions[{1, 2, 3}]

Mathematica graphics

| improve this answer | |
$\endgroup$
  • $\begingroup$ By this we avoid polluting one context by polluting another, and it's more cumbersome to invoke the function. $\endgroup$ – SneezeFor16Min Jun 22 at 4:43
  • 1
    $\begingroup$ @SneezeFor16Min it is an option. You do not have to use it. In Mathematica, there are 10 different ways to do the same thing. You choose which you like., $\endgroup$ – Nasser Jun 22 at 4:45

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.