Message Boards Message Boards

0
|
1759 Views
|
3 Replies
|
1 Total Likes
View groups...
Share
Share this post:

How to permanently store a function

Posted 11 months ago

I have an example of how to permanently store a variable with Set.

InitializationValue[myvar, "Local"] = 42

Initialize[myvar];

Is there a way to generalize this to SetDelayed? I want to store the following definition permanently but I'm not sure how to do it.

Unprotect[UnsortedComplement];
ClearAll[UnsortedComplement]
UnsortedComplement[alist_, del___, opt : OptionsPattern[]] := 
 Select[alist, Union[{#1}, Union[del], opt] =!= Union[del, opt] & ]

Options[UnsortedComplement] = {SameTest -> Automatic};
Protect[UnsortedComplement];

Would this be the solution, where UnsortedComplement is replaced with InitializationValue[UnsortedComplement, "Local"] everywhere?

Unprotect[InitializationValue[UnsortedComplement, "Local"]];
ClearAll[InitializationValue[UnsortedComplement, "Local"]]
InitializationValue[UnsortedComplement, "Local"][alist_, del___, 
  opt : OptionsPattern[]] := 
 Select[alist, Union[{#1}, Union[del], opt] =!= Union[del, opt] & ]

Options[InitializationValue[UnsortedComplement, 
    "Local"]] = {SameTest -> Automatic};
Protect[InitializationValue[UnsortedComplement, "Local"]];

Initialize[UnsortedComplement]

There is a helpful function PersistResourceFunction that can help. I've also tried using PacletizeResourceFunction. I tried building a paclet but Mathematica 13.3 froze. I then tried Wolfram Desktop 13.2, but it froze when I tried to build the paclet and I had to force the programs to close with Task Manager.

Since the paclet didn't work, I'm going to try Local as an alternative plan to paclets. The paclet finished building successfully in Wolfram Desktop 13.2. Now it's freezing again.

I don't want to evaluate the code because I don't know whats it doing and it has a side effect that I'm not sure how to undo.

I think the solution is CloudSave.

POSTED BY: Peter Burbery
3 Replies

I do not believe it is possible to use InitializationValue for a set-delayed value. I found this out when I tried to use the resource function "PersistResourceFunction" and found that it would load the definitions at kernel start time which is in my opinion unacceptable, and saw that it was implemented using InitializationValue.

Why not just do it the old fashioned way? Put something like this in your kernel init.m file

UnsortedComplement := (
  ClearAll[UnsortedComplement];
  UnsortedComplement[args__] := code here;
  (* protect it if you like *)
  UnsortedComplement
)

Or wrap it up in a package and use the paclet manager's autoloading mechanism, which I very much prefer over InitializationValue.

I actually only discovered "PersistResourceFunction" because my own submission "UseResourceFunctionAsSymbol" was rejected as a duplicate. My version of the function creates a local paclet called ResourceFunctionSymbols and will add resource functions to that paclet when you call it.

(* add a resource function to the list and then quit the kernel *)
UseResourceFunctionAsSymbol["UnsortedComplement"];
Quit[]

Now you always have the symbol UnsortedComplement available at kernel startup, without the overhead of InitializationValue:

In[1]:= OwnValues[UnsortedComplement] // Short 

Out[1]//Short= {HoldPattern[UnsortedComplement]:>Package`ActivateLoad[<<1>>]}

In[2]:= UnsortedComplement[{4, 4, 4, 4, 3, 3, 3, 2, 2, 1}, {3, 2}]

Out[2]= {4, 4, 4, 4, 1}

UseResourceFunctionAsSymbol is defined below.

setDefinitions[names_, context_] := ToExpression[
    Map[StringJoin[context, #]&, names],
    StandardForm,
    Function[Null,
        With[{sn = SymbolName @ Unevaluated @ #},
            # := # = ResourceFunction[sn, "Function"] (* ignore the syntax highlighting here, the FE is wrong *)
        ],
        HoldAllComplete
    ]
];
UseResourceFunctionAsSymbol[function_String, Optional[context_String, "Global`"]] := Module[
    {
        functions,
        pacletDir = FileNameJoin @ {$UserBasePacletsDirectory, "Repository", "ResourceFunctionSymbols"}
    },
    If[
        FailureQ[Quiet @ ResourceFunction @ function],
        Return[$Failed, Module]
    ];
    functions = Replace[ResourceFunctionSymbols`Private`$installedResources, Except[_ ? ListQ] :> {}];
    Quiet @ PacletManager`PacletUninstall @ "ResourceFunctionSymbols";
    If[DirectoryQ[pacletDir],
        DeleteDirectory[pacletDir, DeleteContents -> True]
    ];
    AppendTo[functions, function];
    ResourceFunctionSymbols`Private`$installedResources = functions;
    setDefinitions[functions, context];
    functions = Append[functions, "$installedResources"];
    Block[{$ContextPath = Join[$ContextPath, {"ResourceFunctionSymbols`Private`"}]},
        ResourceFunction["Pacletize"]["ResourceFunctionSymbols", functions, FileNameDrop @ pacletDir]
    ];
    Symbol @ function
]
POSTED BY: Jason Biggs
Posted 11 months ago

Take a look at LocalSymbol.

POSTED BY: Rohit Namjoshi

This is a problem. Local symbols cannot be assigned subvalues or other special values: LocalSymbol["f"][x_] := x^2 This is under possible issues.

POSTED BY: Peter Burbery
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract