Welcome back.

Welcome back. At the end of the last section we saved our workspace. If you would like to continue to save your work as you go, please:

  1. Load your previously saved workspace
  2. Create a namespace called Day2 and change into that namespace.

You are of course welcome to simply proceed through each section with a )CLEAR workspace.

Session Toolbelt

Dyalog provides a native IDE for Microsoft Windows, and the Remote IDE for macOS and Linux. As well as the text-editor-like APL session, these provide some additional tools and shortcuts to make working with Dyalog easier. Click here to learn about some of these.

Depth

We introduced stranding to show how it formed vectors before the application of dyadic functions, for example:

      2 + 2 2 + 2   
      2 + 2 (2 + 2)
      (2 + 2) 2 + 2

Stranding is a useful way to form arrays. Generally, arrays separated by spaces form vectors. Experiment with the examples below, and notice the difference between stranding a b and catenation a,b.

      2 3⍴'DY' 'AL' 'OG'
      'a' 'b' 'c'
      'a' 'bc'
      'a','b','c'
      'a','bc'
      mixed←3 3⍴1 2 3 'a' 'b' 'c'   ⍝ Simple mixed-type array
      mixed2←3 3⍴1 2 3 'abc'        ⍝ Nested mixed-type array

Note that the prototypical element of a numeric array is the number zero 0 and of a character array is a space ' ' character (⎕UCS 32).

      bnm←2 3⍴⍬                     ⍝ Blank numeric matrix
      bcm←3 2⍴''                    ⍝ Blank character matrix
      (⎕UCS 32)=bcm

Below are some more examples to demonstrate the difference between catenation, first-axis catenation and stranding.

      3 1⍴mixed bnm bcm
      ⍪mixed bnm bcm
      ↑mixed bnm bcm
      mixed,bcm
      mixed⍪bcm
      mixed⍪bnm
      3 3⍴mixed,bcm
      3 3⍴mixed bnm,bcm

A simple scalar is a rank-0 array which contains itself as its value.

      'a'≡⊃'a'       ⍝ The disclose of a simple scalar is itself
      42≡⊂42         ⍝ As is the enclose
      'abc'≡⊃'abc'   ⍝ Disclose on a simple array picks the first element
      'abc'≡⊂'abc'   ⍝ Enclosing an array results in a nested scalar
  1. When does (a b)≡a,b?

  2. When does (↑a b)≡a⍪b?

Primitive Loops

Experiment with the following expressions to determine what the each ¨ and bind operators do in this context.

      's',¨'ong' 'ink' 'and'
      'lph',¨'ong' 'ink' 'and'
      (1 2)(2 2)(3 1)⍴¨3 4 5
      2 2∘⍴¨3 4 5
      (⍴∘3 4 5)¨2 2

Options

Sometimes we would like a function to accept one or more option or parameter arguments.

For example

      'bob'{⍺∘≡¨⍵}'bob' 'dave' 'jim' 
1 0 0
      'bob'{⍺∘≡¨⍵}'bob'  
0 0 0

Why does the second expression above return three values? This is remedied using the enclose-if-simple function (monadic ).

      {'bob'∘≡¨⊆⍵}'bob'  
1

We can define stranding as the Strand function.

      Strand←{(⊂⍺),⊆⍵}               ⍝ A Stranding function 
      'bob'Strand'dave'Strand'jim'
┌───┬────┬───┐
│bob│dave│jim│
└───┴────┴───┘

Or as the function Strand2←{⍺⍵}.

Word Problems

We are going to do some text processing on a dictionary of words.

If you have access to the internet, the following expressions will download a text file dictionary (917kB in size) and store it as a nested vector of character vectors named words.

      ]Load HttpCommand
      words ← (⎕UCS 10) {(⍺≠⍵)⊆⍵} (HttpCommand.Get'https://tinyurl.com/y7asendy').Data

If you have the file on your computer (maybe you were given it on a USB drive, for example) then you can load it into your workspace from disk using the following expressions.

      (content encoding newline) ← ⎕NGET'/path/to/words.txt'
      words ← (⎕UCS newline) (≠⊆⊢) content

Now answer the following questions about words.

  1. How many words have at least 3 'e's in them?

  2. How many words have exactly two consecutive 'e's in them? The first three such words are Aberdeen Abderdeen's and Aileen.

  3. What is the shortest word with two consecutive 'a's?

  4. What words have three consecutive double letters? For example, mississippi does not but misseetto does. Misseetto is not a real word.

A palindrome is the same when reversed. For example, racecar is a palindrome but racecat is not.

  1. How many palindromes are there in words?

  2. Which palindrome in words is the longest?

An introduction to an introduction to an introduction to an introduction to an int…

Try the following dfns with various numeric arguments and consider the following:

  1. Which symbol refers to the function itself?
  2. Which symbol separates expressions?
  3. Which part represents a conditional? This is where one part of code executes only if a preceding statement is true.
  4. What is the default left argument? What happens if you call this function dyadically?
      {⍺←1 1 ⋄ ⍵=2:⍺ ⋄ (⍺,(+/¯2↑⍺))∇⍵-1}

Give the function an appropriate name.

When a function calls itself like this it is called recursion. APL tends to rely less on explicit iteration and recursion than most popular programming languages, but it is good to be able to do it when you need to.

If a function gets stuck in an infinite loop, use Action → Interrupt in the menu. You can also use the key combination Ctrl+Break to interrupt a running function.

  1. Write the shortest dfn which causes infinite recursion.

  2. Write the shortest dfn which causes infinite recursion unless its argument is 0.

  3. The factorial function multiplies integers up to . Write the factorial function as a recursive dfn called Factorial. Use the primitive !N factorial function to check your solution.

  4. Write an expression for the factorial function as a reduction (an expression which includes f/ for some function f).

A Sort of Detour

Dyalog’s grade-up and grade-down functions are able to sort any array. However, it is interesting and useful to look at other approaches to sorting.

Here is a function ‘NSort’ for sorting numeric lists.

      NSort←{0=⍴⍵:⍬ ⋄ (U/⍵),∇(~U←⍵=⌊/⍵)/⍵}

Try NSort with some numeric arguments. Here it is presented piece-by-piece. For each comment prompt , write a brief description of what that part of the function does. The first one has been done for you.

      NSort←{
             0=⍴⍵:⍬                         ⍝ Reached end of list, return empty numeric vector
                    ⋄                       ⍝ 
                      (U/⍵),                ⍝ 
                            ∇               ⍝
                             (~U←⍵=⌊/⍵)     ⍝
                                       /⍵   ⍝
                                         }

Below is a function TSort for sorting character matrices.

      TSort←{⍺[((⍴⍵)[2])S ⍺⍳⍵]}
      S←{⍺=0:⍵ ⋄ (⍺-1)S ⍵[⍋⍵[;⍺];]}

Examine TSort and replace below with an appropriate left argument to sort the character matrix WORDS.

      WORDS←↑'DOLPHIN' 'BRACKEN' 'SAUCER' 'MAGNET' 'FLOP'
      ⍺ TSort WORDS
BRACKEN
DOLPHIN
FLOP   
MAGNET 
SAUCER 

What do the following expressions tell you about the grade-up and grade-down functions on high-rank arrays?

      ⍋4 2 2⍴∊1 2 3 4,¨?4⍴(⊂3⍴10)
      ⍒4 2 2⍴∊'ABCD',¨{⎕A[⍵]}¨?4⍴(⊂3⍴10)

Rank Practice

  1. Model Each
    Write models of the following functions using rank instead of each ¨. That is, write IotaEach, SumEach and ReshapeEach as dfns which use the rank operator and do not use the each operator.
           IotaEach 1 2 3              ⍝ ⍳¨1 2 3
     ┌─┬───┬─────┐
     │1│1 2│1 2 3│
     └─┴───┴─────┘
           SumEach 2 3⍴ IotaEach ⍳6    ⍝ +/¨2 3⍴⍳¨⍳6
      1  3  6
     10 15 21
    
           2 2 ReshapeEach (1 2) 3 4   ⍝ 2 2∘⍴¨(1 2) 3 4
     ┌───┬───┬───┐
     │1 2│3 3│4 4│
     │1 2│3 3│4 4│
     └───┴───┴───┘
    
Each ¨ will implicitly disclose its arguments. You might need to use enclose and disclose to achieve the desired effect.
  1. Split k-cells
    The split function (monadic ) splits an array of rank ≥2 by rows, returning an array of shape ¯1↓⍴⍵. Use enclose with the rank operator to create a function Split which always splits an array into a nested vector of the major cells of .

           Split 3 2 2 3⍴⍳9
       ┌─────┬─────┬─────┐
       │1 2 3│4 5 6│7 8 9│
       │4 5 6│7 8 9│1 2 3│
       │     │     │     │
       │7 8 9│1 2 3│4 5 6│
       │1 2 3│4 5 6│7 8 9│
       └─────┴─────┴─────┘