# How are function definitions distributed to parallel kernels?

For example, I define a function f.

f[x_] := x^2;


And when I execute

ParallelTable[f[i], {i, 1, 10}]


I get

{1, 4, 9, 16, 25, 36, 49, 64, 81, 100}


as expected. (my function definition has propagated to the parallel kernels)

Now, if I do

Unprotect[Print];
Print = Null;


and

ParallelDo[Print[i], {i, 1, 10}]


I expect nothing to be printed out because I have changed the Print function. But instead, I get the printout.

1
3
5
7
9
10
2
4
6
8


Why did my function definition propagate to the parallel kernels in the first example, but not in the second example?

• Seemingly minor but important point: Definitions are shared among subkernels. They are "distritbuted" (copied to) the subkernels directly from the main kernel. I changed the title to avoid confusion with SetSharedVariable/SetSharedFunction. – Szabolcs Oct 12 '16 at 7:13

Print didn't get distributed because it was in the System context. By default only Global (or rather $Context) symbols are distributed. Definitions are sent to subkernels using DistributeDefinitions. Both this function and those that call is have the DistributedContexts options which usually defaults to $DistributedContexts, which in turn is set to

$DistributedContexts :=$Context


You can set these to choose which contexts will get distributed.

Auto-distributing everything by default would lead to breakage soon due to many different reasons (loading a package often does more than issue definitions, some contexts hold mutable state such as caches, etc.)

Related:

That said, attempting to distribute (automatically or manually) any System symbols is a patently bad idea that could very easily lead to breakage. While I haven't tried to find out if it is so, I wouldn't be surprised if the system protected itself against this even beyond the fact that these symbols are Protected` on the subkernels as well, which alone would break distribution anyway.