# How to assemble and disassemble a function into steps

I've watched many programmers (both novice and expert) write functions in Mathematica and have observed a common behavioral pattern. This pattern has many elements that would be automated and thus coding speed improved!

Set Up

A Mathematica function can be thought of as a sequence of transformations, or as I like to say a pipeline. The function arguments go into the mouth of the pipeline, a local scope of variables is generated and a sequence of expressions (e.g. the cylindrical components of the pipeline) are evaluated, and finally a value comes out at the end.

So in general, functions that use Module's can be expressed as 4-tuples:

{functionName, args, localVars, steps, returnedVar}


which refer to some part of a nicely formatted code cell like this:

functionName[args....] := Module[{localVars...},
steps[[1]];
...
steps[[n]];
returnedVar
]


Now here's my observation:

When starting to write or debug a function, most people seem to be looping over the two following steps, the process of which I want to automate.

Step 1: Disassemble (code cell -> input cells) We want to see what values are transformed in each step of the function. So we manually "explode" the function into separate input cells for each step. Practically, this means the following:

• Create a new section of a notebook
• Setup the arguments as variables and seed them with appropriate test values
• Make a sequence of input cells from the expressions in the module's body

Now, after all the steps are working for a single input, the developer wants to reshape them into a proper function and map it over many inputs and presumably use the results elsewhere. Ok great, so we do that in step 2!

Step 2: Reassemble (code cell <- input cells) Manually put it all back together into code cell with nice tabs and clean up the scope the old value whichThis wastes a lot of time!

At long last the coder has a lovely working function, that is, until it breaks or needs improvements and then it's back to step 1!

Conclusion: Both steps 1 and 2 are bookkeeping, so we shouldn't have to do them by hand and automating this would speed up development by an order of magnitude. A dev-tool achieving this would allow for an awesome level of functional introspection and visualization. Now who can build this?

Notes:

• The assistant bar hints at this idea of automating the rolling up and unrolling of code.
• Loggers and debuggers (both mma & workbench) are useful but are overkill at the beginning of the dev-cycle when you are building an algorithm from scratch.
• I voted for this question (only now as I am seeing it for the first time) because I find it quite interesting. However I do not understand the specific disassembly that you describe. Could you give a complete example for a section of code not written in procedural style? – Mr.Wizard Dec 26 '14 at 9:07
• I tried to implement a part of this some time ago, a button which would break apart a CompoundExpression into separate input cells and another to reverse the process. I seem to have lost the notebook though. I do recall that I was never really happy with it and decided that it was easier just to use the divide and merge cells keyboard shortcuts. – Simon Woods Dec 26 '14 at 17:29

This seems like more of a feature request for Mathematica Notebooks (which you can submit here) than an issue that can be completely addressed here. The people who can best implement the functionality you want in a Mathematica Notebook work for Wolfram.

Nonetheless, I think that it's already possible to be pretty efficient using Mathematica's keyboard shortcuts. In particular you can use SHIFT+CTRL+D to divide (hence the D) cells once you have the cursor where you want to split them. If you want to "explode" the function, you can (with some practice) use this shortcut and arrow keys to break things apart pretty quickly. There's not really a way to automate the part about "[setting] up the arguments and variables and [seeding] them with appropriate test values," since Mathematica won't know a priori what sorts of test values are legitimate.

Combining the working cells is already fairly straightforward in the notebook. You can quickly SHIFT + CLICK the cells you want to combine and then the shortcut SHIFT+CTRL+M will merge (hence the M) them for you. Again, you'll have to put the test values back into the argument form to finish.

Useful reference: How do I extract the contents of a selected cell as plain text?

The following code creates two buttons, and docks them at the top of the current notebook.

The first button takes the contents of the clipboard, temporarily pastes it at the end of the evaluation notebook, and then replaces that single cell with a set of cells, one per line of the pasted text (lines are split at each ";").

The second button removes the split lines, and any output generated from them, based on the assigned cell tag of "SplitCode".

Still needs a button to re-assemble the code.

buttonA = Button["Split Clipboard", Module[{nb, data, text, lines},
nb = EvaluationNotebook[];
SelectionMove[nb, After, Notebook];
Paste[];
SelectionMove[nb, Previous, Cell];
data =
FrontEndExecute[
FrontEndExportPacket[NotebookSelection[nb], "InputText"]];
text = First[data];
NotebookDelete[];
lines = StringSplit[text, ";"];
SelectionMove[nb, After, Notebook];
Scan[NotebookWrite[nb,
Cell[#, "Input", CellTags -> {"SplitCode"},
Background -> LightOrange]] &, lines];
]];

buttonB =
Button["Remove Split", (NotebookLocate["SplitCode"];
NotebookDelete[])];

grid = Grid[{{buttonA, buttonB}},
Background -> LightOrange,
Editable -> False,
Frame -> All];
cell = Cell[BoxData@ToBoxes@grid, CellTags -> {"ButtonCell"}];
SetOptions[EvaluationNotebook[], DockedCells -> {cell}];
`