Difference between revisions of "Tacit programming"

From APL Wiki
Jump to navigation Jump to search
 
(15 intermediate revisions by 4 users not shown)
Line 32: Line 32:
  
 
== Trains ==
 
== Trains ==
A train is a series of functions in isolation. An isolated function is either surrounded by parentheses or named. Below, <source lang=apl inline>⍺</source> and <source lang=apl inline>⍵</source> refer to the arguments of the train. <source lang=apl inline>f</source>, <source lang=apl inline>g</source>, and <source lang=apl inline>h</source> are function (which themselves can be tacit or not), and <source lang=apl inline>A</source> is an array. The arguments are processed by the following rules:
+
A train is a series of functions in isolation. An isolated function is either surrounded by parentheses or named. Below, <source lang=apl inline>⍺</source> and <source lang=apl inline>⍵</source> refer to the arguments of the train. <source lang=apl inline>f</source>, <source lang=apl inline>g</source>, and <source lang=apl inline>h</source> are functions (which themselves can be tacit or not), and <source lang=apl inline>A</source> is an array. The arguments are processed by the following rules:
  
 
A 2-train is an ''atop'':
 
A 2-train is an ''atop'':
Line 53: Line 53:
 
|}
 
|}
  
Only [[dzaima/APL]] allows <source lang=apl inline>(A h)</source>, which it treats as <source lang=apl inline>A∘h</source>.<ref>dzaima/APL: [https://github.com/dzaima/APL/blob/ceea05e25687988ed0980a4abf4b9249b736543f/docs/differences.txt#L19 Differences from Dyalog APL]. Retrieved 09 Jan 2020.</ref>
+
Only [[dzaima/APL]] allows <source lang=apl inline>(A h)</source>, which it treats as <source lang=apl inline>A∘h</source>.<ref>dzaima/APL: [https://github.com/dzaima/APL/blob/ceea05e25687988ed0980a4abf4b9249b736543f/docs/differences.txt#L19 Differences from Dyalog APL]. Retrieved 09 Jan 2020.</ref> See [[Bind]].
  
 
== Examples ==
 
== 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]].
+
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 [[idiom]]s.
  
 
=== Plus and minus ===
 
=== Plus and minus ===
Line 75: Line 75:
  
 
=== Fractions ===
 
=== Fractions ===
We can convert decimal numbers to fractions. For example, we can convert <math>2.625</math> to the improper fraction <math>21\over 8</math> with
+
We can convert decimal numbers to fractions. For example, we can convert <math>2.625</math> to the improper fraction <math>\tfrac{21}{8}</math> with
 
<source lang=apl>
 
<source lang=apl>
 
       (1∧⊢,÷)2.625
 
       (1∧⊢,÷)2.625
 
21 8
 
21 8
 
</source>
 
</source>
Alternatively, we can convert it to the mixed fraction <math>2{5\over 8}</math> with
+
Alternatively, we can convert it to the mixed fraction <math>2\tfrac{5}{8}</math> with a mixed fraction:
A mixed fraction:
 
 
<source lang=apl>
 
<source lang=apl>
 
       (1∧0 1∘⊤,÷)2.625
 
       (1∧0 1∘⊤,÷)2.625
Line 118: Line 117:
 
0 0 2
 
0 0 2
 
</source>
 
</source>
For a more parallel comparison of the notations, see the [[Comparison_with_traditional_mathematics#Practical_example|comparison with traditional mathematics]].  
+
For a more parallel comparison of the notations, see the [[Comparison_with_traditional_mathematics#Practical_example|comparison with traditional mathematics]].
 +
 
 +
===The Number of the Beast===
 +
The following expression for computing the [[wikipedia:666 (number)|number of the Beast]] (and of [[I.P. Sharp]]'s APL-based email system, [[666 BOX]]) nicely illustrates how to read a train.
 +
<source lang=apl>
 +
      ((+.×⍨⊢~∘.×⍨)1↓⍳)17 ⍝ Accursed train
 +
666
 +
</source>
 +
First, <source lang=apl inline>((+.×⍨⊢~∘.×)1↓⍳)</source> is supplied with only one argument <source lang=apl inline>17</source> and is thus interpreted monadically.
 +
 
 +
Second, <source lang=apl inline>(+.×⍨⊢~∘.×⍨)1↓⍳</source> is a 4-train: reading right-to-left, the last 3 components are interpreted as the fork <source lang=apl inline>1↓⍳</source> and the 4-train is interpreted as the atop <source lang=apl inline>(+.×⍨⊢~∘.×⍨)(1↓⍳)</source>.
 +
Similarly, <source lang=apl inline>(+.×⍨⊢~∘.×⍨)</source> is also a 4-train and interpreted as the atop <source lang=apl inline>+.×⍨(⊢~∘.×⍨)</source>.
 +
 
 +
Thus the accursed train is interpreted as <source lang=apl inline>((+.×⍨(⊢~∘.×⍨))(1↓⍳))17</source>. Having read the train, we now evaluate it monadically.
 +
<source lang=apl>
 +
      ((+.×⍨(⊢~∘.×⍨))(1↓⍳))17 ⍝ Accursed train as an atop over a fork atop a fork
 +
      +.×⍨(⊢~∘.×⍨)1↓⍳17      ⍝ Atop evalution
 +
      +.×⍨(⊢1↓⍳17)~∘.×⍨1↓⍳17  ⍝ Fork evalution
 +
      +.×⍨(1↓⍳17)~∘.×⍨1↓⍳17  ⍝ ⊢ evaluation
 +
      +.×⍨2 3 5 7 11 13 15 17 ⍝ numbers 2 through 17 without those appearing in their multiplication table are primes
 +
666                          ⍝ the sum of the squares of the primes up to 17
 +
</source>
 +
Note that <source lang=apl inline>((⊢⍨∘.×⍨)1↓⍳)</source> is a train computing primes up to the given input.
 +
 
 +
A more satisfying variation of the accursed train is the following.
 +
<source lang=apl>
 +
      (⍎⊢,⍕∘≢)'((+.×⍨⊢~∘.×⍨)1↓⍳)'                    ⍝ Accursed train 2.0
 +
      ⍎(⊢,⍕∘≢)'((+.×⍨⊢~∘.×⍨)1↓⍳)'                    ⍝ 4-train intepreted as an atop
 +
      ⍎(⊢'((+.×⍨⊢~∘.×⍨)1↓⍳)'),⍕∘≢'((+.×⍨⊢~∘.×⍨)1↓⍳)' ⍝ fork evaluation
 +
      ⍎'((+.×⍨⊢~∘.×⍨)1↓⍳)','17'                      ⍝ ⊢ evaluation and ⍕∘≢ evaluation
 +
      ⍎'((+.×⍨⊢~∘.×⍨)1↓⍳)17'                        ⍝ , evaluation
 +
666                                                  ⍝ ⍎ executes original Accursed train
 +
</source>
 +
 
 
== External links ==
 
== External links ==
== Tutorials ==
+
=== Tutorials ===
* APL Cultivation: [https://chat.stackexchange.com/rooms/52405/conversation/lesson-23-transcribing-to-and-reading-trains Transcribing to and reading trains]
+
* Dyalog: [http://help.dyalog.com/16.0/Content/RelNotes14.0/Function%20Trains.htm version 14.0 release notes]
* APLtrainer: [https://www.youtube.com/watch?v=kt4lMZbn-so How to read trains in Dyalog APL code] (video)
+
* [[APL Cultivation]]: [https://chat.stackexchange.com/rooms/52405/conversation/lesson-23-transcribing-to-and-reading-trains Transcribing to and reading trains]
* APLtrainer: [https://www.youtube.com/watch?v=A2LqqBosvY0 Function trains in APL] (video)
+
* [[APLtrainer]]: [https://www.youtube.com/watch?v=kt4lMZbn-so How to read trains in Dyalog APL code] (video)
* Dyalog Webinar: [https://www.youtube.com/watch?v=Enlh5qwwDuY?t=440 Train Spotting in Dyalog APL] (video)
+
* [[APLtrainer]]: [https://www.youtube.com/watch?v=A2LqqBosvY0 Function trains in APL] (video)
 +
* [[Dyalog webinar]]: [https://www.youtube.com/watch?v=Enlh5qwwDuY?t=440 Train Spotting in Dyalog APL] (video)
 +
* [[Dyalog '13]]: [https://www.youtube.com/watch?v=7-93GzDqC08 Train Spotting in Version 14.0] (video)
  
== Documentation ==
+
=== Documentation ===
 
* [http://help.dyalog.com/16.0/Content/RelNotes14.0/Function%20Trains.htm Announcement]
 
* [http://help.dyalog.com/16.0/Content/RelNotes14.0/Function%20Trains.htm Announcement]
 
* [http://help.dyalog.com/latest/Content/Language/Introduction/Trains.htm Dyalog]
 
* [http://help.dyalog.com/latest/Content/Language/Introduction/Trains.htm Dyalog]
  
==References==
+
== References ==
 
<references/>
 
<references/>
{{APL syntax}}
+
 
 +
{{APL syntax}}[[Category:Tacit programming| ]]

Latest revision as of 09:33, 15 May 2020

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 functions (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) 
g (  h )
 (g h) 
g ( h )

A 3-train is a fork:

  (f g h) 
(  f ) g (  h )
 (f g h) 
( f ) g ( h )

The left tine of a fork can be an array:

  (A g h)
A g (  h )
 (A g h) 
A g ( h )

Only dzaima/APL allows (A h), which it treats as Ah.[1] See Bind.

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 to the improper fraction with

      (1∧⊢,÷)2.625
21 8

Alternatively, we can convert it to the mixed fraction with a mixed fraction:

      (10 1⊤,÷)2.625
2 5 8

Is it a palindrome?

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

Split delimited text

      ','()'comma,delimited,text'
┌─────┬─────────┬────┐
commadelimitedtext
└─────┴─────────┴────┘
      ' '()'space delimited text'
┌─────┬─────────┬────┐
spacedelimitedtext
└─────┴─────────┴────┘

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 in the direction of another vector :

      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.

The Number of the Beast

The following expression for computing the number of the Beast (and of I.P. Sharp's APL-based email system, 666 BOX) nicely illustrates how to read a train.

      ((+.×⊢~∘.×)1↓⍳)17 ⍝ Accursed train
666

First, ((+.×⊢~∘.×)1↓⍳) is supplied with only one argument 17 and is thus interpreted monadically.

Second, (+.×⊢~∘.×)1↓⍳ is a 4-train: reading right-to-left, the last 3 components are interpreted as the fork 1↓⍳ and the 4-train is interpreted as the atop (+.×⊢~∘.×)(1↓⍳). Similarly, (+.×⊢~∘.×) is also a 4-train and interpreted as the atop +.×(⊢~∘.×).

Thus the accursed train is interpreted as ((+.×(⊢~∘.×))(1↓⍳))17. Having read the train, we now evaluate it monadically.

      ((+.×(⊢~∘.×))(1↓⍳))17 ⍝ Accursed train as an atop over a fork atop a fork
      +.×(⊢~∘.×)1↓⍳17       ⍝ Atop evalution
      +.×(1↓⍳17)~∘.×1↓⍳17  ⍝ Fork evalution
      +.×(1↓⍳17)~∘.×1↓⍳17   ⍝ ⊢ evaluation
      +.×2 3 5 7 11 13 15 17 ⍝ numbers 2 through 17 without those appearing in their multiplication table are primes
666                           ⍝ the sum of the squares of the primes up to 17

Note that ((⍨∘.×)1↓⍳) is a train computing primes up to the given input.

A more satisfying variation of the accursed train is the following.

      (⍎⊢,⍕)'((+.×⍨⊢~∘.×⍨)1↓⍳)'                    ⍝ Accursed train 2.0
      (⊢,⍕)'((+.×⍨⊢~∘.×⍨)1↓⍳)'                    ⍝ 4-train intepreted as an atop
      ('((+.×⍨⊢~∘.×⍨)1↓⍳)'),⍕'((+.×⍨⊢~∘.×⍨)1↓⍳)' ⍝ fork evaluation
      '((+.×⍨⊢~∘.×⍨)1↓⍳)','17'                      ⍝ ⊢ evaluation and ⍕∘≢ evaluation
      '((+.×⍨⊢~∘.×⍨)1↓⍳)17'                         ⍝ , evaluation
666                                                  ⍝ ⍎ executes original Accursed train

External links

Tutorials

Documentation

References

  1. dzaima/APL: Differences from Dyalog APL. Retrieved 09 Jan 2020.


APL syntax [edit]
General Comparison with traditional mathematicsPrecedenceTacit programming
Array Numeric literalStringStrand notationObject literalArray notation
Function ArgumentFunction valenceDerived functionDerived operatorNiladic functionMonadic functionDyadic functionAmbivalent functionTradfnDfnFunction train
Operator OperandOperator valenceTradopDopDerived operator
Assignment MultipleIndexedSelectiveModified
Other Function axisBranchingSystem commandUser commandKeywordDot notation