S T R U C T O R I Z E R - User Guide
Diagram > Outsourcing

Outsourcing of elements to a subroutine

Since release 3.27 you may select a subset of your diagram and automatically outsource it to a new subroutine just in a flash!

Imagine the following example of a statistical calculation. It starts with the manual input of some numerical values, then computes their average and finally derives the standard deviation.

You may want to decompose this algorithm. Let's start with the standard deviation. Select all elements involved in this part of the computation:

Outsourcing demo - the original program

To convert the selected part in a subroutine you may:

  • select menu item "Diagram => Outsourcing icon Outsource",
  • select context menu item "Outsourcing icon Outsource", or
  • enter <Ctrl><F11>.

Outsourcing demo - menu item Outsource

You will simply be prompted for a routine name:

Outsourcing demo - the name prompter

That's all what you have to do (most times, at least)! Structorizer will automatically analyze what arguments the routine needs and whether it is to return a value, then it will move the elements to the new routine created with this signature and also push the routine diagram to the Arranger:

Outsourcing demo - the created subroutine for standard deviation

In the original diagram the selected elements will have been replaced with the respective routine call. The call is automatically selected (and hence highlighted). Note that the result is immediately ready for execution!

Outsourcing demo - the odified main algorithm

Looks nice? Well, but what about diagram regions that produce more than a single value, which other parts of the algorithm rely on? Let's try with the input part next - it introduces both the count variable and the readings array, which are both used by subsequent code:

Outsourcing demo - outsourcing the input sequence

Since there hadn't been record (struct) types in Structorizer when this feature was implemented, the converter makes use of the ability to fill arrays ad-hoc with values of different types (which is still simpler than a record since the latter needs a global type definition):

Outsourcing demo - routine with two results

And how is the call integrated in the main program? Let's have a look:

Outsourcing demo - call of a routine with several results

As you can see, an array variable with a generic name is introduced to receive the values from the routine, then the values are extracted one by one and put into the actual target variables. (This method may not look so nice but is very effective in Structorizer. We have to admit, of course, that it may cause trouble on code export to some strictly typed languages, where you would have to make use of record/struct types instead. A future release might use the record concept also introduced with release 3.27 here.)

Consequently, outsourcing the average calculation is just as easy as before:

Outsourcing demo - outsourcing the average calculation

So we get the third subroutine in a blink, too.

Outsourcing demo - the outsourced average calculation

The main program has shrunk a lot, this way:

Outsourcing demo - main statistics program after three outsourcings

It is not necessary to mention that the outsourcing can of course be undone in the main routine (and redone etc.). The undoing will not delete the created subroutines, of course. You may simply drop them if you want to get rid of them.

Of course this was only half the truth - there are cases where Structorizer may not cope with correctly identifying the needed parameters and result values. Then you will have to accomplish the result yourself. But we think that even in these cases the "Outsourcing" function will facilitate your job to decompose an algorithm grown too complex. Let's see an example in the following section.

Outsourcing with record types or includables involved

Consider the following algorithm, which simply derives a slightly modified date from a given date (without calendar corrections). Here a record type is involved, which the main program and the outsourced subroutine (from the selected elements) will have to share. You start the outsourcing as described above:

Outsourcing with record types

But Structorizer detects that the type Date defined in the main program must also be known to the subroutine diagram and thus decides that it must be tranferred to an includable diagram that both main and subroutine must include. Therefor you will asked for a name for that additional diagram:

Outsourcing - includable name query

After having commited the question, you will obtain two new diagrams, the includable and the subroutine:

Outsourcing with includable (Arranger view)

The main program will have changed as follows:

Defective main after outsourcing with record variable

As you can see in the Analyser report list, the result isn't quite correct. A record variable cannot simply be introdced by assignment (unless the assigned value is a record initializer). So we must re-introduce a declaration like the one moved to the subroutine (where it is also necessary, so it wouldn't have helped just not to select the declaration before outsourcing - in that case the subroutine would have been detective instead). For the current version of Structorizer an automatic solution of this situation is still slightly too complex.

Main progam after outsourcing and manual correction

By the way: If the record type had already been included by the main routine (instead of having been defined locally) before outsourcing, however, then the subroutine would have inherited that include item automatically without asking.

Counter-indications against outsourcing

There are algorithm subsets, however, which cannot easily be outsourced. Not surprisingly, they are usually provoked by unstructured diagram elements like Jumps. If the selected region of the diagram contains Jump elements, which intend to direct the control flow to targets outside the selection then we get in deep trouble. Look at the following nonsense example. It contains a CASE selection with several kinds of outbreaking elements -  exiting the inner loop, the outer loop, the entire application, or the current routine or program, respectively:

Outsourcing demo - diagram with compromising jumps

If we liked to outsource the selected elements then three of the Jumps point outwards the subset, only the empty Jump (equivalent to leave) has a target inside the selection: the input instruction beneath the FOR loop. The exit command is not a problem, either - its semantics is independent of its location, it will always abort the entire execution. With the 2-level leave it's different: its target is the Repeat loop, which will be outside the routine and hence unreachable, the leave 2 instruction is going to be illegal therefore. The return instruction, on the other hand, will change its semantics drastically: Instead of ending the outer program it would now just leave the subroutine, this way compromising the program logic. (And there is no easy way to maintain or restore the original logic.)

Structorizer tries to detect such cases and vividly warn off outsourcing element sets of that kind:

Outsourcing demo - warning on problematic Jumps

If you really know what you do and you have an idea how to mend the defects provoked by the outsourcing then you may go on, otherwise you better back off.