Simple examples: Difference between revisions

Jump to navigation Jump to search
513 bytes added ,  22:10, 10 September 2022
m
Text replacement - "</source>" to "</syntaxhighlight>"
m (Text replacement - "<source" to "<syntaxhighlight")
m (Text replacement - "</source>" to "</syntaxhighlight>")
Line 6: Line 6:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       {(+⌿⍵)÷≢⍵}  
       {(+⌿⍵)÷≢⍵}  
</source>
</syntaxhighlight>
It is unnamed: the enclosing braces mark it as a function definition. It can be assigned a name for use later, or used anonymously in a more complex expression.
It is unnamed: the enclosing braces mark it as a function definition. It can be assigned a name for use later, or used anonymously in a more complex expression.


The <syntaxhighlight lang=apl inline>⍵</source> refers to the argument of the function, a list (or 1-dimensional array) of numbers. The <syntaxhighlight lang=apl inline>≢</source> denotes the [[tally]] function, which returns here the length of (number of elements in) the argument <syntaxhighlight lang=apl inline>⍵</source>. The divide symbol <syntaxhighlight lang=apl inline>÷</source> has its usual meaning.
The <syntaxhighlight lang=apl inline>⍵</syntaxhighlight> refers to the argument of the function, a list (or 1-dimensional array) of numbers. The <syntaxhighlight lang=apl inline>≢</syntaxhighlight> denotes the [[tally]] function, which returns here the length of (number of elements in) the argument <syntaxhighlight lang=apl inline>⍵</syntaxhighlight>. The divide symbol <syntaxhighlight lang=apl inline>÷</syntaxhighlight> has its usual meaning.


The parenthesised <syntaxhighlight lang=apl inline>+⌿⍵</source> denotes the sum of all the elements of <syntaxhighlight lang=apl inline>⍵</source>. The <syntaxhighlight lang=apl inline>⌿</source> operator combines with the <syntaxhighlight lang=apl inline>+</source> function: the <syntaxhighlight lang=apl inline>⌿</source> fixes the <syntaxhighlight lang=apl inline>+</source> function between each element of <syntaxhighlight lang=apl inline>⍵</source>, so that
The parenthesised <syntaxhighlight lang=apl inline>+⌿⍵</syntaxhighlight> denotes the sum of all the elements of <syntaxhighlight lang=apl inline>⍵</syntaxhighlight>. The <syntaxhighlight lang=apl inline>⌿</syntaxhighlight> operator combines with the <syntaxhighlight lang=apl inline>+</syntaxhighlight> function: the <syntaxhighlight lang=apl inline>⌿</syntaxhighlight> fixes the <syntaxhighlight lang=apl inline>+</syntaxhighlight> function between each element of <syntaxhighlight lang=apl inline>⍵</syntaxhighlight>, so that
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       +⌿ 1 2 3 4 5 6
       +⌿ 1 2 3 4 5 6
21
21
</source>
</syntaxhighlight>
is the same as
is the same as
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       1+2+3+4+5+6
       1+2+3+4+5+6
21
21
</source>
</syntaxhighlight>
=== Operators ===
=== Operators ===
[[Operator]]s like <syntaxhighlight lang=apl inline>⌿</source> can be used to derive new functions not only from [[primitive function]]s like <syntaxhighlight lang=apl inline>+</source>, but also from defined functions. For example
[[Operator]]s like <syntaxhighlight lang=apl inline>⌿</syntaxhighlight> can be used to derive new functions not only from [[primitive function]]s like <syntaxhighlight lang=apl inline>+</syntaxhighlight>, but also from defined functions. For example
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       {⍺,', ',⍵}⌿
       {⍺,', ',⍵}⌿
</source>
</syntaxhighlight>
will transform a list of strings representing words into a comma-separated list:
will transform a list of strings representing words into a comma-separated list:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
Line 32: Line 32:
│cow, sheep, cat, dog│
│cow, sheep, cat, dog│
└────────────────────┘
└────────────────────┘
</source>
</syntaxhighlight>
So back to our mean example. <syntaxhighlight lang=apl inline>(+⌿⍵)</source> gives the sum of the list, which is then divided by <syntaxhighlight lang=apl inline>≢⍵</source>, the number elements in it.
So back to our mean example. <syntaxhighlight lang=apl inline>(+⌿⍵)</syntaxhighlight> gives the sum of the list, which is then divided by <syntaxhighlight lang=apl inline>≢⍵</syntaxhighlight>, the number elements in it.
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       {(+⌿⍵)÷≢⍵} 3 4.5 7 21
       {(+⌿⍵)÷≢⍵} 3 4.5 7 21
8.875
8.875
</source>
</syntaxhighlight>


=== Tacit programming ===
=== Tacit programming ===
Line 47: Line 47:
       (+⌿÷≢) 3 4.5 7 21
       (+⌿÷≢) 3 4.5 7 21
8.875
8.875
</source>
</syntaxhighlight>


This is a so called 3-train, also known as a ''fork''. It is evaluated like this:
This is a so called 3-train, also known as a ''fork''. It is evaluated like this:
{|
{|
|<syntaxhighlight lang=apl>(+⌿ ÷ ≢) 3 4.5 7 21</source>|| {{←→}} ||<syntaxhighlight lang=apl>(+⌿ 3 4.5 7 21) ÷ (≢ 3 4.5 7 21)</source>
|<syntaxhighlight lang=apl>(+⌿ ÷ ≢) 3 4.5 7 21</syntaxhighlight>|| {{←→}} ||<syntaxhighlight lang=apl>(+⌿ 3 4.5 7 21) ÷ (≢ 3 4.5 7 21)</syntaxhighlight>
|}
|}


Note that <syntaxhighlight lang=apl inline>+⌿</source> is evaluated as a single derived function.
Note that <syntaxhighlight lang=apl inline>+⌿</syntaxhighlight> is evaluated as a single derived function.
The general scheme for monadic 3-trains is the following:
The general scheme for monadic 3-trains is the following:
{|
{|
|<syntaxhighlight lang=apl>(f g h) ⍵</source>|| {{←→}} ||<syntaxhighlight lang=apl>(f ⍵) g (h ⍵)</source>
|<syntaxhighlight lang=apl>(f g h) ⍵</syntaxhighlight>|| {{←→}} ||<syntaxhighlight lang=apl>(f ⍵) g (h ⍵)</syntaxhighlight>
|}
|}


Line 65: Line 65:
APL represents text as character lists (vectors), making many text operations trivial.
APL represents text as character lists (vectors), making many text operations trivial.
=== Split text by delimiter ===
=== Split text by delimiter ===
<syntaxhighlight lang=apl inline>≠</source> gives 1 for true and 0 for false. It [[scalar function|pairs up]] a single element argument with all the elements of the other arguments:
<syntaxhighlight lang=apl inline>≠</syntaxhighlight> gives 1 for true and 0 for false. It [[scalar function|pairs up]] a single element argument with all the elements of the other arguments:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       ','≠'comma,delimited,text'
       ','≠'comma,delimited,text'
1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1
1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1
</source>
</syntaxhighlight>
<syntaxhighlight lang=apl inline>⊢</source> returns its right argument:
<syntaxhighlight lang=apl inline>⊢</syntaxhighlight> returns its right argument:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
           ','⊢'comma,delimited,text'
           ','⊢'comma,delimited,text'
comma,delimited,text
comma,delimited,text
</source>
</syntaxhighlight>
<syntaxhighlight lang=apl inline>⊆</source> returns a list of runs as indicated by runs of 1s, leaving out elements indicated by 0s:
<syntaxhighlight lang=apl inline>⊆</syntaxhighlight> returns a list of runs as indicated by runs of 1s, leaving out elements indicated by 0s:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       1 1 0 1 1 1⊆'Hello!'
       1 1 0 1 1 1⊆'Hello!'
Line 81: Line 81:
│He│lo!│
│He│lo!│
└──┴───┘
└──┴───┘
</source>
</syntaxhighlight>
We use the comparison [[vector]] to [[partition]] the right argument:
We use the comparison [[vector]] to [[partition]] the right argument:


Line 90: Line 90:
│comma│delimited│text│
│comma│delimited│text│
└─────┴─────────┴────┘
└─────┴─────────┴────┘
</source>
</syntaxhighlight>
{{Works in|[[Dyalog APL]]}}
{{Works in|[[Dyalog APL]]}}
Notice that you can read the [[tacit]] function <syntaxhighlight lang=apl inline>≠⊆⊢</source> like an English sentence: ''The inequality partitions the right argument''.
Notice that you can read the [[tacit]] function <syntaxhighlight lang=apl inline>≠⊆⊢</syntaxhighlight> like an English sentence: ''The inequality partitions the right argument''.


Many dialects do not support the above [[tacit]] syntax, and use the [[glyph]] <syntaxhighlight lang=apl inline>⊂</source> for partition [[primitive function]]. In such dialects, the following formulation can be used:
Many dialects do not support the above [[tacit]] syntax, and use the [[glyph]] <syntaxhighlight lang=apl inline>⊂</syntaxhighlight> for partition [[primitive function]]. In such dialects, the following formulation can be used:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       (','≠s)⊂s←'comma,delimited,text'
       (','≠s)⊂s←'comma,delimited,text'
</source>
</syntaxhighlight>
{{Works in|[[APL2]], [[APLX]], [[GNU APL]]}}
{{Works in|[[APL2]], [[APLX]], [[GNU APL]]}}
This assigns the text to the variable <syntaxhighlight lang=apl inline>s</source>, then separately computes the partitioning vector and applies it.
This assigns the text to the variable <syntaxhighlight lang=apl inline>s</syntaxhighlight>, then separately computes the partitioning vector and applies it.


=== Indices of multiple elements ===
=== Indices of multiple elements ===
<syntaxhighlight lang=apl inline>∊</source> gives us a mask for elements (characters) in the left argument that are members of the right argument:
<syntaxhighlight lang=apl inline>∊</syntaxhighlight> gives us a mask for elements (characters) in the left argument that are members of the right argument:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       'mississippi'∊'sp'
       'mississippi'∊'sp'
0 0 1 1 0 1 1 0 1 1 0
0 0 1 1 0 1 1 0 1 1 0
</source>
</syntaxhighlight>
<syntaxhighlight lang=apl inline>⍸</source> gives us the indices where true (1):
<syntaxhighlight lang=apl inline>⍸</syntaxhighlight> gives us the indices where true (1):
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       ⍸'mississippi'∊'sp'
       ⍸'mississippi'∊'sp'
3 4 6 7 9 10
3 4 6 7 9 10
</source>
</syntaxhighlight>
We can combine this into an anonymous infix (dyadic) function:
We can combine this into an anonymous infix (dyadic) function:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       'mississippi' (⍸∊) 'sp'
       'mississippi' (⍸∊) 'sp'
3 4 6 7 9 10
3 4 6 7 9 10
</source>
</syntaxhighlight>
{{Works in|[[Dyalog APL]], [[NARS2000]], [[dzaima/APL]]}}
{{Works in|[[Dyalog APL]], [[NARS2000]], [[dzaima/APL]]}}


Line 127: Line 127:
  1 0 0 0 0 0 0
  1 0 0 0 0 0 0
  0 0 0 0 0 0 0
  0 0 0 0 0 0 0
</source>
</syntaxhighlight>
Then it is simply a matter of performing a sum-reduce <syntaxhighlight lang=apl inline>+/</source> to calculate the total frequency of each character:<ref name="Marshall LambaConf 2019">[[Marshall Lochbaum]] used this example as part of his talk on [[Outer Product]] at LambdaConf 2019.</ref>
Then it is simply a matter of performing a sum-reduce <syntaxhighlight lang=apl inline>+/</syntaxhighlight> to calculate the total frequency of each character:<ref name="Marshall LambaConf 2019">[[Marshall Lochbaum]] used this example as part of his talk on [[Outer Product]] at LambdaConf 2019.</ref>
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       +/ 'abcd' ∘.= 'cabbage'
       +/ 'abcd' ∘.= 'cabbage'
  2 2 1 0
  2 2 1 0
</source>
</syntaxhighlight>


=== Parenthesis nesting level ===
=== Parenthesis nesting level ===
Line 138: Line 138:
What was the one-liner for the nesting level of parentheses? It would take a bit of work to figure out, because at the time of the meeting Perlis described, no APL implementation existed. Two possibilities are explained here.
What was the one-liner for the nesting level of parentheses? It would take a bit of work to figure out, because at the time of the meeting Perlis described, no APL implementation existed. Two possibilities are explained here.
==== Method A ====
==== Method A ====
For this more complex computation, we can expand on the previous example's use of <syntaxhighlight lang=apl inline>∘.=</source>. First we compare all characters to the opening and closing characters;
For this more complex computation, we can expand on the previous example's use of <syntaxhighlight lang=apl inline>∘.=</syntaxhighlight>. First we compare all characters to the opening and closing characters;
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       '()'∘.='plus(square(a),plus(square(b),times(2,plus(a,b)))'
       '()'∘.='plus(square(a),plus(square(b),times(2,plus(a,b)))'
0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
</source>
</syntaxhighlight>
An opening increases the current level, while a closing decreases, so we convert this to ''changes'' (or ''deltas'') by subtracting the bottom row from the top row:
An opening increases the current level, while a closing decreases, so we convert this to ''changes'' (or ''deltas'') by subtracting the bottom row from the top row:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       -⌿'()'∘.='plus(square(a),plus(square(b),times(2,plus(a,b)))'
       -⌿'()'∘.='plus(square(a),plus(square(b),times(2,plus(a,b)))'
0 0 0 0 1 0 0 0 0 0 0 1 0 ¯1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 ¯1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 ¯1 ¯1 ¯1
0 0 0 0 1 0 0 0 0 0 0 1 0 ¯1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 ¯1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 ¯1 ¯1 ¯1
</source>
</syntaxhighlight>
The running sum is what we're looking for:
The running sum is what we're looking for:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       +\-⌿'()'∘.='plus(square(a),plus(square(b),times(2,plus(a,b)))'
       +\-⌿'()'∘.='plus(square(a),plus(square(b),times(2,plus(a,b)))'
0 0 0 0 1 1 1 1 1 1 1 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 2 2 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 3 2 1
0 0 0 0 1 1 1 1 1 1 1 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 2 2 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 3 2 1
</source>
</syntaxhighlight>
{{Works in|all APLs}}
{{Works in|all APLs}}
==== Method B ====
==== Method B ====
Alternatively, we can utilise that if the [[Index Of]] function <syntaxhighlight lang=apl inline>⍳</source> doesn't find what it is looking for, it returns the next index after the last element in the the lookup array:
Alternatively, we can utilise that if the [[Index Of]] function <syntaxhighlight lang=apl inline>⍳</syntaxhighlight> doesn't find what it is looking for, it returns the next index after the last element in the the lookup array:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       'ABBA'⍳'ABC'
       'ABBA'⍳'ABC'
Line 162: Line 162:
       '()'⍳'plus(square(a),plus(square(b),times(2,plus(a,b)))'
       '()'⍳'plus(square(a),plus(square(b),times(2,plus(a,b)))'
3 3 3 3 1 3 3 3 3 3 3 1 3 2 3 3 3 3 3 1 3 3 3 3 3 3 1 3 2 3 3 3 3 3 3 1 3 3 3 3 3 3 1 3 3 3 2 2 2
3 3 3 3 1 3 3 3 3 3 3 1 3 2 3 3 3 3 3 1 3 3 3 3 3 3 1 3 2 3 3 3 3 3 3 1 3 3 3 3 3 3 1 3 3 3 2 2 2
</source>
</syntaxhighlight>
Whenever we have a 1 the parenthesis level increases, and when we have a 2 it decreases. If we have a 3, it remains as-is. We can do this mapping by indexing into these values:
Whenever we have a 1 the parenthesis level increases, and when we have a 2 it decreases. If we have a 3, it remains as-is. We can do this mapping by indexing into these values:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       1 ¯1 0['()'⍳'plus(square(a),plus(square(b),times(2,plus(a,b)))']
       1 ¯1 0['()'⍳'plus(square(a),plus(square(b),times(2,plus(a,b)))']
0 0 0 0 1 0 0 0 0 0 0 1 0 ¯1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 ¯1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 ¯1 ¯1 ¯1
0 0 0 0 1 0 0 0 0 0 0 1 0 ¯1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 ¯1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 ¯1 ¯1 ¯1
</source>
</syntaxhighlight>
The running sum is what we're looking for:
The running sum is what we're looking for:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       +\1 ¯1 0['()'⍳'plus(square(a),plus(square(b),times(2,plus(a,b)))']
       +\1 ¯1 0['()'⍳'plus(square(a),plus(square(b),times(2,plus(a,b)))']
0 0 0 0 1 1 1 1 1 1 1 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 2 2 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 3 2 1
0 0 0 0 1 1 1 1 1 1 1 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 2 2 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 3 2 1
</source>
</syntaxhighlight>
{{Works in|all APLs}}
{{Works in|all APLs}}


Line 189: Line 189:
│MPLFF│⌺  ⌺⌺│
│MPLFF│⌺  ⌺⌺│
└─────┴─────┘
└─────┴─────┘
</source>
</syntaxhighlight>
</p>
</p>
Retrieve elements of the grid where there are spaces in the grille.
Retrieve elements of the grid where there are spaces in the grille.
Line 195: Line 195:
       grid[⍸grille=' ']
       grid[⍸grille=' ']
ILIKEAPL
ILIKEAPL
</source>
</syntaxhighlight>
An alternative method using [[ravel]].
An alternative method using [[ravel]].
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
       (' '=,grille)/,grid
       (' '=,grille)/,grid
ILIKEAPL
ILIKEAPL
</source>
</syntaxhighlight>
===References===
===References===
<references/>
<references/>

Navigation menu