## Key Operator

General APL language issues

### Key Operator

In
{⍺⍵}⌸'Mississippi'

⍵ is 'Mississippi'

what is the meaning of ⍺ ?

The result is:
┌─┬────────┐
│M│1 │
├─┼────────┤
│i│2 5 8 11│
├─┼────────┤
│s│3 4 6 7 │
├─┼────────┤
│p│9 10 │
└─┴────────┘

Can ⌸ only be used in context with ⍺ and ⍵ and never as some other X ⌸ Y
+←--------------------------------------------------------------→
+ Jay Moskowitz
+←--------------------------------------------------------------→
+ http://www.linkedin.com/in/jay-moskowitz-5745b83
+

jmosk

Posts: 69
Joined: Thu Jul 18, 2013 5:15 am

### Re: Key Operator

Let's do it as
Code: Select all
`     {⍺⍵}⌸t←'Mississippi'`

We've used the variable t, so it’s easier to see which right argument goes with what.
Then
t is 'Mississippi'. t is the right argument to ⌸ (key), but not the right argument within the left operand {⍺⍵} to key;
in operand {⍺⍵} is each unique letter in t in turn, i.e. each letter in (∪t); and
in operand {⍺⍵} is a vector (enclosed list) containing the indices showing where that unique letter occurred in t.
Try this:
Code: Select all
`     {('⍺=',⍺)('⍵=' ⍵)}⌸t←'Mississippi' ⍺=M   ⍵=  1        ⍺=i   ⍵=  2 5 8 11 ⍺=s   ⍵=  3 4 6 7  ⍺=p   ⍵=  9 10  `

Note that I referenced both ⍺ and ⍵ in the left operand to key, but I could just as well have omitted either one. A common thing to do is to use ≢⍵ to tally (count) the number of references to each unique element in turn, like this:
Code: Select all
`     {⍺ (≢⍵)}⌸t←'Mississippi'M 1i 4s 4p 2`

This says, for example, that s occurs 4 times in 'Mississippi'.

Note also that these both produce the unique elements in their right arguments:
Code: Select all
`      Lk← ⊣⌸   ⍝ {⍺}⌸      U← ∪      Lk 'ccattss'cats      U 'ccattss'cats`
petermsiegel

Posts: 159
Joined: Thu Nov 11, 2010 11:04 pm

### Re: Key Operator

I rarely comment , being an ` outsider but evolving from the same Iversonian tradition .
Everybody forever had their ` unique verb . Sometime along the way Iverson named it ` nub . Whitney's K was the first place I had ` nub , his name ` range , and ` group .

In CoSy the equivalents are defined in https://cosy.com/4thCoSy/Code/CoSy/CoSy.f relatively recently . They're small enough I'll include the code :
Code: Select all
`| return unique items .  Like  K's  ' ? : nubb 1p> R@ ['] where 'R ,/ R@ rho iota =i 1P> ; | bool of 1st occurrences: nubx nubb & ;    | indices of 1st occurrences : nub 1p> dup nubx at 1P> ;    | unique items .: nnub 1p> dup nubb 0=i & at 1P> ; | redundants | Group items by uniques | see Wed.Oct,20191002 | https://youtu.be/fxx9kS_seXk |: grpib 1p> nub R@ ,/ ' =i 'L 1P> ;    | group integer bool: grpix grpib ' & 'm ;        | group integer index: grpcx >a> nub a> swap  ' conn 'R  ;   | 20191008 | ` nubgrp optimized merge . Eliminates redundant call of ' nub : nubgrpib 1p> nub >a> R@ ,/ ' =i 'L a> swap ,L 1P> ; | nub & group integer bool| and uses CoSy's access to addresses using ' ix rather than just ' i@ and ' i!| to optimally replace just the second item in the result from ' nubgrpib: nubgrpix nubgrpib >a> 1 ix dup @ ' & 'm swap rplc a> ;  : nubgrpcx >a> nub a> swap >a> ' conn 'R a> swap ,L  ;    | 20210625 | /\ | Takes list . Returns 2 item list of `( nub grp )` . `

I've yet to add a layer of ` genericity so different names for different types .
You'll note several uses of ` operators , eg: Arthur's eachLeft , 'L , where the verb to be applied is simply passed using Chuck Moore's brilliant ` ' which puts the address of the next word on the stack rather than executing it .

In any case here's the ` mississippi example in CoSy RPN .
Code: Select all
`    ` mississippi nubgrpcx(  misp (   0   1 4 7 10   2 3 5 6   8 9  ) )`

a list of 2 lists . To format it a little nicer :
Code: Select all
` R0 fmttbl|(  m  | 0          i  | 1 4 7 10   s  | 2 3 5 6    p  | 8 9        )`

You see I'm into having a rich vocabulary of variants of a given notion , particularly bool , index , & value , and their complements , rather than complex syntax . I feel most of the APL level power comes from the vocabulary .

Bob Armstrong

Posts: 27
Joined: Wed Dec 23, 2009 8:41 pm
Location: 39.038681° -105.079070° 2500m

### Re: Key Operator

What is confusing here is that 4 {⍺,⍵} 5 associates 4 with ⍺ and 5 with ⍵. Yet there does not seem to be an explicate ⍺ defined in {⍺⍵}⌸'Mississippi'. It is not of the form X {F} Y. Yet when executed it seems that ⍺ does end up taking on the value of the keys in Mississippi. So in this case it seems ⍺ is being assigned a value rather than carrying a value into the function. This seems confusing.

Are there other functions like this where there does not seem to be an explicit ⍺ yet a value is taken on during execution? I do understand that one can explicitly set ⍺ to a value inside a function to set it as a default value if not explicitly defined in the call to the function. Maybe that is how to think of the ⌸ function, as one that sets a default value for ⍺.
+←--------------------------------------------------------------→
+ Jay Moskowitz
+←--------------------------------------------------------------→
+ http://www.linkedin.com/in/jay-moskowitz-5745b83
+

jmosk

Posts: 69
Joined: Thu Jul 18, 2013 5:15 am

### Re: Key Operator

The thing to note is that an operator is different from a function, since it might take functions as its operands (or, in this example, its single operand ⍺⍺), as well as arguments (in this example, ⍵). Rather than read what's below (TLDR), you might want to look at the Legrand book https://www.dyalog.com/mastering-dyalog-apl.htm. It's a bit dated, but explains things like functions and operators rather well.

For the case at hand...
What's happening here is that we have an operator, Key (⌸), which takes a left operand, (here) a function, and a right argument, the item whose major elements (items) are being evaluated. (I simplify: Key can also take a left argument, but let's pretend otherwise for now).

In our case, Key calls the operand {⍺ ⍵} many times, once for each unique element in the right argument. On each call, Key sets ⍺ to be each unique element in turn-- one at a time, mind you-- and ⍵ to be a list of indices showing where that item occurred in the ORIGINAL array (the right argument to Key itself).

Operators often call their operand(s) with arguments-- and -- which are related to, but precisely NOT the same as their own (operator) arguments.

A simple case would be
Code: Select all
`      +/1 2 3 410`
where + is an OPERAND of reduce / an operator. Reduce appears to apply operand + between all the elements of its right argument. You can see what's really going on by concocting a verbose equivalent:
Code: Select all
`     {⎕←('⍺=',⍺)'+'('⍵=',⍵),'=> (⍺+⍵)='(⍺+⍵) ⋄ ⍺+⍵}/1 2 3 4 ⍺= 3 + ⍵= 4  => (⍺+⍵)=  7 ⍺= 2 + ⍵= 7  => (⍺+⍵)=  9 ⍺= 1 + ⍵= 9  => (⍺+⍵)=  1010`

So you can see that the operand {⎕←... ⋄ ⍺+⍵} is called several (N-1) times "by" Reduce / with arguments related to 1 2 3 4, but obviously doled out according to the semantics of reduction.

Cheers!
petermsiegel

Posts: 159
Joined: Thu Nov 11, 2010 11:04 pm

Return to Language

### Who is online

Users browsing this forum: No registered users and 1 guest