Difference between revisions of "Tacit programming"
Line 2: | Line 2: | ||
== 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 an operator and operand are tacit. | ||
+ | <source lang=apl> | ||
+ | sum ← +/ | ||
+ | sum ⍳10 | ||
+ | 55 | ||
</source> | </source> | ||
Line 31: | Line 39: | ||
</source> | </source> | ||
− | == | + | == Examples == |
− | One of the major benefits of tacit programming is the ability to convey a short, well-defined idea as an isolated expression ([ | + | 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 | ||
+ | 1 2 3 (+,-) 4 | ||
+ | 5 6 7 ¯3 ¯2 ¯1 | ||
+ | (2 3⍴0) (+,-) 1 | ||
+ | 1 1 1 ¯1 ¯1 ¯1 | ||
+ | 1 1 1 ¯1 ¯1 ¯1 | ||
+ | </source> | ||
+ | |||
+ | === Arithmetic mean === | ||
+ | <source lang=apl> | ||
+ | (+⌿÷≢) ⍳10 ⍝ Mean of the first ten integers | ||
+ | 5.5 | ||
+ | (+⌿÷≢) 5 4⍴⍳4 ⍝ Mean of columns in a matrix | ||
+ | 1 2 3 4 | ||
+ | </source> | ||
+ | |||
+ | === Top-heavy fraction as decimal === | ||
+ | <source lang=apl> | ||
+ | (1∧⊢,÷) 1.125 | ||
+ | 9 8 | ||
+ | </source> | ||
+ | |||
+ | === Is it a palindrome? === | ||
+ | <source lang=apl> | ||
+ | (⌽≡⊢)'racecar' | ||
+ | 1 | ||
+ | (⌽≡⊢)'racecat' | ||
+ | 0 | ||
+ | </source> | ||
+ | |||
+ | === Split delimited text === | ||
+ | <source lang=apl> | ||
+ | ','(≠⊆⊢)'comma,delimited,text' | ||
+ | ┌─────┬─────────┬────┐ | ||
+ | │comma│delimited│text│ | ||
+ | └─────┴─────────┴────┘ | ||
+ | ' '(≠⊆⊢)'space delimited text' | ||
+ | ┌─────┬─────────┬────┐ | ||
+ | │space│delimited│text│ | ||
+ | └─────┴─────────┴────┘ | ||
+ | </source> | ||
+ | |||
+ | === Component of a vector in the direction of another vector === | ||
+ | Sometimes a train can make an expression nicely resemble its equivalent definition in [[Comparison_with_traditional_mathematics|traditional mathematical notation]]. As an example, here is a program to compute the component of a vector '''a''' in the direction of another vector '''b'''. | ||
+ | |||
+ | <div style="text-align:center"> | ||
+ | <math>\textbf{a}_\textbf{b} = (\textbf{a}\cdot\hat{\textbf{b}})\hat{\textbf{b}}</math> | ||
+ | </div> | ||
+ | |||
+ | <source lang=apl> | ||
+ | Sqrt ← *∘.5 ⍝ Square root | ||
+ | Norm ← Sqrt+.×⍨ ⍝ 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> | ||
+ | |||
+ | In particular, the definition of <source inline lang=apl>InDirOf</source> resembles the definition in traditional mathematical notation: | ||
+ | <div style="text-align:center"> | ||
+ | {| class="wikitable c" style="margin: 1em auto 1em auto" | ||
+ | ! style="width:33%" | Traditional notation !! style="width:33%" | APL | ||
+ | |- | ||
+ | | <math>|\textbf{b}|</math> || <source lang=apl>(Sqrt+.×⍨) b</source> | ||
+ | |- | ||
+ | | <math>\hat{\textbf{b}} = \frac{\textbf{b}}{|\textbf{b}|}</math> || <source lang=apl>(÷∘Norm⍨) b</source> | ||
+ | |- | ||
+ | | <math>\textbf{a}\cdot\textbf{b}</math> || <source lang=apl>a +.× b</source> | ||
+ | |- | ||
+ | | <math>(\textbf{a}\cdot\hat{\textbf{b}})\hat{\textbf{b}}</math> || <source lang=apl>a (⊢×+.×)∘Unit b</source> | ||
+ | |} | ||
+ | </div> | ||
− | {{APL | + | {{APL features}} |
+ | {{APL syntax}} |
Revision as of 12:00, 9 January 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.
Contents
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 an operator and operand are tacit.
sum ← +/
sum ⍳10
55
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 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 (but not an atop) can be an array:
(A g h) ⍵ ⬄ A g ( h ⍵)
⍺ (A g h) ⍵ ⬄ A g (⍺ 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
1 2 3 (+,-) 4
5 6 7 ¯3 ¯2 ¯1
(2 3⍴0) (+,-) 1
1 1 1 ¯1 ¯1 ¯1
1 1 1 ¯1 ¯1 ¯1
Arithmetic mean
(+⌿÷≢) ⍳10 ⍝ Mean of the first ten integers
5.5
(+⌿÷≢) 5 4⍴⍳4 ⍝ Mean of columns in a matrix
1 2 3 4
Top-heavy fraction as decimal
(1∧⊢,÷) 1.125
9 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 a in the direction of another vector b.
Sqrt ← *∘.5 ⍝ Square root
Norm ← Sqrt+.×⍨ ⍝ 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
In particular, the definition of InDirOf
resembles the definition in traditional mathematical notation:
Traditional notation | APL |
---|---|
(Sqrt+.×⍨) b
| |
(÷∘Norm⍨) b
| |
a +.× b
| |
a (⊢×+.×)∘Unit b
|
APL features [edit] | |
---|---|
Built-ins | Primitive function ∙ Primitive operator ∙ Quad name |
Array model | Shape ∙ Rank ∙ Depth ∙ Bound ∙ Index (Indexing) ∙ Axis ∙ Ravel ∙ Ravel order ∙ Element ∙ Scalar ∙ Vector ∙ Matrix ∙ Simple scalar ∙ Simple array ∙ Nested array ∙ Cell ∙ Major cell ∙ Subarray ∙ Empty array ∙ Prototype |
Data types | Number (Boolean, Complex number) ∙ Character (String) ∙ Box ∙ Namespace |
Concepts and paradigms | Leading axis theory ∙ Scalar extension ∙ Conformability ∙ Scalar function ∙ Pervasion ∙ Glyph ∙ Identity element ∙ Complex floor ∙ Total array ordering |
Errors | LIMIT ERROR ∙ RANK ERROR ∙ SYNTAX ERROR ∙ DOMAIN ERROR ∙ LENGTH ERROR ∙ INDEX ERROR ∙ VALUE ERROR |