Wolfram Research

LocalEvaluate

Contributed by: Richard Hennigan (Wolfram Research)

Synchronously evaluate an expression in a separate kernel

ResourceFunction["LocalEvaluate"][expr]

evaluates expr in a separate kernel and returns the result.

ResourceFunction["LocalEvaluate"][expr,wrapper]

wraps the head wrapper around the result before returning it.

Details and Options

LocalEvaluate has attribute HoldFirst.
LocalEvaluate[expr] automatically includes all definitions needed to evaluate expr, much like CloudEvaluate.
The following options can be given:
HandlerFunctions <| |> how to handle generated events
HandlerFunctionsKeys Automatic parameters to supply to handler functions
IncludeDefinitions True whether to include any dependent definitions
Initialization None an expression to be evaluated as part of the kernel initialization
During the evaluation, the following events can be generated:
"TaskStarted" task is started
"FailureOccurred" task could not be started
"ScheduleTriggered" scheduled task evaluation is beginning
"MessageGenerated" evaluation generated a message
"PrintOutputGenerated" evaluation generated print output
"ResultReceived" evaluation generated a result
"ScheduleExecuted" scheduled task evaluation is executed
"TaskStatusChanged" task status changed
"TaskRemoved" task is being removed
With the specification HandlerFunctions<|,"eventi"fi,|>, fi[assoc] is evaluated whenever eventi is generated. The elements of assoc have keys specified by the setting for HandlerFunctionsKeys.
LocalEvaluate initiates a new subkernel whenever it is called.

Examples

Basic Examples

Run an evaluation in a separate kernel:

In[1]:=
ResourceFunction["LocalEvaluate"][$ProcessID]
Out[1]=

Compare to the current kernel:

In[2]:=
$ProcessID
Out[2]=

More Examples

Scope

Retrieve the ResourceFunction:

In[3]:=
ResourceFunction["LocalEvaluate"]
Out[3]=

Retrieve the ResourceObject:

In[4]:=
ResourceObject["LocalEvaluate"]
Out[4]=

Supply a head to be applied to the results of a local evaluation:

In[5]:=
ResourceFunction["LocalEvaluate"][25!, wrapper]
Out[5]=

Options

IncludeDefinitions

By default, definitions are included:

In[6]:=
f[x_] := x + 1;
ResourceFunction["LocalEvaluate"][f[5], Hold]
Out[7]=

Don't include any definitions in the evaluation:

In[8]:=
ResourceFunction["LocalEvaluate"][f[5], Hold, IncludeDefinitions -> False]
Out[8]=
Initialization

Specify an initialization that should evaluate first:

In[9]:=
ResourceFunction["LocalEvaluate"][g[5], Initialization :> (g[x_] := 2 x)]
Out[9]=

The initialization only runs on the other kernel, the current kernel is not affected:

In[10]:=
g[5]
Out[10]=

Using Automatic for Initialization is equivalent to using Get[FindFile["init.m"]]:

In[11]:=
Put[Unevaluated[h[x_] := x!], FindFile["init.m"]];
FilePrint[FindFile["init.m"]]
In[12]:=
ResourceFunction["LocalEvaluate"][h[25], Initialization -> Automatic]
Out[13]=

The symbol h is undefined otherwise:

In[14]:=
ResourceFunction["LocalEvaluate"][h[25]]
Out[15]=

Applications

Discover symbols in a package without loading it in the current kernel:

In[16]:=
ResourceFunction["LocalEvaluate"][Needs["ComputerArithmetic`"]; Names["ComputerArithmetic`*"]]
Out[16]=

The current kernel is unaffected:

In[17]:=
Names["ComputerArithmetic`*"]
Out[17]=

Check how many symbols have been created in your current session that aren't created by default:

In[18]:=
Length@Complement[Names[], ResourceFunction["LocalEvaluate"][Names[], Initialization -> Automatic]]
Out[18]=

Manipulate notebooks with a hidden front end:

In[19]:=
ResourceFunction["LocalEvaluate"][
 UsingFrontEnd@
  NotebookGet@
   NotebookPut@
    Notebook[{Cell["Testing", "Section"], Cell["Hello world", "Text"]}]]
Out[19]=

Properties and Relations

Each evaluation of LocalEvaluate runs in a new kernel:

In[20]:=
ResourceFunction["LocalEvaluate"][{$ProcessID, SessionTime[]}]
Out[20]=
In[21]:=
ResourceFunction["LocalEvaluate"][{$ProcessID, SessionTime[]}]
Out[21]=

Compare to the current kernel:

In[22]:=
{$ProcessID, SessionTime[]}
Out[22]=

Similar behavior to LocalEvaluate can be obtained by using TaskWait with LocalSubmit:

In[23]:=
TaskWait@LocalSubmit[SessionTime[], HandlerFunctions -> <|
     "TaskFinished" -> (($result = #EvaluationResult) &)|>];
$result
Out[24]=

Possible Issues

Messages that are issued from the other kernel aren't printed in the current session:

In[25]:=
ResourceFunction["LocalEvaluate"][First[1], Hold]
Out[25]=

Use HandlerFunctions to handle messages:

In[26]:=
ResourceFunction["LocalEvaluate"][First[1], Hold, HandlerFunctions -> <|
   "MessageGenerated" -> (Message[#MessageOutput] &)|>]
Out[27]=

Resource History