Functional Programming Examples
IMPORTANT NOTE: before getting started on programming the calculator, please have a look at the Important Programming Notes section.
The following examples are intended to show how to write functional programs for the calculator. It starts with the most basic example, then progressively demonstrates more advanced functionality.
Note that each example includes the commands needed to enter the example on the calculator and a link which will load the example into the calculator. Also, any example may be saved into the calculator for later use using SaveFunction under the Mem menu.
Basic example: Quadratic formula
The following example shows how to write a simple function with variables; in this case, the quadratic formula. These are the commands to create the example and to execute it:
b Negation b Square 4 a * c * - Sqrt PlusMinus 2 a * / QuadForm Label
2 5 -12 QuadForm
Note that instead of typing the command "Negation", you can use ctrl-minus hot-key to do the same thing. Also, all of the commands may be entered using the UI buttons instead of being typed, so you don't actually have to memorize a bunch of commands, it's just easier for example purposes to present them that way. If you happen to prefer to use the keyboard as much as possible there is command completion so you don't have to exactly memorize each command.
This is what the result will look like in the calculator:
Notes:
- In the simple case, a function "program" is just a calculation with variables to be filled in when the function executes.
- Once you give the function a label, it can be executed by typing in the label name.
- When the function is executed, it will fill in the undefined variables from the stack alphabetically in left to right order.
In many cases this simple use model will be all you need, but more advanced functions are also possible:
Function block example: Equation of a line given two points
There is no special command to designate a function block, it is primarily a term referencing a set of calculations inside a list that work together. A function block generally includes most or all of the following optional features:
- In statement
- Specifies the variable(s) that will be the inputs for the function block, and the order that those inputs will be taken off the stack when the function block is executed. Until the function block is executed, any variables from the In statement that are used in calculations are set to Undefined. The In command can include a single variable or a list of variables, depending on number of inputs needed.
- Labeled calculations
- Labels inside a list are only visible to other calculations in the list. See the help page Names, labels and functions for more information on how labels work.
- Out statement
- If there are any Out statements, then only the results from these statements will show up as a result for the function block. If there is more than one Out statement, then the function block will output a list of results, one for each Out statement. If there is no Out statement, the result for the function block will be one result for each entry in the list, which is default list functionality.
If this seems a bit complicated, keep in mind this is pretty much all you need to know to write a simple functional program that has multiple lines but no looping, so put in that context it's pretty simple.
The following is a simple but useful example of a functional block which finds the equation of a line given two points. Here is what the example looks like when it is entered on the calculator and executed for a test case:
The commands for entering the example are as follows:
{ ( x1 y1 x2 y2 ) In
y2 y1 - x2 x1 - / slope Label
y1 slope x1 * - intercept Label
"y = " slope + "x + " + intercept + Out }
EqLine Label
2 3 4 2 EqLine
Explanation of example
The following statements are all part of the list that makes up the functional block EqLine:
- In
- In this case the In statement indicates that there will be 4 inputs specifying the x and y coordinates of two points. When the function block is executed, the points will be pulled off the stack from left to right in the order indicated.
- slope and intercept
- There are two labeled calculations for the slope and intercept of the line. Note that the intercept calculation makes use of the result from the prior slope calculation.
- Out
- This is the only entry in the function block that will return an external result when the block is executed. Note that it uses results from the slope and intercept calculations to create an output, which in this case is a string formatted to look like the slope-intercept form of the line that passes through the input points.
- y = Undefinedx + Undefined
- This is the output for the function block, which sits under the block in the results area. Since the block hasn't been executed yet, the In variables are all undefined which results in the function block output containing Undefined values.
Execution of EqLine
After the function block is defined and given a label, it is executed. To execute the new function, four inputs are placed on the stack and the new EqLine command is entered. Note that while the function definition was complex, execution was simple and compact.
Advanced example using Fref and recursion: Finding a root using bisection method
The examples so far have the potential to save a lot of repetitive calculation if you were planning to do the same calculation multiple different times with different inputs. The next example function does a lot of work for a single calculation, performing multiple loops to get one result.
Description of Bisection Method
The bisection method is a simple and robust method for finding a root of a function. It's not especially fast, but since the calculator will do all the work simple and robust is preferable. Basically, the method works by taking two points that straddle the root (one input must return a positive result from the function, the other a negative result) and splitting the difference until the answer is within a given tolerance. There is a Wikipedia article at this link which gives more details.
When entered into the calculator and executed, the FindRoot function looks like this:
The commands for entering the FindRoot function and executing a simple example are as follows:
{ ( f a b tolerance ) In
a b + 2 / c Label
( c ) f fref fofc Label
fofc ( a ) f fref * 0 > c a ? newa Label
fofc ( b ) f fref * 0 > c b ? newb Label
fofc 0 == c a - Abs tolerance < Or end Label
end c ( f newa newb tolerance ) FindRoot fref ? Out
} FindRoot Label
2 x Square - 1 2 0.001 FindRoot
Explanation of example
The following statements make up the FindRoot functional block:
- In
-
The In statement indicates the following inputs:
- f - the function for which to find the root.
- a, b - the two bracketing estimates for the root. One must return a positive value when entered in the function, the other must return a negative value (order not important).
- tolerance - How close the final estimate must be to the actual root.
- c
- The average of the two bracketing values.
- newa, newb
- The new brackets for the root. C will replace whichever one of the original bracket values has the same sign.
- end
- This value will be true (value of 1) if f(c) == 0 or if c is within the tolerance limit of the bracketing values. Basically, this is a test to see if we've found our root estimate or not.
- Out
- If the end condition is true, the Out statement returns the c value. If the end condition is not true, the Out statement will return a recursion of the FindRoot function with the newa and newb values. The function will recurse over and over again until either the end condition is met or the maximum number of recursions is reached (this is a built in limit to prevent the calculator from crashing from running out of memory).
- FindRoot(...)
- This is a test of the function. As you can see it returns a value reasonably close to the actual root, which is the square root of two (1.4142)
Notes:
- Looping in the calculator is generally done using recursion (a function calling itself, usually using a function reference - fref). A recursive call must always be placed inside of a Conditional statement to avoid an endless loop, which will time out when the maximum number of fref calls for one calculation is reached.
Further Programming Examples
A list of further programming examples may be found here