attributeswolfram-mathematicadrm

Any way to force Mathematica to remove the Locked attribute?


Obviously Mathematica is able to remove this attribute; it's just not letting me. Does anyone know of any hacks to force Mathematica to do what I say?


Solution

  • This is not a positive answer.

    One particular use case that might require removing the Locked attribute would be the local modification of a symbol with e.g. Internal`InheritedBlock. Often this scoping construct is used to change/remove attributes locally of system symbols, to yield a different behaviour for the scope of the block (see for example this answer).

    However, according to my research, out of the 38 Locked symbols (out of all contexts and packages loaded with Quiet[Needs /@ Contexts[]]!) none have any other functional attributes that, if changed, would result in modified behaviour (e.g. no Flat, Orderless, Hold***, etc.) and none of them have any Options that could be changed. Usually these symbols are very basic ones, almost all from the System` context e.g. I, List or True. The only 3 exceptions having either functional attributes or options are:

    (* Symbol *)                 (* Attributes *)              (* Options *)
    Remove                       {HoldAll, Locked, Protected}  {}
    $ProductInformation          {Locked, Protected}           {"ProductIDName" -> "Mathematica", "ProductKernelName" -> "Mathematica 9 Kernel", "ProductVersion" -> "9.0 for Microsoft Windows (64-bit) (January 25, 2013)", "ProductVersionNumber" -> 9.}
    Developer`StartProtectedMode {Locked, Protected}           {"Allow" -> Null, "Deny" -> Null, "Execute" -> {}, "Read" -> {}, "ReadWrite" -> {}, "Write" -> {}}
    

    So apart from modifying these remotely used functions, the only reason one would want to remove Locked is to directly modify some symbol's definitions. But this could only be performed if symbol also is ReadProtected, otherwise the code is written in lower-than-Mathematica-level that is completely hidden from the user (except perhaps high-level wrappers). There are only three such symbols (again, out of all standard contexts and packages):

    I                    (* with {Locked, Protected, ReadProtected} *)
    $InputStreamMethods  (* with {Locked, Protected, ReadProtected} *)
    $OutputStreamMethods (* with {Locked, Protected, ReadProtected} *)
    

    As a conclusion, I would say removing Locked wouldn't really give any advantage on exploring/modifying function internals for a great many functions, and also changing behaviour of such fundamental functions as I or $Input seems to be a very bad idea, so no one is likely to invest too much time in figuring out a hack.

    Furthermore, since Locked itself has the attribute Locked (since v9, in v8 it was only Protected), it cannot be redefined to e.g. Locked = Sequence[] before loading a package to bypass security even for encrypted stuff. One could redefine Attributes and SetAttributes before loading packages, but god knows what could go wrong if done so.

    Of course if the function is a packaged one and the package files are available and not encoded, one can remove attributes manually by editing the files directly. But according to my experience, the common tradition is that functions that are freely explorable in packages are not Locked.