Scalar extension: Difference between revisions

Jump to navigation Jump to search
(Make clearer what's going on)
m (Text replacement - "<source" to "<syntaxhighlight")
Tags: Mobile edit Mobile web edit
Line 3: Line 3:
== History and terminology ==
== History and terminology ==


The concept of scalar extension has been around since [[APL\360]]. An example which extends the scalar <source lang=apl inline>2</source> is:
The concept of scalar extension has been around since [[APL\360]]. An example which extends the scalar <syntaxhighlight lang=apl inline>2</source> is:
<source lang=apl>
<syntaxhighlight lang=apl>
       2 × 1 2 3 4
       2 × 1 2 3 4
2 4 6 8
2 4 6 8
Line 12: Line 12:
The word "extension" applies to scalar extension in two ways: first, a function is extended by making a case which would have been a [[RANK ERROR]] into a valid application. Second, the application works by conceptually extending the scalar to function as though it were an array of higher rank.
The word "extension" applies to scalar extension in two ways: first, a function is extended by making a case which would have been a [[RANK ERROR]] into a valid application. Second, the application works by conceptually extending the scalar to function as though it were an array of higher rank.


Two arrays are said to [[Conformability|conform]] if they have the same shape or at least one can be extended (it is a scalar, or, in langauges with singleton extension, has exactly one element). A pair of conforming arrays defines a single shape which describes how their elements are paired: if neither is a scalar, it is their shared shape; if one is a scalar, it is the other's shape; if both are scalars, it is the [[empty]] vector, <source lang=apl inline>⍬</source> ([[Zilde]]).
Two arrays are said to [[Conformability|conform]] if they have the same shape or at least one can be extended (it is a scalar, or, in langauges with singleton extension, has exactly one element). A pair of conforming arrays defines a single shape which describes how their elements are paired: if neither is a scalar, it is their shared shape; if one is a scalar, it is the other's shape; if both are scalars, it is the [[empty]] vector, <syntaxhighlight lang=apl inline>⍬</source> ([[Zilde]]).


=== Rank extension ===
=== Rank extension ===


The term "scalar extension" is sometimes used to refer to the practice of allowing a scalar when a higher rank is expected. The scalar is treated as an array of the expected minimum rank whose shape is a vector of 1s (that is, a [[singleton]]). For example, <source lang=apl inline>⍳8</source> and <source lang=apl inline>8⍴'a'</source> both produce an array of shape <source lang=apl inline>,8</source> (a vector) even though they were given a shape specification of  <source lang=apl inline>8</source> (a scalar). This type of extension, which differs from ordinary scalar extension in that there is no expected shape and only an expected rank, has also been present since [[APL\360]].
The term "scalar extension" is sometimes used to refer to the practice of allowing a scalar when a higher rank is expected. The scalar is treated as an array of the expected minimum rank whose shape is a vector of 1s (that is, a [[singleton]]). For example, <syntaxhighlight lang=apl inline>⍳8</source> and <syntaxhighlight lang=apl inline>8⍴'a'</source> both produce an array of shape <syntaxhighlight lang=apl inline>,8</source> (a vector) even though they were given a shape specification of  <syntaxhighlight lang=apl inline>8</source> (a scalar). This type of extension, which differs from ordinary scalar extension in that there is no expected shape and only an expected rank, has also been present since [[APL\360]].


=== Singleton extension ===
=== Singleton extension ===


Some APLs, such as [[Dyalog APL]], treat arrays with one element ([[singleton]]s) as scalars for the purposes of scalar extension. This practice is referred to as "singleton extension". For example,
Some APLs, such as [[Dyalog APL]], treat arrays with one element ([[singleton]]s) as scalars for the purposes of scalar extension. This practice is referred to as "singleton extension". For example,
<source lang=apl>
<syntaxhighlight lang=apl>
       (1 1⍴5) + 10 20
       (1 1⍴5) + 10 20
15 25
15 25
Line 39: Line 39:


Dyadic [[scalar functions]] and the [[Each]] operator use scalar extension to pair their arguments:
Dyadic [[scalar functions]] and the [[Each]] operator use scalar extension to pair their arguments:
<source lang=apl>
<syntaxhighlight lang=apl>
       1 2 3 4 * 2
       1 2 3 4 * 2
1 4 9 16
1 4 9 16
Line 49: Line 49:




[[Replicate]] and [[Partitioned Enclose]] (and also [[Partition]], but this is less useful, as it is equivalent to <source lang=apl inline>,⊂</source> or  <source lang=apl inline>{0⍴⊂0⍴⍵}</source>) extend a scalar left argument to apply to each column of the right argument:
[[Replicate]] and [[Partitioned Enclose]] (and also [[Partition]], but this is less useful, as it is equivalent to <syntaxhighlight lang=apl inline>,⊂</source> or  <syntaxhighlight lang=apl inline>{0⍴⊂0⍴⍵}</source>) extend a scalar left argument to apply to each column of the right argument:
<source lang=apl>
<syntaxhighlight lang=apl>
       2/'abc'
       2/'abc'
aabbcc
aabbcc
Line 60: Line 60:


[[Decode]] uses extends a single radix left argument to apply to all digit values in the right argument:
[[Decode]] uses extends a single radix left argument to apply to all digit values in the right argument:
<source lang=apl>
<syntaxhighlight lang=apl>
       2⊥1 0 1
       2⊥1 0 1
5
5
Line 66: Line 66:


[[APL2]] and [[Dyalog APL]] use a variant of singleton extension when the selected axis of the right argument has length one: each element along that axis is reused for every element of the left argument.
[[APL2]] and [[Dyalog APL]] use a variant of singleton extension when the selected axis of the right argument has length one: each element along that axis is reused for every element of the left argument.
<source lang=apl>
<syntaxhighlight lang=apl>
       ⍴ 2 ¯3 /[2] 7 1 8⍴⍳56
       ⍴ 2 ¯3 /[2] 7 1 8⍴⍳56
7 5 8
7 5 8
Line 74: Line 74:


In languages which allow a vector left argument to [[Rotate]], the behavior with a scalar left argument follows from scalar extension. In the following example a length-2 vector could be used to rotate each row by a different amount. A scalar rotates both rows by the same amount.
In languages which allow a vector left argument to [[Rotate]], the behavior with a scalar left argument follows from scalar extension. In the following example a length-2 vector could be used to rotate each row by a different amount. A scalar rotates both rows by the same amount.
<source lang=apl>
<syntaxhighlight lang=apl>
       3⌽2 6⍴'extendscalar'
       3⌽2 6⍴'extendscalar'
endext
endext
Line 83: Line 83:


A common problem is pairing up each [[element]] of one [[argument]] with all the elements of another argument. Because of scalar extension, [[enclose|making one argument a scalar]] accomplishes this:
A common problem is pairing up each [[element]] of one [[argument]] with all the elements of another argument. Because of scalar extension, [[enclose|making one argument a scalar]] accomplishes this:
<source lang=apl>
<syntaxhighlight lang=apl>
       1 2 3,¨⊂100 200
       1 2 3,¨⊂100 200
┌─────────┬─────────┬─────────┐
┌─────────┬─────────┬─────────┐
Line 94: Line 94:
</source>
</source>
For [[scalar function]]s, explicit use of the [[Each]] operator is unnecessary:
For [[scalar function]]s, explicit use of the [[Each]] operator is unnecessary:
<source lang=apl>
<syntaxhighlight lang=apl>
       1 2 3+⊂100 200
       1 2 3+⊂100 200
┌───────┬───────┬───────┐
┌───────┬───────┬───────┐
Line 105: Line 105:
</source>
</source>
[[Bind]]ing one argument to the function also works, but this always requires the Each operator:
[[Bind]]ing one argument to the function also works, but this always requires the Each operator:
<source lang=apl>
<syntaxhighlight lang=apl>
       1 2 3∘,¨100 200
       1 2 3∘,¨100 200
┌─────────┬─────────┐
┌─────────┬─────────┐