SATN-41
Composition and Enclosure

K. E. Iverson
 

Introduction

This technical note treats the new functions, enclose, disclose, and match (denoted by < , > , and ), and three new operators, on, over, and with. In the current release of SHARP APL the domains of these operators are rather restricted; for a discussion of their intended extensions see Bernecky and Iverson [1].

One important related extension not in this release is the application ofto enclosed arrays; as a consequence simple display is not defined, and entry of an expression such as ⎕←<1 2 or <1 2 will produce only the message **array** .

To facilitate the use of examples in discussion we have provided in workspace 1 satn41 the function th which models the proposed definition of the thorn function . It will be used freely in what follows.
 

New Functions

The function match applies to any two arguments to produce a boolean scalar, 0 if the arguments differ in shape or in any element, and 1 otherwise. For example:

      mn←0 3 ∘.+ vn←1 2 3
      mc←2 4⍴vc←'abc'

      mc ≡ vn
0
      vn ≡ vn*1
1
      '' ≡ ⍳0
1

The enclose function applies to any array to produce a result of rank zero; the disclose function is its inverse in the sense that x≡><x . The enclose function is strict in the sense that <x differs from x . For example:

      vn≡<vn 
0
      b≡<b←<mc 
0

Catenation applies to enclosed arguments, but not to one enclosed argument and one simple argument. The extension of other structural and selection functions is based on this extension of catenation. For example:

      vn,<vn
domain error
      vn,<vn
      ^
      ⍴p←(<mn),(<vn),(<mc),(<vc)
4
      th q←2 3⍴p
1 2 31 2 3
4 5 6
abca abc
bcab
1 2 31 2 3
4 5 6
      (0 1 2⌽q)[;1] ≡ (<mn),(<vc),<mn
1

The extension of the ‘comparison’ functionsandis based upon the match function rather than upon equality. Thus:

      (<vn)∊q
1
      p⍳<vn 
2

The remaining primitive functions are not extended to enclosed arrays. Thus vn+<vn and (<vn)+<vn yield domain errors.

The argument rank of the disclose function is zero (i.e., it applies to each of the scalars in its argument), and >a therefore produces an array of shape (⍴a),s where s is the (necessarily common) shape of the results produced by disclosing each element of a . For example:

      ⍴r←>q[1 3;1]
2 2 3
      r
1 2 3
4 5 6

1 2 3
4 5 6
      >q[1;]
domain error
      >q[1;]
      ^
      >q[;1]
domain error
      >q[;1]
      ^

The expressions >q[1;] and >q[;1] yield domain errors for different reasons, the first because the disclosed arrays differ in shape, and the second because they differ in type.

The disclose function is permissive, i.e., when applied to a simple argument (which has no enclosed elements) it behaves as an identity function and yields its argument. Thus:

      r ≡ >r←2 3⍴⍳6
1

The restriction of catenation to apply only to two numeric or to two character arguments prohibited the introduction of ‘non-homogeneous’ arrays; the present extension of catenation to two enclosed arguments only likewise prohibits non-homogeneous arrays. As a consequence, a function which determines whether its argument is simple may be defined rather plainly as follows:

      simple: x ≡ >x←1⍴⍵: O∊⍴⍵: 1

In order to avoid (or at least defer) the introduction of further ‘fill elements’ for the functions take and expand, and the introduction of further dependence on the ‘type’ of an empty argument, we have introduced a nonce error for the overtake or expansion of enclosed arrays. For example:

      3↑<1 2
nonce error
      3↑< 1 2
       ^

Composition Operators

Three new operators have been introduced, called on, over, and with; they are denoted by the symbols  , and ¨ , the first two of which are sometimes given the nicknames paw and hoof.

The dyadic operatorapplies to two functions in the form f⍤g and may be read as f on (the result of) g . The resulting derived function is ambivalent and may therefore be used in the dyadic form x f⍤g y as well as the monadic form f⍤g y .

The monadic case is similar to composition in mathematics, which is defined by the expression f g y . This is the definition adopted here for the case that y is a single argument of the function g  However, for an array of such arguments we insist that the composition is close in the sense that the expression f g is applied individually to each subarray argument of g , and the overall result is formed (as in the example of the disclose function given earlier) by placing the axes of the individual results last.

The significance of close composition may be best appreciated by comparing the results of f⍤g x and f g x in a few examples:

      th fonts←(<2 3⍴'abcdef'),<2 3⍴'123456'
abc123
def456
      >fonts
abc
def

123
456
      ⍉>fonts
a1
d4

b2
e5

c3
f6
      ⍉⍤>fonts
ad
be
cf

14
25
36
      ⍴ >fonts
2 2 3
      ⍴⍤>fonts
2 3
2 3
      , >fonts
abcdef123456
      ,⍤>fonts
abcdef
123456

The dyadic case of the derived function f⍤g is defined similarly by the identity:

      a f⍤g b ←→ (g a) f (g b)

again with the understanding that the composition is close, and that the identity applies strictly only if a and b are single arguments of the function g . For example:


      4 ⍴ + 1 2 3 
1 2 3 1
      4 ⍴⍤+ 1 2 3
1 1 1 1
2 2 2 2
3 3 3 3
      x←<1 2 3
      x×⍤>x 
1 4 9
      x×>x
domain error
      x×>x
      ^

Even with the present restrictions which preclude composition with derived and user-defined functions, the user will find many interesting applications of composition. For examples, ≡⍤⍴ compares the shapes of its arguments; ,⍤< is the pair function that encloses each of its arguments and catenates them; and summing and ‘padding’ of each of the enclosed vectors in an array may be performed as follows:

      m←2 2⍴(<2 3),(<5 7 11),(<⍳0),(<2 3 4 5)

      1 ⊥⍤> m 
5 23 
0 14
      (⌈/,⍴⍤> m) ↑⍤> m
2  3  0  0 
5  7 11  0

0  0  0  0 
2  3  4  5

The operatorprovides another form of close composition in which the dyadic case is defined by the identity:

      a f⍥g b ←→ f a g b

For example:

      n←2 4⍴⌽,m←2 4⍴1 2 3 4 5 6 7 8

      m |⍥- n
7 5 3 1
1 3 5 7

      th r←0 <⍥+ m 
1234 
5678
      r
**array**
      ⍴r
2 4
      >r
1 2 3 4
5 6 7 8

In the derived function f⍥g the function g is used dyadically, whereas in f⍤g it is used monadically; the association of the larger symbol () with the larger valence may prove useful as a mnemonic aid. The monadic cases of the derived functions produced byandare identical, that is:

      f⍤g y ←→ f⍥g y

Except that it is also based on close composition, the monadic case of the derived function f¨g (read as f with g) is equivalent to the mathematical notion of the dual of f with respect to g , that is:

      f¨g y ←→ gi f g y

where gi is the inverse of g.

The importance of the basis in close composition is particularly clear in the case of f¨> (the dual with disclose), because whatever the shapes or ranks of the arguments and results of f , the function f¨> is, in effect, a scalar function. Applied to an argument a , the function f¨>a produces a result of the same shape as a in which each element is the enclose of the result of f applied to the disclose of the corresponding element of a . For example:

      ⍴q
3 2
      th q
1 2 31 2 3
4 5 6
abca abc
bcab
1 2 31 2 3
4 5 6
      ⍴sh←⍴¨>q
3 2
      >sh[;1]
2 3
2 4
2 3
      >sh[;2]
3
3
3

      ⍴w←⍳¨> 2 3⍴1 2 3 4 5 6
2 3
      th w
1      1 2      1 2 3
1 2 3 41 2 3 4 51 2 3 4 5 6

      1 ⊥⍤> w
 1  3  6
10 15 21

      * 1 ⊥⍤> ⍟¨> w
 1   2   5
24 120 720

The definition of the dyadic derived function provided by f¨g is similar to the monadic case. Thus:

      x f¨g y ←→ gi (g x) f (g y)

For example, since the inverses of * , ~ , and < are , ~ , and > , we have a number of identities suggested by the following examples:

      v +¨⍟ v←1 2 3 4
1 4 9 16
      v×v
1 4 9 16
      v ר* v
2 4 6 8
      v+v
2 4 6 8

      a ∨¨~ b←⍉a←2 2⍴0 0 1 1
0 0
0 1
      a ^ b
0 0
0 1
      a ^¨~ b
0 1
1 1
      a∨b
0 1
1 1

      a ,¨< b
0 0
1 1

0 1
0 1
      a ,[⎕io-.5] b
0 0
1 1

0 1
0 1

Restrictions on Arguments of Operators

The utility of the three operators will be greatly enhanced when they are extended in the manner discussed in [1], and are allowed to apply to arrays and to derived and user-defined functions as well as to primitives. In the present release they apply to primitives only, and are further restricted as follows:

a)  The right argument of ¨ (with) is limited to the following functions: ⍉ < > ~ ÷ * ⍟ - +
 
b)  The right argument offor the monadic case, and offor either case may be any scalar primitive, or one of the following: ⍉ < > , ⍋ ⍒ ⍕ ⍴
 
c)  The right argument forfor the dyadic case may be any dyadic scalar primitive.
 
d)  Because the symbols / and \ denote operators, an expression such as 1 0 1/x is the application to x of the monadic derived function 1 0 1/ rather than the application of a dyadic function denoted by / . Since the composition operators apply to functions only, compositions of the form f⍤/ and /⍤f cannot be used.
 
e)  All system functions and the function are excluded from use as arguments to operators.

Bibliography

[1]  K.E. Iverson and R. Bernecky, Operators and Enclosed Arrays, Proceedings, I.P. Sharp Associates 1980 Users Meeting.


First appeared as SHARP APL Technical Note 41, Composition and Enclosure, 1981-06-20.

created:  2009-11-08 22:40
updated:2018-11-28 16:15