# Is it possible to write a function immune to symbol redefinitions in any Block surrounding its invocation?

Normally, semantics of symbols used in a function definition can be changed by their redefinitions in Blocks surrounding the function invocation:

primeCheck[n_Integer] := If[PrimeQ[n], "prime", "composite"];

primeCheck[10]
(* composite *)

Block[{PrimeQ = True&}, primeCheck[10]]
(* prime *)


Is it possible to make a function definition immune to any symbol redefinitions in Blocks or somehow restore the original global definitions of symbols being used in the function body (without making the symbols Locked that would globally prevent changing their meaning)?

A related question:
I assume there is no way whatsoever to unlock a Locked symbol, right?

-
Compile seems to immunize those parts of functions that can be successfully compiled to a register machine code (except when the CompiledFunction symbol itself is redefined by a Block). –  Vladimir Reshetnikov Jun 21 '13 at 0:24

I am not aware of any method that would make your function immune on the level of a standalone function, if you allow redefinitions of built-in functions with Block, as in your post. Neither seems there to be a way to "unblock" blocked definitions (I was wondering about this myself a while ago (see my second post in that thread), but there seems to be no way to do this). It may also be my ignorance, of course, but it looks like there is little you can do on the level of your function only.

What you can do however, although this is a rather radical measure, is to use Block to disable inner Block-s themselves. Here is how it can look:

Block[{Block},
SetAttributes[Block,HoldFirst];
Block[{PrimeQ=True&},
primeCheck[10]
]
]

(* "composite" *)


so, you can create a dynamic environment in which Block is disabled:

ClearAll[withDisabledBlock];
SetAttributes[withDisabledBlock,HoldAll];
withDisabledBlock[code_]:=
Block[{Block},
SetAttributes[Block,HoldFirst];
code
];


so that any code executed within this environment will have all invocations of Block down the execution stack disabled.

Needless to say, this can be a very error-prone thing, since Block could have been used constructively and disabling it across all execution stack may lead to errors, perhaps quite subtle (Block could have been used also in the implementations of some built-in functions).

One can perhaps make a more elaborate version of Block, by overloading it, so that it only disables blocking of built-in symbols. This is a little harder task, but should be quite doable. I can look at it closer later, if there is some interest in that.

-