Conversation started Nov 8, 2017 at 18:30.
Nov 8, 2017 18:30
Welcome to the APL learning session
To contribute in tonight's APL learning session without having 20 SE rep, send an email to adam@
Last time we went through some operators. I'll continue with more operators if nobody protests.
Sounds good
Isn't like every built in an operator though?
@Pavel No, in APL symbols are called functions or operators depending on their nature.
an operator generates a function
Before we begin, let me introduce you to our very clever chat bot:
#help
Nov 8, 2017 18:33
@EriktheOutgolfer Ah
#about
@Adám You can evaluate an APL expression by typing it into chat prefixed by ⍞←. Use ⎕← instead for boxed display and multi-line results. Do not use markdown. Commands: #lb for language bar, #help for table of language elements, #docs for full documentation, #ref for PDF reference card.
⎕←'test'
@Potato44
test
Nov 8, 2017 18:34
If you do not have an APL keyboard layout (or can't remember the location of a symbol) you can copy and paste from:
#lb
@Adám ← +-×÷*⍟⌹○!? |⌈⌊⊥⊤⊣⊢ =≠≤<>≥≡≢ ∨∧⍲⍱ ↑↓⊂⊃⊆⌷⍋⍒ ⍳⍸∊⍷∪∩~ /\⌿⍀ ,⍪⍴⌽⊖⍉ ¨⍨⍣.∘⍤@ ⍞⎕⍠⌸⌺⌶⍎⍕ ⋄⍝→⍵⍺∇& ¯⍬
@Adám waves
let me know if the bot explodes
@ThomasWard OK.
i'm working on the host node the server running the bot now is on right now, so... :P
Is there a range builtin?
Nov 8, 2017 18:36
@cairdcoinheringaahing Yes:
⍞←⍳10
@Adám 1 2 3 4 5 6 7 8 9 10
Let's do the "Jot" operator.
That's the function composition one, right?
Nov 8, 2017 18:37
comes from function composition, like f(g(x)) can be written f∘g(x) (in mathematics).
So too in APL, if f and g are functions, then f∘g x is the same as f g x (APL doesn't need parentheses for function application).
This is of course not very interesting. However, APL also has dyadic (infix) functions.
A f∘g B is A f g B
or f(A, g(B))
@EriktheOutgolfer Yes, but that isn't APL syntax for a dyadic function f.
sure
I just clarified
Both of these are very important when writing tacit APL code.
E.g. If we want to write a function which adds its left argument to the reciprocal (monadic ÷) of its right argument, it can be written as f ← +∘÷
@Adám Since ÷ can have multiple be dyadic or monadic, how is the arity resolved?
Nov 8, 2017 18:44
The golden ratio (phi) can be calculated with the continued fraction
@Potato44 If there is an array on its left it is dyadic.
@Adám I'm getting Image not found
@Adám he meant ÷...
@Pavel https://snag.gy/qWV3fd.jpg
@EriktheOutgolfer What?
@Potato44 So 2÷3 is division and ÷3 is reciprocal.
@Adám he probably meant how is the arity of ÷ resolved within composition
@Adám Thanks
Nov 8, 2017 18:47
I confused myself because where you have it adding right arguments reciprocal to the left argument. I misread it as adding its reciprcal to itself
What if I compose two dyadic functions together?
@Potato44 Ah, so in A f∘g B f is always dyadic, and g is always monadic.
I understand how it works since i read ir properly
@Adám is there a modulo builtin or do you have to implement it yourself?
@Pavel Functions are usually ambivalent and can be called monadically or dyadically. will make sure to call them the right way.
Nov 8, 2017 18:48
ಠ_ಠ I can't read
@cairdcoinheringaahing | but the arguments are reversed of what you might expect (opposite of ÷).
@cairdcoinheringaahing |⍨
where will reverse the arguments to what you'd expect from other languages
… So phi is 1+÷1+÷1+÷…
We can insert the same function between elements of a list with the / operator, e.g.
@EriktheOutgolfer = Jelly's @?
⍞←+/ 1 1 2 3
Nov 8, 2017 18:50
@Adám 7
I guess we are going to approximate it by reducing with a composition?
@cairdcoinheringaahing A g⍨ B == B g A
@Potato44 Yes, we want to insert …+÷…, but that isn't a single function. However, we can use +∘÷:
for monadic functions it's something else
⍞←+∘÷/1 1 1 1 1 1 1 1 1 1
Nov 8, 2017 18:51
@Adám 1.618181818
X⍴Y reshapes Y into shape X:
⍞←+∘÷/1000⍴1
@Adám 1.618033989
That's phi ^
That's really all there is to say about . However a warning is in place: (f g)Y is the same as f∘g Y which may fool you into thinking that X(f g)Y is the same as X f∘g Y. However, they are not the same!
well, you can make a parameterized function that takes a number being precision (although apl has kinda small float size): +∘÷/⍴∘1
@EriktheOutgolfer Nice, but you can actually switch to 128 bit decimal floats:
Nov 8, 2017 18:55
@Adám yeah X(f g)Y is f(X, g(X, Y)) right?
⍞←÷7⊣⎕PP←34⊣⎕FR←1287
@Adám 0.1428571428571428571428571428571429
@EriktheOutgolfer No, X(f g)Y is f(g(X, Y))
there are a lot of train rules...
@Adám This is getting into the rules for tacit functions, right?
Nov 8, 2017 18:58
And a nice golfing trick using is having the left operand (which we've called f) be . This allows using a monadic function on the right argument while ignoring the left argument.
This is equivalent to the more intuitive (f⊢)
@Adám why does TryAPL not like this?
⊢ is ID the identity function, or is that ⊣?
@cairdcoinheringaahing Because that would prompt for input on the server :-)
@Potato44 Both are. is the identity of the right argument, and is of the left.
(Monadically they are the same, though.)
@Adám So... they give us a command, and then refuse to let us run that command?
@cairdcoinheringaahing TryAPL is not a full APL for technical reasons. The Primer still has a full APL reference. does work on TIO.
Are we (relatively) clear about ? Questions?
Nov 8, 2017 19:04
@Adám I still don't understand the interface with TIO. Why do you enter code into the Input section?
um tio doesn't really work like that with apl
@cairdcoinheringaahing Input is the immediate execution mode. Each line will get executed by itself. You can also use it to "respond" to and prompts. The Code field will let you define multi-line functions and objects.
Can we continue with the @ operator?
(Note: TryAPL is running an old version of APL which doesn't have @. TIO's APL does have @)
ooh, new command
Nov 8, 2017 19:10
The @ "At" operator does exactly what it says. What's on its left gets done at the position indicated by its right operand.
⍞←('X'@2 5) 'Hello'
@Adám HXllX
so is it 'apply at index'?
So we put an X at positions 2 and 5 (APL is 1-indexed by default – you can change to 0-indexing if you want)
@Potato44 Yes. Well, at position. You'll see…
We can also give an array which matches the selected elements:
⍞←('XY'@2 5) 'Hello'
@Adám HXllY
@Adám sorry to interrupt again, but can you tell me why this is a syntax error?
Nov 8, 2017 19:13
@cairdcoinheringaahing Sure works by me.
@cairdcoinheringaahing there's no error in there
@cairdcoinheringaahing Ah, try )erase abs first.
@Adám Ah, now it works. Thanks!
Is abs a builtin?
there are no "reserved words" in apl
@cairdcoinheringaahing To prevent losing your code and data, APL will not let you use the name of a function for data or vice versa without you explicitly erasing them first.
Nov 8, 2017 19:16
@Adám that doesn't happen for me
@EriktheOutgolfer TIO link or it did happen :-)
huh
      abs ← ×∘×
      abs ← ×∘+
      abs
×∘+
(I know the functions are wrong :p)
@Adám
@EriktheOutgolfer name of a function for data or vice versa
So, is the only way to do absolute value square then square root?
Nov 8, 2017 19:18
@EriktheOutgolfer (These are really useful function in complex math)
@cairdcoinheringaahing No, monadic | because in math that's |x| but APL harmonises all monadic functions to be prefix.
> Magnitude (Modulus)
That has no indication for absolute value
I;m looking at those docs for the forking rules and they are composing with an array like
⍳∘1
what does tha mean?
@cairdcoinheringaahing looks like tryapl has got it wrong
"Magnitude" is absolute value
@cairdcoinheringaahing The absolute value is the magnitude (ignoring the sign). It has to be called that due to complex numbers.
@Potato44 This means the dyadic function but "pre-populate" the right argument with 1. So that gives you a new monadic (prefix) function: (⍳∘1)x is x⍳1 (which is the index of the leftmost 1.
@Adám (o_o coincidence?)
Nov 8, 2017 19:22
@Potato44 And right, in discussing I completely forgot mentioning composing with arguments:
g←f∘A where f is a dyadic function and A an array (any data) gives g, a new monadic function which calculates x f A.
@Adám so it is partial application, can you partially apply to the left arguent?
@Potato44 Similarly g←A∘f makes g a function which calculates A f x
@Adám noteworthy: B(f∘A) isn't valid syntax, (f∘A)B is
@EriktheOutgolfer Yes, all monadic functions are prefix.
Btw, for operators you can "curry" their right operand. So WithTwo←∘2 is a new monadic operator which can in turn modify a dyadic function to become monadic (using 2 as its right argument). E.g. + WithTwo 3 will give 5.
This is especially useful with the f⍣n "power operator" which applies its f operand functionn times.
So twice←⍣2 is an operator which applies a function twice. E.g. 2+twice 3 is 7.
@Adám and this can be very useful:
Nov 8, 2017 19:30
And inv←⍣¯1 is an operator which will apply a function -1 times, i.e. applies the inverse of that function.
inverse ← ⍣¯1
duh ninja :p
I'm guessing not, but do all functions have inverses?
@Potato44 No, but surprisingly many do. And if you derive new functions tacitly using only operators and invertible functions, then the resulting function can also (generally) be inverted automatically.
@Potato44 no
an example would be monadic | (magnitude)
@Potato44 Even structural functions can be inverted:
⍞←('x'∘,⍣¯1) 'x'∘, 'abc'
Nov 8, 2017 19:32
@Adám abc
where {|⍣¯1⊢⍵} is an identity function which throws if the argument isn't a positive integer
structural?
So what happened here is that we applied the function 'x'∘, which prepends the letter x, and then we applied its inverse, which removes an x from the left side.
@Potato44 Yes, e.g. drops elements and its inverse pads elements (it will use the default fill element):
⍞←3↓⍣¯1⊢'hello'
@Adám    hello
So I applied the inverse of dropping the first three characters, i.e. pad three characters (spaces) on the left.
Nov 8, 2017 19:36
@Adám is that hardcoded in the interpreter or is there magic in the interpreter?
also, i'm having some connectivity problems at the moment
I think it's very noteworthy that you can invent a useful function on accident pretty easily
@Potato44 The specific function 'x'∘, is not hardcoded. Instead the interpreter has a bunch of rules which lets it determine the inverse of various compositions.
@EriktheOutgolfer You mean ×∘× (A times the direction of B) and ×∘+ (A times the conjugate of B)?
@Adám and ↓⍣¯1 too :)
I'd say that ⍣A where A < 0 is a very sophisticated feature of apl
@EriktheOutgolfer is that equivalent to ↑?
Nov 8, 2017 19:40
One of the most useful inverted functions is ⊥⍣¯1 (inverse of convert-from-base) which will use as many positions as needed to represent a number in a given base:
⍞←2⊥⍣¯1⊢123
@Adám 1 1 1 1 0 1 1
@Potato44 No, is "take":
⍞←3↑'Hello'
@Adám Hel
@Adám I meany monadic ↑.
@Potato44 Monadic and do something entirely different, namely raising and lowering the rank. That's covered in Lesson 1, iirc.
Nov 8, 2017 19:42
or is that not how ⍣ works?
@Adám yep they are
@Potato44 No, does not invert the symbol, except where the upside-down symbol happens to be the inverse too :-)
OK, let's see if we can finish @.
Until now, we've only used it to substitute elements. But we can also use it to modify them:
⍞←(-@2 5)10 20 30 40 50 60
@Adám 10 ¯20 30 40 ¯50 60
Here we applied the monadic function - (negate) at positions 2 and 5.
@Adám so 'map at'
Nov 8, 2017 19:45
⍞←7(+@2 5)10 20 30 40 50 60
@Adám 10 27 30 40 57 60
like jelly's ¦ (sorta)
And that's the same but using a dyadic function.
@Potato44 I guess so.
is @ an operator or a function?
Nov 8, 2017 19:47
Now we have been using an array right operand. If we use a function right operand it gets applied to the right argument, and the result must be a Boolean mask instead of a list of indices.
⍞←⎕A ⍝ uppercase alphabet
@Adám ABCDEFGHIJKLMNOPQRSTUVWXYZ
back in 3 minutes
⍞←'x'@(∊∘⎕A)'Hello World'
@Adám xello xorld
is membership, so the derived function ∊∘⎕A gives a Boolean for where elements of the right (and only) argument are members of the uppercase alphabet:
⍞←(∊∘⎕A)'Hello World'
Nov 8, 2017 19:49
@Adám 1 0 0 0 0 0 1 0 0 0 0
And that is used as mask by @ to determine where to substitute with x.
See e.g.
4
A: Goto the Nth Page

AdámAPL (Dyalog), 83 82 bytes Anonymous infix function taking current as left argument and total as right argument. {('prev '/⍨⍺>1),('x+'⎕R'...'⍕∊(⊂1⌽'][',⍕)@⍺⊢'x'@(~∊∘(1,⍵,⍺+3-⍳5))⍳⍵),' next'/⍨⍺<⍵} Try it online! {…} explicit lambda where ⍺ and ⍵ represent the left and right arguments:  ⍺<⍵ ...

i.e. @ uses the result of on it
where I use @ twice.
@Adám whatever :p
what is ⍸?
Nov 8, 2017 19:52
@Potato44 is the (new) "where" primitive which converts a Boolean array to a list of indices of the 1s.
⍞←⍸1 0 0 0 0 0 1 0 0 0 0
@Adám 1 7
⍞←(⍸∊∘⎕A)'Hello World' ⍝ i.e. "where uppercase"
@Adám 1 7
@Adám um, is there any function to convert to lowercase and/or a "lowercase alphabet" builtin?
@EriktheOutgolfer Due to this being dependent on the whims of the Unicode consortium, it is currently a special-access function:
⍞←819⌶⎕A
Nov 8, 2017 19:55
@Adám abcdefghijklmnopqrstuvwxyz
@Adám are there any docs with the i-beam functions anywhere?
@EriktheOutgolfer I-beams
is a special operator (although it follows normal APL syntax) which uses a positive integer operand to select a functionality.
@Adám aside from the primer on TryAPL, is there a complete list of all functions and operators?
Some of the numbers are a little bit mnemonic. E.g. 819 looks a bit like BIg. It takes a Boolean left argument which says whether the right argument should be made big (uppercase) or not (lowercase):
#help
Nov 8, 2017 19:59
@cairdcoinheringaahing ^
@Adám Ah, thanks
⍞←1(819⌶)'Hello World'
@Adám HELLO WORLD
⍞←0(819⌶)'Hello World'
@Adám hello world
Nov 8, 2017 20:00
The default is 0.
Thank you to all participants. Feel free to join next week.
 
Conversation ended Nov 8, 2017 at 20:01.