Simple examples: Difference between revisions

Jump to navigation Jump to search
3,061 bytes added ,  05:49, 26 August 2020
m
Miraheze>RikedyP
(24 intermediate revisions by 7 users not shown)
Line 1: Line 1:
This page contains examples that show APL's strengths. The examples require minimal background and have no special dependencies.
This page contains examples that show APL's strengths. The examples require minimal background and have no special dependencies. If these examples are too simple for you, have a look at our [[advanced examples]].
 
== Longer examples ==
A list of more involved examples.
[[Category: Lists]]
 
* [[APL Wiki logo]]
 
* [[Convex Hull]]
 
* [[Conway's Game of Life]]
 
* [[Ranking poker hands]]


== Arithmetic mean ==
== Arithmetic mean ==
Line 17: Line 5:
Here is an APL program to calculate the average (arithmetic mean) of a list of numbers, written as a [[dfn]]:
Here is an APL program to calculate the average (arithmetic mean) of a list of numbers, written as a [[dfn]]:
<source lang=apl>
<source lang=apl>
       {(+⌿ω)÷≢ω}  
       {(+⌿⍵)÷≢⍵}  
</source>
</source>
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 <source lang=apl inline>ω</source> refers to the argument of the function, a list (or 1-dimensional array) of numbers. The <source lang=apl inline>≢</source> denotes the [[tally]] function, which returns here the length of (number of elements in) the argument <source lang=apl inline>ω</source>. The divide symbol <source lang=apl inline>÷</source> has its usual meaning.
The <source lang=apl inline></source> refers to the argument of the function, a list (or 1-dimensional array) of numbers. The <source lang=apl inline>≢</source> denotes the [[tally]] function, which returns here the length of (number of elements in) the argument <source lang=apl inline></source>. The divide symbol <source lang=apl inline>÷</source> has its usual meaning.


The parenthesised <source lang=apl inline>+⌿ω</source> denotes the sum of all the elements of <source lang=apl inline>ω</source>. The <source lang=apl inline>⌿</source> operator combines with the <source lang=apl inline>+</source> function: the <source lang=apl inline>⌿</source> fixes the <source lang=apl inline>+</source> function between each element of <source lang=apl inline>ω</source>, so that
The parenthesised <source lang=apl inline>+⌿⍵</source> denotes the sum of all the elements of <source lang=apl inline></source>. The <source lang=apl inline>⌿</source> operator combines with the <source lang=apl inline>+</source> function: the <source lang=apl inline>⌿</source> fixes the <source lang=apl inline>+</source> function between each element of <source lang=apl inline></source>, so that
<source lang=apl>
<source lang=apl>
       +⌿ 1 2 3 4 5 6
       +⌿ 1 2 3 4 5 6
Line 36: Line 24:
[[Operator]]s like <source lang=apl inline>⌿</source> can be used to derive new functions not only from [[primitive function]]s like <source lang=apl inline>+</source>, but also from defined functions. For example
[[Operator]]s like <source lang=apl inline>⌿</source> can be used to derive new functions not only from [[primitive function]]s like <source lang=apl inline>+</source>, but also from defined functions. For example
<source lang=apl>
<source lang=apl>
       {α,', ',ω}⌿
       {,', ',}⌿
</source>
</source>
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:
<source lang=apl>
<source lang=apl>
    {⍺,', ',⍵}⌿'cow' 'sheep' 'cat' 'dog'
      {⍺,', ',⍵}⌿'cow' 'sheep' 'cat' 'dog'
┌────────────────────┐
┌────────────────────┐
│cow, sheep, cat, dog│
│cow, sheep, cat, dog│
└────────────────────┘
└────────────────────┘
</source>
</source>
So back to our mean example. <source lang=apl inline>(+)</source> gives the sum of the list, which is then divided by <source lang=apl inline>ρω</source>, the number of its elements.
So back to our mean example. <source lang=apl inline>(+⌿⍵)</source> gives the sum of the list, which is then divided by <source lang=apl inline>≢⍵</source>, the number elements in it.
<source lang=apl>
<source lang=apl>
       {(+)÷ρω} 3 4.5 7 21
       {(+⌿⍵)÷≢⍵} 3 4.5 7 21
8.875
8.875
</source>
</source>


=== Tacit programming ===
=== Tacit programming ===
{{Main|Tacit programming}}


In APL’s tacit definition, no braces are needed to mark the definition of a function: primitive functions just combine in a way that enables us to omit any reference to the function arguments — hence ''tacit''. Here is the same calculation written tacitly:
In APL’s tacit definition, no braces are needed to mark the definition of a function: primitive functions just combine in a way that enables us to omit any reference to the function arguments — hence ''tacit''. Here is the same calculation written tacitly:
Line 59: Line 49:
</source>
</source>


The operator <source lang=apl inline>/</source> can also be used to modify the <source lang=apl inline>(+⌿÷≢)</source> function to produce a moving average.
This is a so called 3-train, also known as a ''fork''. It is evaluated like this:
<source lang=apl>
{|
      2 (+⌿÷≢)/ 3 4.5 7 21
|<source lang=apl>(+⌿ ÷ ≢) 3 4.5 7 21</source>|| {{←→}} ||<source lang=apl>(+3 4.5 7 21) ÷ (≢ 3 4.5 7 21)</source>
3.75 5.75 14
|}
</source>
 
or, more verbosely
Note that <source lang=apl inline>+⌿</source> is evaluated as a single derived function.
<source lang=apl>
The general scheme for monadic 3-trains is the following:
      ave ← +⌿÷≢
{|
      ave 3 4.5 7 21
|<source lang=apl>(f g h) ⍵</source>|| {{←→}} ||<source lang=apl>(f ⍵) g (h ⍵)</source>
8.875
|}
      mave ← ave/
 
      2 mave 3 4.5 7 21
But other types of [[Tacit programming#Trains|trains]] are also possible.
3.75 5.75 14
</source>


==Text processing==
==Text processing==
Line 104: Line 92:
</source>
</source>
{{Works in|[[Dyalog APL]]}}
{{Works in|[[Dyalog APL]]}}
Notice of you can read the [[tacit]] function <source lang=apl inline>≠⊆⊢</source> like an English sentence: ''The inequality partitions the right argument''.
Notice that you can read the [[tacit]] function <source lang=apl inline>≠⊆⊢</source> like an English sentence: ''The inequality partitions the right argument''.
 
=== Indices of multiple elements ===
=== Indices of multiple elements ===
<source lang=apl inline>∊</source> gives us a mask for elements (characters) in the left argument that are members of the right argument:
<source lang=apl inline>∊</source> gives us a mask for elements (characters) in the left argument that are members of the right argument:
Line 122: Line 111:
</source>
</source>
{{Works in|[[Dyalog APL]], [[NARS2000]], [[dzaima/APL]]}}
{{Works in|[[Dyalog APL]], [[NARS2000]], [[dzaima/APL]]}}
=== Frequency of characters in a string ===
The [[Outer Product]] allows for an intuitive way to compute the occurrence of characters at a given location in a string:
<source lang=apl>
      'abcd' ∘.= 'cabbage'
0 1 0 0 1 0 0
0 0 1 1 0 0 0
1 0 0 0 0 0 0
0 0 0 0 0 0 0
</source>
Then it is simply a matter of performing a sum-reduce <source 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>
<source lang=apl>
      +/ 'abcd' ∘.= 'cabbage'
2 2 1 0
</source>


=== Parenthesis nesting level ===
=== Parenthesis nesting level ===
First we compare all characters to the opening and closing characters;
{{quote | "Ken was showing some slides — and one of his slides had something on it that I was later to learn was an APL one-liner. And he tossed this off as an example of the expressiveness of the APL notation. I believe the one-liner was one of the standard ones for indicating the nesting level of the parentheses in an algebraic expression. But the one-liner was very short — ten characters, something like that — and having been involved with programming things like that for a long time and realizing that it took a reasonable amount of code to do, I looked at it and said, “My God, there must be something in this language.”"|[[Alan Perlis]]. ''[https://www.jsoftware.com/papers/perlis78.htm Almost Perfect Artifacts Improve only in Small Ways: APL is more French than English]'' at [[APL78]].}}
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 ====
For this more complex computation, we can expand on the previous example's use of <source lang=apl inline>∘.=</source>. First we compare all characters to the opening and closing characters;
<source lang=apl>
<source lang=apl>
       '()'∘.='plus(square(a),plus(square(b),times(2,plus(a,b)))'
       '()'∘.='plus(square(a),plus(square(b),times(2,plus(a,b)))'
Line 138: Line 145:
<source lang=apl>
<source 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
</source>
{{Works in|all APLs}}
==== Method B ====
Alternatively, we can utilise that if the [[Index Of]] function <source 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:
<source lang=apl>
      'ABBA'⍳'ABC'
1 2 5
      '()'⍳'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
</source>
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:
<source lang=apl>
      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
</source>
The running sum is what we're looking for:
<source lang=apl>
      +\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>
</source>
Line 143: Line 169:


=== Grille cypher ===
=== Grille cypher ===
A [https://en.wikipedia.org/wiki/Grille_(cryptography) grille] is a 500 year old method for encrypting messages.
A [[wikipedia:grille (cryptography)|grille]] is a 500 year old method for encrypting messages.
[[File:Grille.png|none|500px|frameless|left|The application of a grille cypher]]
[[File:Grille.png|none|500px|frameless|The application of a grille cypher]]
<p>
<p>
Represent both the grid of letters and the grille as character matrices.
Represent both the grid of letters and the grille as character matrices.
Line 168: Line 194:
ILIKEAPL
ILIKEAPL
</source>
</source>
===References===
<references/>
{{APL development}}


{{APL programming language}}
[[Category:Examples]]

Navigation menu