Contents

The language of a high-level development environment contributes in two ways: by being as clear and understandable as possible, and also by being as powerful as possible.

Power
A more powerful programming language takes fewer lines of code to perform a given task, in the same way that a power tool does its job faster than a hand tool.

Fewer lines of code indicates a higher level of abstraction, which lets the developer think more in terms of the problem to be solved and less in terms of the hardware and OS. This is especially important in cross-platform development.

Developers speak of “generations” of programming languages17. Machine code, the native language of the CPU, is the first generation. Assembly language, which is machine code represented by mnemonic tags, is the second generation. BASIC, despite its relatively simple syntax, is considered to be a third-generation language, similar to Pascal and C. Scripting languages like Perl, AppleScript, and TCL are often called fourth-generation languages because they offer even greater abstraction18. Transcript is a fourth-generation language: easier to understand and offering greater abstraction than languages of previous generations.

In addition, fewer lines of code to write is better exactly because it’s fewer lines of code to write — and thus read through, document, debug, and maintain.

Both REALbasic and Revolution can do in a few lines what might take tens or even hundreds of lines of C. In the example application, however, the main file-processing routines in REALbasic required over twice as many lines of code as Revolution: 182 vs. 81. Revolution offers a significant advantage in the amount of code to be written.

The line count difference is partly due to variable declarations, but also derives from commands in Revolution that have no equivalent in REALbasic. For example, the code to process a directory in REALbasic loops through each item in the directory, checking individually whether it is a file or a sub-directory:

'REALbasic Code:
tCount = tDir.count
for i = 1 to tCount
if (tDir.item(i).directory) then
' keep a list of the directories, to handle them later
tDirList = tDirList + "d " + tDir.item(i).absolutePath + cr
'...
else
'increment the file count
totalFileCount = totalFileCount + 1
'...
end if
end for

Revolution has built-in commands for getting the sub-directories and files:

-- Revolution Code:
put the files into tFiles
--...
put the directories into tDirs
--...

In addition, simple things like having predefined constants for tabs and return characters in Revolution simplified the process.

The example application can process large numbers of files, which takes time. Therefore the user must be able to pause or abort the process. In REALbasic, asynchronous operations were handled through the use of a thread. A thread is an object that runs independently of the main application code. The thread allows formatting the code in a traditional loop structure, but did require setting flag properties in order to start, stop, and restart the thread (there is no such capability built in).

Instead of a thread object, Revolution handles asynchronous operations through the use of delayed messages. This requires slightly different thinking: each time through, the code processes one file, and then calls itself with a delay if there is more work to do. Here is the Transcript to handle the asynchronous processing:

-- Revolution Code:
  if workQueue is not empty then
    send "doWork" to me in .0001 seconds
    put the result into gWorkMessage
  else
    close file gLogFile
  end if

The use of the “send” command in the second line allows other events to be delivered, independent of ongoing processing on the work queue. If the asynchronous operation needs to be paused, “cancel gWorkMessage” will do so. The process is resumed simply by issuing a “doWork” command.

REALbasic does offer a simpler alternative to setting up a thread object: the timer object. Use of a timer is similar to Revolution’s delayed messages. Unfortunately, a timer isn’t fast enough. Revolution’s delayed messages can fire several thousand times per second, compared to REALbasic’s timer object, which can’t fire faster than sixty times per second19. Using a timer, the REALbasic example application would have been more than fifteen times slower than the Revolution example application.

Clarity

A good indicator of the clarity of Revolution’s Transcript is the fact that many of the comments that document the code of the REALbasic version of the example application are direct quotes of the actual Transcript code for the same function. The following example shows comments written in Transcript, followed by the corresponding REALbasic code:

  'replace tab with "<!--tab-->" in tMatch -- Transcript
  tMatch = replaceAll(tMatch,tab,"<!--tab-->") 'BASIC

  'put word 1 of tLine into tType -- Transcript
  tSpacePos = inStr(tLine," ") 'BASIC
  tType = left(tLine,(tSpacePos-1)) 'BASIC

  'delete word 1 of tLine -- Transcript
  tLine = mid(tLine,(tSpacePos+1)) 'BASIC

Enabling and disabling sets of controls displays another clear distinction. REALbasic windows have a property that returns a list of their controls, which can be used to enable or disable them. However, the list is returned as generic control objects, which don’t have the enabled property, so they must be “cast” as their actual type before being enabled or disabled. Here is the code to do that:

'REALbasic Code:
  Sub XableRectControls(w as window, onoff as boolean)
    dim i, cc as integer
    dim cref as control
    cc = w.controlcount-1
    for i = 0 to cc
      cref = w.control(i)
      if cref isa rectcontrol then
        rectcontrol(cref).Enabled = onoff
      end if
    next
  End Sub

In Revolution, controls can always be enabled or disabled without having to “cast” them. Further, controls can be grouped. This code enables all the controls in a group:

-- Revolution Code:
  enable group "optionalControlGroup"

And this code disables the entire group:

-- Revolution Code:
  disable group "optionalControlGroup"

Thus a single line of Transcript does the work of an eleven-line BASIC routine.

Previous

Revolution and REALbasic: A Comparison

Next