8
$\begingroup$

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?

$\endgroup$
1
  • 1
    $\begingroup$ 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). $\endgroup$ Jun 21, 2013 at 0:24

1 Answer 1

4
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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