↑ to Frrr103 Menu  ↑ to Main Menu

Frrraction 104 — Advanced functions

 ↑ to Frrr104 Menu

CF — Program Functions

In the immediately prior course of FrrractionHighSchool, CF — Classic Fractions, we mentioned that a typical Complex Function looks like

{{ blah this blah that etc }}

That's the topic of the present course.

The actual blah-this-and-that Program-Function keywords include most of the normal button-tapping business of Frrraction. Including one or more of the keywords within a CF function Bracket {{...}} (separated by whitespace) has this effect: When you exit the hNoteEditor and later "execute the function" by yTapping the EXEC key, the bracket is scanned from left to right, top to bottom; as keywords are encountered, Frrraction does exactly what it would do if you had tapped the named keys.
CF Program Function keyword descriptions
F1num F1den F1int
F2num F2den F2int
make the named fraction cell become active
make the named fraction—specifically, the cellmate of the present cell—become active
clear the active fraction cell to zero
backspace-delete digits from the active fraction cell
1 2 3 4 5 6 7 8 9
like tapping the named digit key,
even if preceded by Y RCL or Y STO
· (period)
like tapping · (the dot key);
add sub mul div
these act like tapping the math op keys
You can use + – * / if you prefer.
Unfortunately, Apple omitted ÷ from the iThing keyboard, so / must serve for div.
this acts like tapping the yellow key, and must precede each yellow function
these represent the yellowFunctions shared by the digit keys.
these represent the yellowFunctions shared by the math-op keys
A CF program loop is an @-group: A group of brackets each with a prefix-@, and the last one also has an inside-@.
SkipWhen fCell EQ0 If the named fraction cell Fcell meets the specified condition— also with EQ replaced vt any of LT LE EQ GE or GT or 0 replaced by 1—then the following CFunction bracket will not be executed.
SkipN 7
causes the following 7 (if there are that many) enabled CF brackets to be skipped during EXECution—usually with 7 replaced by another positive integer.
SkipTo .x
scans hNote from the present CF, searching for a CF that begins like <{{ .x and de-enabling any and all enabled CFs that it encounters along the way. It then resumes executing with the located CF. In the target CF, the singlespace after {{ followed immediately the dot followed immediately by x are specifically mandatory, but x can be replaced by any single lowercase or uppercase alphabetic character.
If the present CF is in a subroutine named s then the target CF must reside later in the same subroutine, and the target must begin like {{s .x.
It is permissible for the present CF and/or the target CF to be within @-loops.
these are INTENTIONALLY OMITTED from the CF-function lexicon

I tend to type the keywords in mixed upper/lowercase (illustrated in the table) for readability, but CF ignores case so you can use all lowercase or all uppercase or mix it up however you like (also illustrated in the table).

 ↑ to Frrr104 Menu

CF — The no-pause suffix

CFunctions, like all such "keystroke macros", are fairly easy to write but they tend to be hard to read by others—or even later while trying to debug them, by the person who wrote them in the first place. To help get around this drawback, Frrraction's CFunction facility allows {{...}} brackets to be broken into smaller brackets, with explanatory comments in between. For example:

The bracket

overall explanation
<{{ A B C D E F }}
concluding comments

can be broken into as many as six brackets—e.g. three:

introductory explanation
<{{ A B }}> Note the no-Pause symbols >
intermediate explanation of AB or CDE
<{{ C D E }}>
intermediate clarification of CDE, intro to F
<{{ F }}
concluding comments

Without the "no-pause" symbols, each smaller bracket needs a separate tap of EXEC--a nuisance if the only reason they're separate is for that explanatory purpose. This drawback can be eliminated, as shown above, by replacing the closing braces }} of each-but-the-last intermediate bracket by }}>. Appending the "noPause" symbol to a CFbracket causes execution at runtime to proceed directly to the next enabled bracket without waiting for a tap of EXEC.

There are two opt-outs from this run-without-pause execution:
  1. Execution of the bracket-sequence stops at the end of a bracket that places some output into the hNote itself
  2. At the end of an @-Loop, execution pauses to wait for the user to tap EXEC (see below)
The first exception is to allow users to view the output before tapping EXEC to proceed; such output might affect her decision to proceed. The second is to prevent what would otherwise be a high-speed infinite loop that could only be stopped by shutting down Frrraction.

 ↑ to Frrr104 Menu

CF — @-Loops


Setup for the following @-Loop examples is: The active fraction — F2 in our example — contains 100,001/1. The CFunction-Op named Factor finds the smallest prime factor of Fnum greater than or equal to Fden and shows the result in Fden.

@-Loop Example 1

@<{{ Factor @}}

With setup as described above, the first EXEC-tap changes F1 to 100,001/11, 11 being the smallest prime factor of 100,001. Notice that the CFunction is still enabled (because its inner-@ was acted upon right after CF:Factor was run). Tapping EXEC again just repeats the result since the smallest prime factor of 100,001 greater than or equal to 11 is of course 11.

To advance the factoring we need to cancel 11 from the F1 stack. Frraction's "reduce" RDC function can do that: Tapping GCD twice runs RDC and yields F1 = 9,091/1. Actually, the GCD key cycles greenly between GCD and RDC so, to run RDC from the keystrip, you ytap GCD which computes the greatest common divisor of the active Fnum and Fden, displays it in hShow, and changes the key-label from yellow GCD to green RDC; tapping RDC then cancels the gcd from the active fraction stack and reverts the key label to green GCD (because that's the way green-cycles work) Tapping anything else turns the key back to yellow GCD.

Now EXEC produces F1 = 9,091/9,091 since 9,091 is prime. GCD-then-RDC yields F1 = 1/1 and the factoring task is obviously completed: 11 and 9,091 are the prime factors of 100,001.

Let's automate that process a bit more. Notice in Example 2 below that I put the inner-@ into the second CFunction not the first one, to make the @-Loop contain both brackets.

@-Loop Example 2

@<{{ Factor }}
@<{{ Y RDC @}}

The first EXEC in Example 2 runs CF:Factor and yields F1 = 100,001/11; notice also that the first CFunction is no longer enabled. The next EXEC thus runs the still-enabled second CFunction in the program, and yields F1 = 9,091/1 (because it canceled the common factors from F2n and F2d); and now both CFunctions are again enabled. The next EXEC yields F1 = 9,091/9,091; and the next yields F1 = 1/1.

In Example 3 it should only take one tap of CF for each prime factor. See why? It's because I used a nopause-code > suffix on the first CFunction.

@-Loop Example 3

@<{{ Factor }}>
@<{{ yRDC @}}

Oops. It worked, but it blots out any trace of the prime factors it finds. The best ways to remedy that use the advanced "hp" program facility which is described later in this User Guide. Example 3 shows a workaround that doesn't need hp:

@-Loop Example 4

@<{{ Factor }}>
@<{{ Y DUP}}> acts while factor is still in F1d
@<{{ Y RDC @}} changes only F1
New factor is still in F2d after each EXEC

If you want to see all the prime factors after you've EXEC's eough time to find them all then hp is really the solution:

@-Loop Example 5

@<{{ Factor }}>
As in Example 4, this acts while factor is still in F1d
@<{{ hp( print/- , d-/ hShow RetainHShow ) }}> @<{{ Y RDC @}} changes only F1
New factor is still in F2d after each EXEC

With Example 5 it now just takes one EXEC per prime factor and we can see it and all the previous factors after each EXEC. Try it starting with F1 = 5,008,081/1. Six EXEC-taps leaves hShow looking like this:

@-e.g.5 hShow starting with F1=5,008,081/1

13 17 17 31 43 1

We can improve the program so that a single EXEC-tap to find all the factors of any integer, by using the Dot-CFunction idea described below.

 ↑ to Frrr104 Menu

CF — @-Dot-CFunctions


This will be our next-to-last improvement to the above loop example:

@-Loop Example 6 start with 5,008,081/1 in F1

•<{{ hp( 6 sto 0 ) }}> Run @-loop six times
@<{{ Factor }}>
As in Example 4, this acts while factor is still in F1d
@<{{ hp( print/- , d-/ hShow RetainHShow ) }}> @<{{ Y RDC @}} changes only F1
Generates all six factors with a single EXEC.

The final improvement factors any integer up to nMAX (Yes, not just up to pMax):

@-Loop Example 7 start with any/1 in F1

•<{{ hp( 32 sto 0 ) }}> Run @-loop up to 32 times
@<{{ factor }}>
@<{{ hp( print/- , <\f1>d-/ hShow RetainHShow ) }}> @<{{ SkipWhen <\s>0 EQ1 }}
@<{{ yRDC @ }} @<{{ hp( 0 sto 0 ) @}}

CFbrackets generally depend upon space-characters to isolate the keywords so EXEC can recognize them individually, but it makes two exceptions: one for yellowKey, the other for @.

The exception for a loop-closing inner-@ is that "@}}" is as good as "@   }}". EXEC needs no whitespace between '@' and the closing bracket '}}'.

The yellowkey exception is like this:

yAPRX YGCD yGCD ygcd etc.

Example: {{ F2 Y ONE F1 Y RCL 5 + Y STO 5 }}

just as good: {{ f2 yONE f1 yRCL 5 + ySTO 5 }}

If you edit either of these into the current hNote, then tap MAIN to exit the editor then tap EXEC, then... oops. We expected fraction F1 and register R5 to both end up containing a number 1 larger than the original contents of register R5, but nothing happened!

 ↑ to Frrr104 Menu

CF — CF Enablers

Key idea

tutorialicon Try it.
Use the editor to change the above example to give it two enablers, so it looks like this:

<<{{ f2 yONE f1 yRCL 5 + ySTO 5 }}

The CFunction (assuming it's the enabled bracket closest to the top of hNote) can then be executed twice before becoming dormant. You can confirm the operation: Put - 21/33 into fraction F1 then do Y STO 5 to put it into register R5 as a test value; run CF twice; then activate fraction F2 and tap the key-sequence Y RCL 5. At that point, F2 will also contain the same value as F1: 15/11.
If you'd like a CF to execute every time you tap EXEC, without having to go into PROGview to add more enablers whenever it runs out of them, use the @-loop facility like this:
@<{{ f2 yONE f1 yRCL 5 + ySTO 5 @ }}

Now the bracket will run every time you tap EXEC.

If you'd like automatic one-time initialization to be done by the first EXEC-tap, with subsequent EXEC-taps running the @-loop, you can add something like this before the @-loop in the hNote:

<{{ yPURE f2num clr 2 1 yCHS f2den clr 3 3 ySTO 5 }}>

With that as the first CFbracket in hNote, the initialization will run the first time you EXEC; that will consume its single <enabler so, on subsequent EXECs, only the @-loop will run, its single <enabler being replenished each time by its inner-@. This will repeat as often as you tap EXEC.

 ↑ to Frrr104 Menu

CF —Green-W mode

Key idea

You can have any number of CF functions in an hNote, some dormant, some enabled, some in @-loop-groups. At any given moment some members of @-loop-group may have <enablers, others not—although the unenabled ones will be re-enabled the next time the inside-@ command within the last cf bracket of the @-group is executed.

Each time you run CF, Frrraction scans the hNote from top towards bottom, and performs the first enabled CF function it finds—it doesn't matter whether it happens to be an @<{{ bracket or just a normal <{{ bracket. Each time CF finishes running a function bracket, it strips off one of that function's enablers. When its last enabler is gone, the function falls dormant and the next enabled function will be executed next time you yTap CF.

The hNoteEditor's Up- navigation key and Down- navigation key navigator buttons try to position the insertion cursor at the enabler-positions of the various CF functions—that's what the squigglies at the bottom of the keys are meant to remind you—so enablers can be easily replenished.

Follow this link for an actual useful example of a CFunction. It automates the Newton method for calculating approximate square roots in exact fractions!!

 ↑ to Frrr104 Menu

hp( — a major CF extension

Some CF Program functions aren't available on Frrraction's keyboard due to lack of space. One of the best of the missing functions is hp(. 'hp' stands for either "high precision" — or "high performance", because it provides much more than just precision.

The precision it provides is 38-decimal-place floatingPoint within Frrraction applets, and 64-bit integer-and-floatingPoint decimal arithmetic for those times when Frrraction's 32-bit integers need some help. The high performance it provides is exceedingly flexible utilization of the resources that iThings make available to Frrraction.

A typical reason to appreciate hp( arises when you compute a high accuracy square root of a fraction. To confirm the result you'd like to multiply the result by itself—doing something like Y DUP ×. But, if the numerator or denominator of the putative result exceeds 46,340 (the integer square root of pMAX) the multiplication will cause overflow. Here's where hp( can come to the rescue, because multiplication of two 32-bit numbers cannot overflow in 64-bit arithmetic.

Among its other resources, hp( gives separate access to each of Frrraction's fCells, individually and in combination, allowing manipulation beyond conventional fraction paradigms. An easy example: Want to give F2's stack a non-unit gcd, to exercise the yellow GCD key? Use hp( to multiply each of F2num and F2den by the desired common divisor. For example, if F2=2+4/5 you can easily convert it that way into 2+12/15. As with many other hp( operations there's no other convenient way to do it; putting 0+3/3 into F1 and multiplying, for instance, does not have the intended effect.

Hp also gives you control over all of Frrraction's "hCells". Each of the fCells has a corresponding hCell beside it. They only contain text, and they're used mainly as meaningful labels for the fCells — They hold the labels F1n:, :F1i, F1d:, etc. that you've seen since your first view of Frrraction.

Other hCells are the "top labels", h1t for numberField F1, h2t for numberfield F2, and h3t for the overall Frrraction screen.

The most important of the hCells are hInfo (also known as hPeek or as h0t) and hShow. These two are not simple short 1-line labels. Like hNote, they contain nearly unlimited amounts of text. Unlike hNote, they don't permit direct-via-the-keyboard editing, but they do accomodate a variety of user-controlled text-placement options.

Display-access to all those hCells is via its Print/- instruction. The text to be displayed is contained as the text enclosed within /- text -/ (the opening quote "/-" is built into the Print/- instruction itself, and the destination cell is named immediately following the closing "-/" quote.) More later, about the text placement options.

Another @-loop example, to help clarify order of execution of CF brackets when multiple CF program-brackets are in the same hNote:

123 @-Loop Demo

<{{ F1num clr 1 2 3 hp( 0 sto 1
) }}

@{{ hp( rcl 1 1 + dupx sto 1
put f2num print/- second -/
f1num ) }}

@<{{ hp( rcl 1 1 + dupx sto 1
put f1num print/- first -/ f2num
) @ }}


tutorialicon Try it.
Put the above program into hNote (either type it in, or use iPhone's Copy/Paste to get it from the web into a fresh hNote) and Return-to-Frrr.

Look at the program to determine what you think will happen when you run it. While YellowKey is in its temporary Green-W state (due to Return-to-Frrr), tap CF to see.

F1num contains 123, and the first of the three program brackets no longer has a <enabler. Clearly, that's the bracket that ran.

Which program bracket will run the next time you run CF? Test your analysis by running CF again (YellowKeyStatus is still Green-W, so just tap CF to do it).

F2num now contains 'first'. Q: Which function-bracket put that there? A: The third, with its 'print/- first -/ f2num' command.

Q: Why did the third bracket run before the second? A: For the same reason the first bracket didn't run again: They had no <enabler and the third one did.

Q: The third bracket only had one <enabler; why does it now still have an <enabler? A:It doesn't still have an <enabler; it has a new <enabler—and so does the second bracket—put there by the inside-@ command which executed when the third bracket ran.

What will happen if we tap CF again? Did you figure it out? Then try it.

We didn't tap Y first and F1num is the active Fcell, so you might expect F1num to now contain 7 or 1237. But it now contains 'second'. Only the second bracket with its 'print/- second -/ f1num' command could have done that. Q: Why did CF run instead of the digit 7 being put into F1num? A: Because the YellowState was Green-W, not White-W, and CF is one of the three special greenFunctions that don't need Y to be tapped when Green-W is up.

Q: Why did the second bracket run instead of the first? A: Because the first had no <enabler whereas the second's <enabler had been replenished as part of an @-loop. Note that the first bracket still has no <enabler and, since it ran, the second function-bracket again has no <enabler. So the third bracket is next-in-line to run.

From now on, as the members of the @-loop, the second and third brackets take turns running whenever you tap CF.

Q: Have you figured out the source of the increasing numbers that alternate with the words 'first' and 'second' in the Fnums? You've probably already noticed.

background icon Background Topic: RPN

"Reverse Polish Notation" is all about the order you name numbers and operations when writing arithmetic. The name sounds sophisticated and scary to some people at first, but in practice it's very nice to use. What most people normally use would sound scary too, if schools told you what it's called before telling you how to do it: "In-Fix Notation". See what I mean? There are three notations:

  • Pre-Fix Notation, e.g. – 7 4 or maybe Subtract(7,4)
  • In-Fix Notation (the standard), e.g. 7 – 4
  • Post-Fix Notation (reverse Polish), e.g. 7 4 –
All three of the example expressions define the same result: Subtracting 4 from 7 gives 3.

The great thing about RPN is how it eliminates calculation ambiguities that plague the other two notations, such as: What is the result of 7 – 4 * 2 using infix calculation? Is it –1 or is it 6?

In-fix processors resort to two artifices to resolve such ambiguities: the hard-to-remember notion of "operator binding precedence" in which *mul has higher precedence than –subtract. In the example, *mul is bound to the 4 more tightly than –subtract is bound to the 4, so 7 – 4 * 2 would be 7 – 8. This notion is augmented with user-provided parentheses to override the natural precedence (or overcome the ok-which-is-it confusion) when necessary. Sometimes the whole expression must be rearranged to contrive the result you want. Thus, presented with 7 – 4 * 3 the in-fix processor multiply 3 by 4, and that result would be subtracted from 7 to get –5. To get the other result you would need to override the natural operator precedence by using parentheses, viz. (7 – 4) * 3 would do 7 – 4 first, to get 3; then do 3 * 3 to get 9.

Does that In-Fix approach stll sound simple? I don't think so. We do it just because it's what we first got taught in school.

RPN handles the problem this way: It treats data (7,4,2) and operators (–,*) as a simple stream; data items get "pushed onto the stack" one by one as they're received (like dishes onto a steaming stack in a cafeteria); when the next operator comes along in the stream, it "pulls" the data it needs off the top of the stack, however many data items it needs (the common +,–,*, and / operators each needs two, CHS change-sign needs one, and so forth); combines the data as the operator's nature requires; and pushes the result onto the stack—to be treated as data by future operations when they come along in the stream.

So. To get In-Fix's 7 – (4 * 3) = –5 result, RPN could use
7 4 3 * –

The Stack
during 7 4 3 * –
X 0  7  4  3 12 -5 

To get (7 – 4) * 3 = 9, RPN could do
7 4 – 3 *
The Stack
during 7 4 – 3 *
X 0  7  4  3  3  9 

Note that RPN needs no parentheses or hard-to-interpret precedence rules. It's a simple first-come first-served cafeteria.

information icon Info Topic: hp(

hp( operates in hNotes within the standard {{...}} CF bracket in the format hp(...). That is, it has its own sub-bracket: The opening brace, an ordinary left parenthesis, is built right into the hp( keyword with no intervening space. The closing brace is an ordinary right parenthesis. Within that bracket, the keywords, all private to hp(, are presented in Reverse-Polish notation—which means that numeric operands are listed first, followed by the operations that need them.

For example, to subtract 3 from 22 you could edit the following into hNote:

<{{ hp( 22 3 − ) }}

Or, to subtract 3 from the denominator of fraction F1—a kind of thing that might be more useful while being awkward to do in Frrraction itself:

<{{ hp( get F1den 3 − put F1den ) }}

The sequence of stacks the first of these would produce is:
The Stack in Action
init after getafter 3after −after put

Assuming that the fraction cell F1den started out containing 22, the second CF bracket would produce the same sequence of stacks as the first.

Operation of the stack is automatic. The only times you need to think about it are when you want to get it to show you some intermediate results that would normally evaporate in the normal course of a computation. For such cases, here's how it works: Called a FILO stack (First-In, Last-Out) the stack owns private operations called "push" and "pull". When an operation produces a result, that value gets pushed onto the stack; a chain reaction pushes the older stack entries down by one position: discards the current contents of T (there being no place for it to go), Z moves down into T, Y moves down into Z, and the new value loads into the newly vacated X-position at the top. When an operation needs an operand value, it pulls it from the top of stack: this retrieves the X-value, lets the old Y float up to replace it, the old Z floats up to replace the old Y, the old T value floats up as the new Z and (what doesn't work with plates in the cafeteria) also leaves the old T in place as a copy. The DUPx and XCHxy operations give a modicum of control over the stack contents, and the hp( operation whose keyword is '=' prints the current contents of the stack in the hNote.

hp( Control
+ − * / ^
Integer operations
(Y op X → X) e.g.Y−X→X
X and Y get pulled off the stack,
integer parts extracted if decimal
(before doing the arithmetic),
64-bit integer result pushed onto stack,
becomes new X
(Y mod X → X) X and Y pulled off the stack,
keep remainder after Y÷X,
push remainder as new X
00+ 00− 00* 00/ 00^
Decimal operations ('00' prefix intended to remind of Frrraction's doubletap 0 gesture)
(Y op X → X) e.g.Y−X→X
X and Y get pulled off the stack,
converted to decimal if not already,
decimal result pushed on to become new X
X and Y pulled off the stack,
pushed back in reverse order
pull X,
reverse algebraic sign,
push back as new X
duplicate X,
push so Y becomes copy of X
up to 19 digits wide,
e.g. -3141592653589793238
get Fcell
retrieves 32-bit value from a Frrraction F1 or F2 cell,e,g, get F1num,
pushes 64-bit version onto stack as new X
put Fcell
pulls 64-bit X from stack,
attempts to deliver it to 32-bit Frrraction cell,
e.g.put F2den.
May cause hidden overflow in Frrraction
00put F1intD
pulls 64-bit X from stack,
converts it to decimal if not already,
delivers rounded-to-32-bit version to F1int,
F1int a.k.a. F1intD is the only Frrraction cell that can hold a decimal value.
sto i
pulls 64-bit X from stack,
stores it in hpRegister i
i between 0 and 9
rcl i
recalls 64-bit value from hpRegister i,
pushes it onto the stack
i between 0 and 9
00C c-function
pulls operands from the stack, runs the named math.h c-function, and pushes the result onto the stack in position X. For functions like modf whose second argument also returns a result, that second result is pushed into position Y.
=X or =Y or... =U
When the hp( scanner encounters the equal sign it halts processing of the bracket and displays a snapshot of the stack through the named depth X,Y,Z,T, or U
=>X ... =>U
Display snapshot of the stack (without disturbing the stack pointer) then continue processing
hp( delivers some information into the hNote; you can have it intersperse a few words of yours by putting
show/- a few words -/
inside the hp( ... ) bracket.
show Fcell
Frrraction cell contents can be displayed in the hNote as well, using
show <fcell>
where <fcell> is any of F1num, F1den, etc.
print/- ... -/ F or H cell
Labels can be put into Frrraction or Help cells, using
print/- label -/ <cell>
where <cell> is any of F1num or F1n, F1den or F1d, etc. or H1num or H1n, H1den or H1d, etc.
Intended primarily for Help cells, this trick should be used only sparingly with Fcells.
The Fcell operands for GET and PUT are:
F1num or F1n, F1den or F1d, F1int or F1i, F2num or F2n, F2den or F2d, F2int or F2i. The Hcell operands are the same with F replaced by H. Capital and small letters can be used interchangeably.
There should be nothing but whitespace between GET or PUT and its f- or h-cell operand — and nothing between the t and / of print/- or the w and / of show/-.
Within the /- text -/ of print/- and show/- any expressions of the form <s>n will be replaced in the display by the current contents of hpRegister Sn.
The contents of the ten 64-bit hpRegisters S0...S9 are preserved throughout the Frrraction session, across separate runs of CF, but the hpStack is reset to all 0's with each hp( command.
hpRegister S0 is treated as a count-down-and-stop control for @-loops. If S0 contains its default 0, an @-loop runs only once. Otherwise the @-loop system subtracts 1 from it after each trip around the loop and terminates when the result is 0.
Just like the {{...}}-keywords, the hp(...)-keywords are insensitive to upper/lower case — except in the case of 00c's math.h c-functions, which must be entered exactly as shown, for example, in: Appendix of Frrraction circa 9960.

 ↑ to Frrr104 Menu  ↑ to Main Menu

Frrraction is a product of GRS Enterprises, NLC,
a Michigan company since 1978
Most recent update of this guide: February 14, 2019, 1639 GMT
Copyright © GRS Enterprises, NLC, 2010-2019
Not void, even where prohibited. Your mileage may vary.