# Tacit programming: Difference between revisions

Tacit functions apply to implicit arguments following a small set of rules. This is in contrast to the explicit use of arguments in dfns (⍺ ⍵) and tradfns (which have named arguments). Known dialects which implement trains are Dyalog APL, dzaima/APL, ngn/apl and NARS2000.

## Primitives

All primitive functions are tacit. Some APLs allow primitive functions to be named.

      plus ← +
times ← ×
6 times 3 plus 5
48

## Derived functions

Functions derived from a monadic operator and an operand, or from a dyadic operator and two operands are tacit functions:

      Sum ← +/
Sum ⍳10
55

Dot ← +.×
3 1 4 dot 2 7 1
17

## Derived operators

A dyadic operator with its right operand forms a tacit monadic operator:

      1(+⍣2)10
12
Twice ← ⍣2
1 +Twice 10
12

## Trains

A train is a series of functions in isolation. An isolated function is either surrounded by parentheses or named. Below, ⍺ and ⍵ refer to the arguments of the train. f, g, and h are function (which themselves can be tacit or not), and A is an array. The arguments are processed by the following rules:

A 2-train is an atop:

  (g h) ⍵ $\Leftrightarrow$ g ( h ⍵) ⍺ (g h) ⍵ $\Leftrightarrow$ g (⍺ h ⍵)

A 3-train is a fork:

  (f g h) ⍵ $\Leftrightarrow$ ( f ⍵) g ( h ⍵) ⍺ (f g h) ⍵ $\Leftrightarrow$ (⍺ f ⍵) g (⍺ h ⍵)

The left tine of a fork can be an array:

  (A g h) $\Leftrightarrow$ A g ( h ⍵) ⍺ (A g h) ⍵ $\Leftrightarrow$ A g (⍺ h ⍵)

Only dzaima/APL allows (A h), which it treats as A∘h.

## Examples

One of the major benefits of tacit programming is the ability to convey a short, well-defined idea as an isolated expression. This aids both human readability (semantic density) and the computer's ability to interpret code, potentially executing special code for particular idioms.

### Plus and minus

      (+,-) 2     ⍝ ±2
2 ¯2
5 (+,-) 2   ⍝ 5±2
7 3

### Arithmetic mean

      (+⌿÷≢) ⍳10       ⍝ Mean of the first ten integers
5.5
(+⌿÷≢) 5 4⍴⍳4    ⍝ Mean of columns in a matrix
1 2 3 4

### Fractions

We can convert decimal numbers to fractions. For example, we can convert $2.625$ to the improper fraction $21 \over 8$ with

      (1∧⊢,÷)2.625
21 8

Alternatively, we can convert it to the mixed fraction $2{5 \over 8}$ with A mixed fraction:

      (1∧0 1∘⊤,÷)2.625
2 5 8

### Is it a palindrome?

      (⌽≡⊢)'racecar'
1
(⌽≡⊢)'racecat'
0

### Split delimited text

      ','(≠⊆⊢)'comma,delimited,text'
┌─────┬─────────┬────┐
│comma│delimited│text│
└─────┴─────────┴────┘
' '(≠⊆⊢)'space delimited text'
┌─────┬─────────┬────┐
│space│delimited│text│
└─────┴─────────┴────┘

### Component of a vector in the direction of another vector

Sometimes a train can make an expression nicely resemble its equivalent definition in traditional mathematical notation. As an example, here is a program to compute the component of a vector ${\textbf {a}}$ in the direction of another vector ${\textbf {b}}$ :

${\textbf {a}}_{\textbf {b}}=({\textbf {a}}\cdot {\hat {\textbf {b}}}){\hat {\textbf {b}}}$ Root ← *∘÷⍨              ⍝ Nth root
Norm ← 2 Root +.×⍨       ⍝ Magnitude (norm) of numeric vector in Euclidean space
Unit ← ⊢÷Norm            ⍝ Unit vector in direction of vector ⍵
InDirOf ← (⊢×+.×)∘Unit   ⍝ Component of vector ⍺ in direction of vector ⍵
3 5 2 InDirOf 0 0 1      ⍝ Trivial example
0 0 2

For a more parallel comparison of the notations, see the comparison with traditional mathematics.