Scripting in Partial Recall

Taking a couple of sample scripts, you will learn about scripting feature in Partial Recall as well as its limitation compared with other programing tools.

You can write your own function in a Recall note, using NewtonScript, and call it from another Recall note by a single gesture. When you make a Recall gesture, you can pass one or more parameters to the function, by striking through them along with the function name.

Parital Recall intends to provide user an option to implement user specific calculation, search method, or data manipulation. It is not to give an environment to write application, which is much more complicated task for non-programmer.

Unlike Newton Tool Kit or any other programming tools, Partial Recall does not offer any framework, macro, pre-processor or those kind of things. There is no graphical user interface builder either. However, this does not mean that you are heavily restricted writing NewtonScript program. With a little practice, you may create a view which offers user interface like other application. You will see a sample which shows the possibility.

For basic structure of NewtonScript, please refer to "NewtonScript Reference". And for detail about NewtonScript programming language along with reference of system services, see "Newton Programmer's Guide". Both documents are provided Apple Computer, Inc.


Passing Parameters

You can write a function so that it takes parameters from user and manipulate them. When you call a function from a Recall note, you write the function name followed by one or more parameters. For example:

When you strike through "sum" to "789", Partial Recall calls a function named "sum" with a series of parameters (123, 456, and 789).

NOTE: When you call a function, you have to give at least one parameter, whether the function takes it or not. If no parameter is given, Partial Recall would assume that you intend to do usual Recall action, and pull the function script into the current note.

Your function receives the parameters through a variable named "args", which is an array of strings. Each string in args corresponds to each parameters you pass. In the above example, the args in the function sum shows:

Now, the sum function might be written like this:

NOTE: All parameters are passed in string format. If you need to manipulate them differently, you have to convert them properly. In the above example, we use StringToNumber() global function to convert a string representing a number to a real number.


Return Value

When execution of a function reached to the end, a value of the last expression in the script is returned as a result of Recall action. You may return a value explicitly in a return statement.

The return value is converted to a string before it is actually put back into the note. Numbers, strings, characters, and symbols are converted to their natural form, but the other data types like frames, arrays, and booleans are converted to an empty string.

NOTE: In case a function returns nil, Partial Recall will leave the original text, and put anything in the note.

If you want to return an array or frame of values, you need to flatten them into a string at the end of function. The following example collects the name and size of the installed packages, and then stuffs elements in the result array into a string.

Let's name the script "package" and try Recall the following line:


Limitation and Workaround

Creating Views

As mentioned earlier, there is no graphical user interface builder provided in Parital Recall. So, it is not easy to write a function which shows a view on the screen. However with a little practice, you can write such a script. Here is a sample script which creates a simple sticky note view:

In this example, we have to specify literal values for viewJustify, viewFlags, viewFormat, and viewClass. Because Partial Recal does not offer pre-defined constants that are used to specify those values. The viewClass 81, for example, represents clParagraphView. For more about those slots and the constant values, please refer to "Newton Programmer's Guide".

The main view is based on protoFloatNGo proto, which is represented by a value @180. This is a special expression to refer to prototype frames or other objects in Newton OS. You can find those values in "Newton 2.0 Defs" file which comes with Newton Toolkit.

DeclareChild() is a special function that Partial Recall provides for you. It helps you structure a view with children views. If you create a child view which belongs to another view, you must call this function to declare the relationship:

The above example does not take any parameter, but you still need to give one when you call. If you name the function "sticky", you can call it like this way:

Structured Programming

Although Partial Recall scripting function is not designed for building a large structured program, you may still need to write shared scripts or subroutines within your script. You can easily achieve this using NewtonScript's frame objects.

The next example shows how to create a frame that provides a set of functions that can be shared inside the script. The frame named accessNames has two functions namely person() and phone(). Person() takes an array of keywords, and finds a person record from Names soup. Phone() takes a person record, and returns the phone number. When you call this script along with a person's name, it returns his/her phone number.

Here is another example, which shows more complicated frame model. The calculator frame object owns a stack and its accessor methods push(), pop(), and next(). The calculator works like a stack machine, taking an expression in postfix notation (for example, the postfix notation for an expression "1 * 2 + 3" is "1 2 * 3 +"). Each element or token of an expression is passed through next() function. When a calculation complete, you can find the result on the top of the stack.

Assuming you name the function "calc", you can call it like:

The fuction would give you 2536.13333333333 as a result of the expression (12 + 34) * (56 - 78 / 90).

NOTE: There is no error handler implemented in the example. For use in real world, you must be careful about checking data types in every places.

Few Words About Inheritance

As you noticed in the last example, there is another frame operators embeded in calculator frame. This frame defines a set of functions for each operator (+, -, *, and /). When the next() function encounters an operator, it sets the function object to lookup slot. In this way, each operator function can inherit the stack accessor methods.

You may come out a smarter way to propagate frame values to another using the NewtonScript inheritance mechanism. For more information about frame and inheritance, please refer to "NewtonScript Reference".