The decisive behavior is described in the "More Information" section of the documentation for DynamicModule :
DynamicModule first gives unique names to local variables in expr expressions, like a module, then evaluates the resulting expression, and then returns the version of this package to DynamicModule.
The exact sequence of events becomes more apparent if you add a Print statement to the Initialization parameter, this way:
a = {1, 2, 3}; DynamicModule[{b}, Print[Dynamic[b]]; {Dynamic[a], Dynamic[b]} , Initialization :> (b = Length[a]; Print["init:", b]; a = a + 2) ]
resulting in three cells:
b$107 Out[7]= {{3, 4, 5}, 3} init:3
A cell containing b$107 is the result of Print inside a DynamicModule . Then we get the result cell (marked Out[7] here). Finally, we see the output of the third cell in the Print expression in Initialization .
If you check the cell expression of the Out[7] cell Out[7] , you will find that the localized variable is b$$ . This is different from the variable in the first cell, which is b$107 . This difference is due to the โdouble coverageโ described in the DynamicModule documentation. Cell b$107 contains the Dynamic field, as you can see if we assign the value b$107 .
Update
In response to an updated question ...
Returning to the original expression (without additional Print in Initialization ), the exact sequence of events is as follows:
First, the body of the DynamicModule is evaluated after providing "unique names to local variables [...] just like a module". That is, this expression is evaluated:
Print[Dynamic[b$107]]; {Dynamic[a], Dynamic[b$107]}
The result of this expression is the list {Dynamic[a], Dynamic[b$107]} . As a side effect, a dynamic cell is created containing b$107 , but this cell is now removed from further consideration, since it is not part of the evaluation result. Now "the version of [ {Dynamic[a], Dynamic[b$107]} ] is wrapped in a DynamicModule" and is back. This is evaluated and implicitly printed to create an expression of the output cells as follows:
Cell[BoxData[ DynamicModuleBox[{$CellContext`b$$ = 3}, RowBox[{"{", RowBox[{ DynamicBox[ToBoxes[$CellContext`a, StandardForm], ImageSizeCache->{57., {2., 8.}}], ",", DynamicBox[ToBoxes[$CellContext`b$$, StandardForm], ImageSizeCache->{7., {0., 8.}}]}], "}"}], DynamicModuleValues:>{}, Initialization:>($CellContext`b$$ = Length[$CellContext`a]; $CellContext`a = $CellContext`a + 2)]], "Output"]
Note that b$107 renamed to $CellContext`b$$ as a function for localizing the DynamicModule character. The expression Initialization now evaluated as the window is displayed and displayed.
The key point is that the print cell containing b$107 is not connected in any way with the last DynamicModule cell.