Sharpening your APL knife

Basics -1-

Simple Arrays

Originally, there where only two types of arrays in APL:


  • Characters arrays
  • Numeric arrays

Those arrays could have a rank of 0, 1, 2 or more

The rank is defined as ⍴⍴

Mixed and Nested Arrays

  • ⍝ Later mixed arrays were introduced:
  •   ≡mixed←'abc',1,'def',2
  • 1
  • ⍝ Together with nested arrays:
  •   ≡nested←'abc' 1 'def' 2
  • ¯2
  •   ⍴¨mixed nested
  • 8  4

Deeply Nested Arrays

¯4 ←→ ≡na←1 (2 3) 'abc' (¯2 (2 2⍴'aa' 1) 3)'apl'

Arrays: Overhead -1-

  • ordinaryVars←1 2 3
  • 20 ←→ ⎕size 'ordinaryVars'

Every ordinary variable remains of two parts:

Arrays: Overhead -2-

  • nestedVars←⊂1 2 3
  • 36 ←→ ⎕size 'nestedVars'

For all parts of a nested variable, the data chunks are kept apart from each other

The variable itself contains only:

Arrays: Overhead -3-

  • simple←1,2,3
  • 20 ←→ ⎕size 'simple'
  • nested←⊂1 (21 22) 3
  • 96 ←→ ⎕SIZE 'nested'
  • mixed←1,'2',3
  • 76 ←→ ⎕size 'mixed'
  • nestedAndMixed←⊂1 (21 22) '3'
  • 96 ←→ ⎕size 'nestedAndMixed'
  • nestedAndMixed←⊂1 (21 22) '3' 'hello'
  • 124 ←→ ⎕size 'nestedAndMixed'

Arrays: Performance Issues -1-

  • buffer←''
  • :Repeat
  •   buffer←buffer,ReadRecord fileNo
  • :Until EndOfFile

To be avoided even with small amounts of data because it is an assumption that the amount of data is small!

Arrays: Performance Issues -2-

  • buffer←''
  • :Repeat
  •   buffer←buffer,  ReadRecord fileNo
  • :Until EndOfFile

Arrays: Overhead - Sample 1

  •   rec←'filename.txt' 'c:\dir\log\' (2007 02 03)
  •   rec←30000 3⍴rec
  • 2.760.020 ←→ ⎕size 'rec'
  •   ⍴rec2←⍕rec
  • 30000 37
  • 1.110.020 ←→ ⎕size 'rec2'

Point out that "rec" is a mixed and nested array while rec2 is a simple char matrix

Arrays: Overhead - Sample 2

  •   rec←'filename.txt' 'c:\dir\log\' (2007 02 03)
  •   rec←30000 3⍴rec
  • 2.760.020 ←→ ⎕size 'rec'
  • 3 ←→ ⍴rec2←↑¨⊂[1]rec
  • 30000 12  30000 11  30000 3 ←→ ⍴¨rec2
  • 870.088 ←→ ⎕size 'rec2'

Explain "vector" format and "matrix" format. Point out advantages and drawbacks

Prototype - the problem

In case of an "overtake" operation a definition is needed:

  •   n←1 2 3
  •   4↑n
  • ?
  •   10⍴0/n
  • ?

Explain "Overtake" and its association with prototypes

Prototype of simple arrays -1-

  •   t←'text'
  •   n←1 2 3
  •   (10↑t),'|'
  • text      |
  •   10↑n
  • 1 2 3 0 0 0 0 0 0 0

Prototype of simple arrays -2-

  •   ' '=1↑0/t
  • 1
  •   ' '=1↑0/n
  • 0

Prior to ⎕DR this was used to examine the data type of a simple variable

Prototype of nested arrays -1-

Display 1⊃n←(1 (2 3 ('s' 4)) 'abc') 1 (1 2 3)

Broken Windows

Prototype of nested arrays -2-

  •   1⊃n←(1 (2 3 ('s' 4)) 'abc') 1 (1 2 3)
  • 1  2 3   s  4   abc
  •   1↑0/n
  • 0  0 0    0
  •   ' '=1↑0/n
  • 0  0 0  1 0   1 1 1 

Prototype of nested arrays -3-

For nested arrays, the prototype is build by the following rules:

  • a) Take the first item of the nested array:
  •    1  2 3   s  4   abc ⍝ The first item
  • b) Replace recursively chars by blanks and numbers by 0:
  •    0  0 0    0         ⍝ That is the Prototype!

Mention the "∊" function which is performing both steps with ⎕ML←0

Prototypes: what are they good for?

Prototypes are used as a fill element if needed

  • ⍝ An overtake where one fill element is needed:
  • 3↑2↑array
  • ⍝ An overtake where three fill elements are needed:
  • 3↑0/array

Fill elements are also needed with references under special circumstances, but this is not covered yet

Prototypes: Predicting

As a consequence, the prototype of an empty, non-simple array can be predicted only if you know the contents/structure of the original variable

  •   n←0/(1 (2 3 ('ds' 4)) 'abc') 1 (1 2 3)
  •   ≡n
  • ¯5
  •   ⍴n
  • 0

Prototypes: Conclusion

If fill elements are needed, handle them yourself whenever possible. For example, to get one, two or three elements out of a right argument Y:

  • r←FunctionName Y
  • :If (≡Y)∊0 1
  •   Y←⊂Y
  • :EndIf
  • (filename path aliasName)←Y,(⍴,Y)↓3⍴' '

End