In the latest episode of the Array Cast we discussed tacit programming but perhaps did not say enough about what we meant.
So here is a tiny example of a useful tacit expression.
From the very beginning I wanted my APL functions to look like extensions of the language. Not the style I had learned with Fortran
∇ MAIN
[1] DOTHIS
[2] DOTHAT
[3] DOTHEOTHER
[4] ∇
John Backus
but
R←OTHER THAT THIS x
Although I did not then know the term, functional programming was in the air. “APL was the primary influence on John Backus’s FP” – and why Backus proposed Ken Iverson for the Turing Award.
So my inner aesthete was excited by Ken’s internal paper at I.P. Sharp Associates that used what he called “direct definition”.
PLUS: ⍺ + ⍵
And John Scholes eventually implemented a version of direct definition in Dyalog APL as ‘dfns’.
plus ← {⍺ + ⍵}
I often want the members of an integer range. Say, a range of 5 11
should return 5 6 7 8 9 10
.
Clearly it involves the the APL Index Generator – til
in q.
⍳11
0 1 2 3 4 5 6 7 8 9 10
q)til 11
0 1 2 3 4 5 6 7 8 9 10
Traditional APL suggests keeping a ‘utility’ function around.
∇ RANGE
[0] Z←X RANGE Y
[1] Z←X+⍳Y-X
[2] ∇
5 RANGE 11
5 6 7 8 9 10
Lambdas are less fuss.
5{⍺+⍳⍵-⍺}11
5 6 7 8 9 10
q){x+til y-x}[5;11]
5 6 7 8 9 10
or, given the range as a pair
⊃{⍺+⍳⍵-⍺}/5 11
5 6 7 8 9 10
q){x+til y-x}. 5 11
5 6 7 8 9 10
Above, the q Apply operator (.
) applies its lambda left argument to a list of its two arguments. The APL solution gets there by using the lambda to reduce the pair, and must then Disclose the result.
This still seemed too much ‘ceremony’ for something so simple. I wanted more. Or rather, I wanted less.
A two-operator version is as efficient for small arguments.
⊃{⍺↓⍳⍵}/5 11
5 6 7 8 9 10
q){x _ til y}. 5 11
5 6 7 8 9 10
The Bind operator ∘
in Dyalog APL allows me one more step. I can replace {⍺↓⍳⍵}
with ↓∘⍳
.
⊃↓∘⍳/5 11
5 6 7 8 9 10
John Scholes
WIBNI (wouldn’t it be nice if) was a favourite coinage of John Scholes.
WIBNI we could borrow q’s Apply operator? As an APL operator it would derive from a dyadic function a monadic function that takes the dyadic’s two arguments as a 2-element array.
↓∘⍳. 5 11
5 6 7 8 9 10
Now we’re cooking. A simple tacit expression for range: ↓∘⍳.
. No ceremony. You could hear a pin drop. You could hear yourself think.