Skip to content

An APL SCRIPT Function

Vector 7:3, page 24

education programming techniques

Transcribed from the printed issue; not yet reviewed. Read it in the PDF of the issue, page 24

Have you felt the need for being able to record the results of a session of APL for future use? The ability to be able to record a sequence of APL statements and any results returned, so that, perhaps, text can be placed round the APL session script to form an illustrated article on APL or the use of APL? In a teaching environment, this facility is quite important, as it is in writing these articles for Education Vector.

Here then is something like what is required. I have called it APLSCRIPT, and it produces a vector that when printed looks approximately like the screen would have appeared had the same set of instructions been executed. The function may be terminated by typing an input of four consecutive asterisks.

Here is a typical example of its use.

      Z←APLSCRIPT
X←1 2 3 4
⍴X
4
+/X
4
(+/X)÷⍴X
2.5
3 4⍳4
1 2 3 4
1 2 3 4
1 2 3 4
****

      Z
      X←1 2 3 4
      ⍴X
4
      +/X
10
      (+/X)÷⍴X
2.5
      3 4⍴⍳4
1 2 3 4
1 2 3 4
1 2 3 4

The basic idea is to capture input from the keyboard using ⍞, and then to execute the resulting string, attaching the result of the execution (if there is one) to the string in a suitable way.

The function used is relatively simple; no attempt has been made to be clever and scan the input line for embedded allocations to the screen (⎕←), though one of these occurring at the beginning of the session is acceptable.

The function (written in APL*PLUS) is recorded below. Note that it has a line (line 2) containing an error check, which allows the user to make a silly mistake and recover from it. (If you are not using APL*PLUS, then you may have to adapt the program sensibly, by replacing the existing error trap with its equivalent one for your interpreter, or perhaps even dropping the statement altogether.)

    ∇APLSCRIPT[⎕]∇
[0]  ∆SCRIPT←APLSCRIPT;∆S;∆C;∆F;∆D;∆;⎕ELX;∆G
[1]  ⍝
[2]   ⎕ELX←''' ERROR IN COMMAND LINE-REDO ''','⋄→lp'
[3]   ∆SCRIPT←'' ⋄ ∆F←1 ⍝ F RECORDS IF COMMAND ENDS IN A RESULT
[4]  lp:∆S←⍞ ⋄ ∆SCRIPT←∆SCRIPT,(0=⍴∆S)/⎕AV[14] ⍝APPEND LINE FEED
[5]  ⍝IF SO, RETURN WITH EMPTY ST
[6]   →(0=⍴∆S)/lp
[7]  ⍝DROP LEADING BLANKS
[8]   ∆S←(~∧\∆S=' ')/∆S ⋄ →(∧/'****'=4↑∆S)/0
[9]  ⍝FIND WHERE ← IS
[10]  ∆G←∆S⍳'←' ⋄ ∆G←∆G×∆G≤⍴∆S
[11] ct:∆S←(('⎕'=1↑∆S)×∆G)↓∆S ⋄ ⍎'∆←',∆S
[12] ⍝CHECK TO SEE IF STRING TO LEFT OF ← IS A VARIABLE
[13]  ∆C←(¯1+∆S⍳'←')↑∆S
[14]  ∆D←⍴⎕NL 2 ⋄ ∆F←~(∆G≠0)∧∨/((∆D[1],∆D[2]⌈⍴∆C)↑⎕NL 2)∧.=(∆D[2]⌈⍴∆C)↑∆C
[15] do:∆S←(5⍴' '),∆S
[16] ⍝ APPEND LINE-FEEDS TO COMMAND-LINE
[17]  ∆SCRIPT←∆SCRIPT,⎕AV[14],∆S,⎕AV[14] ⋄ →(~∆F)/lp
[18]  ⍎(∆F/'⎕←'),'∆←⍕∆' ⋄ ∆←∆,⎕AV[14]
[19]  ∆SCRIPT←∆SCRIPT,,∆ ⋄ →lp
    ∇

If error trapping is not included, then continuity can be provided with a little care. Here is an example:

      Z∆←APLSCRIPT
X←1 2 3 4
X÷0 1 2 3

DOMAIN ERROR
APLSCRIPT[9]⍎⋄X÷0 1 2 3 4
                ∧

At this point the local variable SCRIPT is available to you, except that it will not contain the statement which caused the crash. One can thus issue a statement such as

      Z←SCRIPT (suitable for a first-time crash)

or    Z←Z,SCRIPT
      )RESET                ...and then
      Z←Z,APLSCRIPT

… to continue.

Since I wrote this function quite recently, I have used it considerably and wonder why I didn’t write it a long time ago! If you have any suggestions for alternative APLSCRIPT functions please share your thoughts with readers.