Key Operator

General APL language issues

Key Operator

Postby jmosk on Thu Jan 25, 2024 9:48 pm

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
+
User avatar
jmosk
 
Posts: 69
Joined: Thu Jul 18, 2013 5:15 am

Re: Key Operator

Postby petermsiegel on Fri Jan 26, 2024 6:19 pm

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 1
i 4
s 4
p 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

Postby Bob Armstrong on Mon Jan 29, 2024 12:08 am

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 .
User avatar
Bob Armstrong
 
Posts: 27
Joined: Wed Dec 23, 2009 8:41 pm
Location: 39.038681° -105.079070° 2500m

Re: Key Operator

Postby jmosk on Mon Jan 29, 2024 1:29 am

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
+
User avatar
jmosk
 
Posts: 69
Joined: Thu Jul 18, 2013 5:15 am

Re: Key Operator

Postby petermsiegel on Mon Jan 29, 2024 7:46 am

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 4
10
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  => (⍺+⍵)=  10
10

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