Tacit programming: Difference between revisions

Jump to navigation Jump to search
4,706 bytes added ,  17:10, 7 April 2020
(Created page with "Tacit functions apply to implicit arguments following a small set of rules. This is in contrast to the explicit use of arguments in dfns (<source inline lang=apl>⍺ ⍵</sour...")
 
(21 intermediate revisions by 2 users not shown)
Line 1: Line 1:
Tacit functions apply to implicit arguments following a small set of rules. This is in contrast to the explicit use of arguments in dfns (<source inline lang=apl>⍺ ⍵</source>) and Tradfns (which have named arguments). Known dialects which implement trains are Dyalog APL, dzaima/apl, ngn/apl and NARS2000.
Tacit functions apply to implicit arguments following a small set of rules. This is in contrast to the explicit use of arguments in [[dfns]] (<source inline lang=apl>⍺ ⍵</source>) and [[tradfns]] (which have named arguments). Known dialects which implement trains are [[Dyalog APL]], [[dzaima/APL]], [[ngn/apl]] and [[NARS2000]].


== Primitives ==
== Primitives ==
All primitive functions are tacit. Some APLs allow primitive functions to be named.
All [[primitive functions]] are tacit. Some APLs allow primitive functions to be named.
<source lang=apl>
<source lang=apl>
       plus ← +
       plus ← +
Line 8: Line 8:
       6 times 3 plus 5
       6 times 3 plus 5
48
48
</source>
== Derived functions ==
Functions derived from a monadic operator and an operand, or from a dyadic operator and two operands are tacit functions:
<source lang=apl>
      Sum ← +/
      Sum ⍳10
55
      Dot ← +.×
      3 1 4 dot 2 7 1
17
</source>
== Derived operators ==
A dyadic operator with its right operand forms a tacit monadic operator:
<source lang=apl>
      1(+⍣2)10
12
      Twice ← ⍣2
      1 +Twice 10
12
</source>
</source>


== Trains ==
== Trains ==
A train is a series of functions in isolation. An isolated function is either surrounded by parentheses or named. 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'':
{|
|<source lang=apl>  (g h) ⍵</source>|| {{←→}} ||<source lang=apl>g (  h ⍵)</source>
|-
|<source lang=apl>⍺ (g h) ⍵</source>|| {{←→}} ||<source lang=apl>g (⍺ h ⍵)</source>
|}
A 3-train is a ''fork'':
{|
|<source lang=apl>  (f g h) ⍵</source>|| {{←→}} ||<source lang=apl>(  f ⍵) g (  h ⍵)</source>
|-
|<source lang=apl>⍺ (f g h) ⍵</source>|| {{←→}} ||<source lang=apl>(⍺ f ⍵) g (⍺ h ⍵)</source>
|}
The ''left tine'' of a fork can be an array:
{|
|<source lang=apl>  (A g h)</source>|| {{←→}} ||<source lang=apl>A g (  h ⍵)</source>
|-
|<source lang=apl>⍺ (A g h) ⍵</source>|| {{←→}} ||<source lang=apl>A g (⍺ h ⍵)</source>
|}
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>
== 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 ===
<source lang=apl>
      (+,-) 2    ⍝ ±2
2 ¯2
      5 (+,-) 2  ⍝ 5±2
7 3
</source>
=== Arithmetic mean ===
<source lang=apl>
<source lang=apl>
  (g h) ⍵ ⬄ g ( h ⍵)
      (+⌿÷≢) ⍳10      ⍝ Mean of the first ten integers
⍺ (g h) ⍵ ⬄ g (⍺ h ⍵)
5.5
      (+⌿÷≢) 5 4⍴⍳4    ⍝ Mean of columns in a matrix
1 2 3 4
</source>
</source>


A 3-train is a ''fork'':
=== 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
<source lang=apl>
      (1∧⊢,÷)2.625
21 8
</source>
Alternatively, we can convert it to the mixed fraction <math>2{5\over 8}</math> with
A mixed fraction:
<source lang=apl>
      (1∧0 1∘⊤,÷)2.625
2 5 8
</source>
 
=== Is it a palindrome? ===
<source lang=apl>
      (⌽≡⊢)'racecar'
1
      (⌽≡⊢)'racecat'
0
</source>
 
=== Split delimited text ===
<source lang=apl>
<source lang=apl>
  (f g h) ⍵ ⬄ ( f ⍵) g (  h ⍵)
      ','(≠⊆⊢)'comma,delimited,text'
⍺ (f g h) ⍵ ⬄ (⍺ f ⍵) g (⍺ h ⍵)
┌─────┬─────────┬────┐
│comma│delimited│text│
└─────┴─────────┴────┘
      ' '(≠⊆⊢)'space delimited text'
┌─────┬─────────┬────┐
│space│delimited│text│
└─────┴─────────┴────┘
</source>
</source>


The ''left tine'' of a fork (but not an atop) can be an array:
=== 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 <math>\textbf{a}</math> in the direction of another vector <math>\textbf{b}</math>:
:::<math>\textbf{a}_\textbf{b} = (\textbf{a}\cdot\hat{\textbf{b}})\hat{\textbf{b}}</math>
<source lang=apl>
<source lang=apl>
  (A g h) ⍵ ⬄ A g (  h ⍵)
      Root ← *∘÷⍨              ⍝ Nth root
(A g h) ⍵ ⬄ A g (h )
      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
</source>
</source>
For a more parallel comparison of the notations, see the [[Comparison_with_traditional_mathematics#Practical_example|comparison with traditional mathematics]].
== External links ==
== Tutorials ==
* Dyalog: [http://help.dyalog.com/16.0/Content/RelNotes14.0/Function%20Trains.htm version 14.0 release notes]
* 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=kt4lMZbn-so How to read trains in Dyalog APL code] (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)


== Expressing algorithms ==
== Documentation ==
One of the major benefits of tacit programming is the ability to convey a short, well-defined idea as an isolated expression ([https://aplwiki.com/wiki/Simple_examples#Tacit_programming example]).  
* [http://help.dyalog.com/16.0/Content/RelNotes14.0/Function%20Trains.htm Announcement]
* [http://help.dyalog.com/latest/Content/Language/Introduction/Trains.htm Dyalog]


{{APL Language}}
==References==
<references/>
{{APL syntax}}

Navigation menu