Left and Right Tack in Dyalog APL

James HeslipAPLLeave a Comment

Tack (⊣ ⊢) – What is it good for?!

Dyalog APL offers two symbols which do, on the surface, a seemingly pointless task. I’m referring to left tack (⊣) and right tack (⊢). As with most APL functions, they have two uses depending on their number of arguments: monadic, if used only with a right argument; or dyadic if used with a left and a right argument.

First, some background

If used monadically, it’s use is “same”. The interpreter returns the argument:

              ⊣'ABC'
ABC
               ⊢ 1 2 3 4 5
1 2 3 4 5
Seems useless so far, right? The dyadic use doesn’t seem much better on the surface:
      'left' ⊣ 'right'  ⍝ return left argument unchanged
left

       'left' ⊢ 'right'  ⍝ return right argument unchanged
right

So, what’s the point, why have two symbols for something that returns the argument? Well I’m writing this blog as this question has come up a couple of times internally, and I want to make sure the wider community is aware of the use cases also.


Use as a separator between functions to prevent binding

files←'abc.csv' 'foo.txt' 'test2.jpg'  ⍝ a vector of pseudo-random filenames
       'foo.*' ⎕S '\0'⊢files
 foo.txt
        ('foo.*' ⎕S '\0')files
 foo.txt

or...

      (2∘⊥⍣¯1)5
1 0 1
Goes to...
       2⊥⍣¯1⊢5  ⍝ don’t need the jot here either- another bonus.
1 0 1 

Essentially tack acts as a separator, and is great for saving a character in code golf.


Arguments in tacit programming

When programming tacitly, functions like , and like . We can turn a d-fn into a train using this knowledge:

{⍵,⌽⍵}’abc’
 {{⍵},⌽{⍵}}’abc’
 (⊢,⌽∘⊢)’abc’
 (⊢,⌽)’abc’

       (⊢,⌽)'hello' ⍝ myself unchanged, catenated with the reverse of myself.
 helloolleh
       {⍵,⌽⍵}'hello'
 helloolleh

Get the right-most/left-most items from an array

     ⎕←mat←?3 5⍴15
 6  4  2 9 9
13 14  9 5 1
 7 14 10 2 7


     ⊢/mat   ⍝ right-most column
9 1 7
     ⊣/mat   ⍝ left-most column
6 13 7

Still not particularly impressed?

]runtime '⊢/mat' 'mat[;2⊃⍴mat]' 'mat[;≢⍉mat]' ',1↑⊖⍉mat' '⊃¨⌽¨↓mat' -compare
                                                                         
 ⊢/mat        → 1.2E¯7 |    0% ⎕⎕⎕⎕                                     
 mat[;2⊃⍴mat] → 3.6E¯7 | +207% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                            
 mat[;≢⍉mat]  → 3.4E¯7 | +185% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                             
 ,1↑⊖⍉mat     → 3.4E¯7 | +191% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                             
 ⊃¨⌽¨↓mat     → 1.1E¯6 | +835% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ 

Run in Dyalog APL/W-64 Version 17.1.36847 

I came up with a few alternative ways to get the last column from a matrix. None of them can compete in terms of performance. The last one is a tad hyperbolic but proves matrix operations can be far quicker than iterative operations on vectors.


Intermediate execution

With left and right tack, you execute both sides of the function before choosing left or right. In the below example, we benefit from the side effects of running a function and not storing the result:

A_function←{
…
(Guard):  ⍬ ⊣ ⎕FUNTIE tn     ⍝ Failed to find any hits, untie file and return zilde.
…
}

Essentially, we untie the file, then we evaluate zilde. Finally, we decide to return zilde as the tack is facing left. The file gets untied as a result, and we get an opportunity to return the result we want, not the ⎕FUNTIE shy result. (In d-fns, the first result not captured into a variable will be returned, so we’d need to something with the result of ⎕FUNTIE here or it will be the return value).




In conclusion

Tack may seem like a simple function with little place amongst the powerful symbols Dyalog APL offers. I think that it deserves its place, though.

A d-fn as long as {(+⌿⍵)÷(1⌈≢⍵)} can be turned into a train like (+⌿÷1⌈≢). This is a little shorter, and slightly easier to remember in that sense.

Certain idioms like ⊢/ and ⊣/ certainly stand up when indexing, and variants of this can be applied through axis with .

       ⊢⌿mat  ⍝ last row instead of last column
7 14 10 2 7

Lastly, if you’re just a simple lover of code golf, you can always save yourself an extra character by omitting brackets. Unpopular opinion, excessive brackets make your code less readable anyway…


About the Author

James Heslip

APL Team Leader


James is an APL Programmer with a keen interest in mathematics. His love for computing was almost an accident. From a young age he always enjoyed using them- playing video games and such- but it was never considered that anything more would come from it. James originally had plans to pursue a career in finance. More about James.


More from James



Other Posts