Functions are the key to any program! Within the Translator, they become even more important because of how Iguana’s annotation blocks track their usage.
For purposes of readability, every significant code block should be set up as a function. This technique has several advantages:
- It makes the main function easier to read
- It makes tracking logic paths within the annotation blocks much easier
- It is easier to maintain
- It is easier to modify
- It imakes production message management much easier
When choosing function names, follow the same rules as when naming variables:
- Names should express what the function will do (intuitive)
- Names should maximize auto-completion by using meaningful prefixes
- Function names should be longer than variable names
Stringing a long number of parameters into a function call will restrict the amount of space available to the annotation block. This negatively impacts readability. To address this, when passing more than three or four parameters, it may be useful to use a table construct: simply place the values into a Lua table and pass the table. This also make future maintenance easier!
Creating Custom Help
Anytime you create user-facing functions, you should define custom help functions for them. For an example of how this works, check out the sample provided in our Module section.
Functions fall into two categories: calculation or processing:
- Calculation functions are functions that perform logical calculations on input parameters, then return a/some value(s) that it computes. Examples are
removeCR(). Normally, calculating functions return only a single or small number of values. These are pretty well understood and are fairly good at self-documenting, as long as the naming is intuitive and useful.
- Processing functions (or workflow functions) manage programmatically built tasks or workflows. Examples are
emr.createBilling. These tend to be more complex. They also tend to fail! When using these functions, we strongly suggest that you perform the following:
- Report the activity and status as a string in the return statement rather than a simple ‘OK’ (i.e. return blah, blah, blah, ‘Billing invoice submitted’)
- Report the activity and status as a
iguana.logdebugentry that can be turned on if there are problems
Scripts often include loops or conditional statements. In both cases, the repeating or conditional logic should surround the function and not the other way around:
for k,v in impairs(patientTable) do validateValue(v) end function validateValue(x) if x == nil then error ‘Null value found’ end end -- function
The above example is obviously more readable and more expandable than the following:
validateValue(patientTable) function validateValue(t) for k,v in impairs(t) do if v == nil then error ‘Null value found’ end end -- for end-- function
Performance vs. Readability
In long loops, we recommend that you assign a function to a local variable (as the local function will run about 30% faster):
-- Global function for i= 1, 1000000 do local x = math.sin(i) end -- Local Function use local sin = math.sin for i= 1, 1000000 do local x = sin(i) end
In this case, we sacrifice a bit of readability in favour of performance. This should be a case-by-case decision.