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'
- Can be nested as deeply as you want/need
- Gives you all freedom in data design
- You have to pay a price for this...
Arrays: Overhead -1-
- ordinaryVars←1 2 3
- 20 ←→ ⎕size 'ordinaryVars'
Every ordinary variable remains of two parts:
- The data as such
- The variable header (type,rank,shape...)
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:
- Pointers to memory where the data is held
- The header of the nested variable (type,rank,shape...)
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
- Very expensive technique
- Every assignment copies the variable in the first place
- To be avoided whenever possible
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
- APL allocates memory only for the next chunk of data
- No copy operation of data is performed
- Only the header information is added (=also copied) in memory
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:
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-
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)
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