This page uses CSS, and renders properly in the latest versions of Microsoft Internet Explorer and Mozilla.
This is Frontier: The Definitive Guide by Matt Neuburg, unabridged and unaltered from the January 1998 printing.
It deals with the freeware Frontier 4.2.3; for commercial Frontier 8, look here, and for the inexpensive Radio UserLand, look here. See my Web site for information.
Those wishing an offline or printed copy may purchase the book, which is still in print.
Copyright 1998 O'Reilly & Associates, Inc. ALL RIGHTS RESERVED. Reprinted with permission.
TOP UP: Data Manipulation NEXT: Interface

23

Extending
the Language

Despite the many virtues of UserTalk, situations arise where its speed and functionality are deemed insufficient, and one wishes to extend the language at the level of compiled code. If the compiled code is in the right format, UserTalk can call it. The UserTalk script which calls the code, known as "glue," can itself be called like an ordinary UserTalk verb. Thus, the UserTalk programmer doesn't need to be at all conscious of the fact that a verb is implemented in this way.

The compiled code can be in one of three formats:

Use of OSAXen from UserTalk is discussed in Chapter 33, AppleScript ; this book says nothing about how to write an OSAX. The rest of this chapter is about XCMDs and UCMDs; further technical details on how to write these are provided in Chapter 43, XCMDs and UCMDs.

To be called from UserTalk, an XCMD or UCMD must be living in the database as a binary. The standard location for these extensions is system.extensions ; there is a search path to this table. For example, the trigCmd verbs discussed under Chapter 15, Math, are implemented by calling a UCMD at system.extensions.trigCmd.code. To see an XCMD in action, call listSelect.example(); it works by calling an XCMD at system.extensions.listSelect.code.

Examination of a glue script such as trigCmd.sqrt() shows that the UCMD is called by way of a rather nasty-looking UserTalk verb, appleEvent(). The idea of the glue script is to shield the user from this sort of thing. Calling trigCmd.sqrt() is easy; calling appleEvent() is not, so trigCmd.sqrt() does it for you. XCMDs and UCMDs are often accompanied by a ReadMe wptext that explains how to call the glue.

Why XCMDs and UCMDs Exist

There are two questions to be answered. First, why do XCMDs and UCMDs exist at all? One reason is so as to be able to perform functions that are impossible through UserTalk alone. This is true of both trigCmd and listSelect.

Another reason is for speed. Some UCMDs started out as UserTalk scripts and were rewritten in compiled form just to make them faster. The speed increase is roughly an order of magnitude. Even a UCMD, though, won't be as fast as code incorporated into the UserTalk kernel. This is doubtless because of the overhead involved in packaging and passing the information to and from the UCMD. For example, string.parseHTTPargs() was about ten times faster as a UCMD than it was as a script, but now is incorporated in the kernel and is around five times faster than that. However, it is not open to the user to modify the kernel, which is part of the Frontier application itself and can only be changed by UserLand - whereas any technically minded user can write an XCMD or UCMD, put it in the database, construct glue for it, and call it.

Second, why do both XCMDs and UCMDs exist? After all, a single way of extending UserTalk ought to suffice. The reason is largely historical: the XCMD format was well established when Frontier first appeared; UCMDs were developed later to take advantage of Apple event architecture. XCMD support has not been abandoned, largely because, owing to the long history of HyperCard, there are so many XCMDs in existence.2 Thus the user can leverage a large existing base of code.

Also, it is easy to import an XCMD into the database, and to write glue code for it; so if you need to extend UserTalk and you know of an XCMD that does what you want, you can, in most cases, make that functionality available to UserTalk without doing any coding. XCMDs are also faster and smaller than UCMDs. On the other hand, not every existing XCMD can be successfully called by UserTalk (only experimentation will show which ones can be).

Importing and Glue

Suppose you have a HyperCard stack containing an XCMD you'd like to be able to call from UserTalk. To import the XCMD into the database, all you have to do is this: in the Finder, drop the stack's icon onto Frontier's icon. Frontier will search the stack for XCMDs and will offer to import each one in turn into system.extensions. XCMDName.code as a binary. Another option is to use a resource editor such as ResEdit to copy the desired XCMD into its own resource file, and drop that resource file's icon onto Frontier's icon.

It is also possible to write a script to import the desired XCMD into the database; this is demonstrated in Chapter 20, Resources (Example 20-3).

Some XCMDs may expect the presence of other resources, such as dialogs. It is possible to import these into the database as well and make them available in the resource chain as part of the action of the glue script. This is also discussed in Chapter 20.

Having imported an XCMD, you should write glue for it. The UserTalk interface to an XCMD binary is through the verb callXCMD(). It's easy to use. Suppose we have at system.extensions.sortFieldByItem.code an XCMD which in HyperTalk would be called like this:

sortFieldByItem (bg fld "myFld", 7)

where the first parameter is some text and the second parameter is a number. Then the glue would look like this:

on sort (s, n)
    return callXCMD (@sortFieldByItem.code, s, string(n))

The coercion is needed because XCMDs take only string parameters. If the glue lives at system.extensions.sortFieldByItem.sort, the user can then simply call sortFieldByItem.sort().

A UCMD is easier to import because it will typically be delivered as a packed object; just open it from the Finder, and Frontier will import it automatically (see Chapter 29, Import/Export). The packed object will include both the UCMD and the glue, so the UCMD will be usable immediately with no further effort. The format of UCMD glue is explained later; see Chapter 32, Driving Other Applications, and Chapter 43.


1. The only difference between an XCMD and an XFCN is that the latter is intended to return a value, the former is not. Henceforward I shall generally refer to both as XCMDs.

2. They are mostly available for free download via the Internet. See, for example, http://www.glasscat.com/hypercard/makeIND.cgi/XCMD_etc.


TOP UP: Data Manipulation NEXT: Interface

This is Frontier: The Definitive Guide by Matt Neuburg, unabridged and unaltered from the January 1998 printing.
It deals with the freeware Frontier 4.2.3; for commercial Frontier 8, look here, and for the inexpensive Radio UserLand, look here. See my Web site for information.
Those wishing an offline or printed copy may purchase the book, which is still in print.
Copyright 1998 O'Reilly & Associates, Inc. ALL RIGHTS RESERVED. Reprinted with permission.