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.

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?

share|improve this question
1  
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

1 Answer 1

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.

share|improve this answer

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.