« first day (1055 days earlier)      last day (1589 days later) » 

12:00 AM
I guess it should be clear. I guess it just works like function composition in math, right?
Ah, well for nomenclature. Is the whole +.× thing called an operator?
 
@david Yes, in fact, function composition is another APL operator, which works exactly as in TMN. f∘g x is f(g(x)).
@david No, only . is the operator. +.× is a derived function.
 
Ah, okay.
 
Are you familiar with APL's array model?
 
Not really I think
 
OK, no problem. In a way, it is really simple. All data is arranged in collections (arrays) or 0 or more axes (dimensions). The number of dimensions is equal to the number of indices one needs to pinpoint a specific element.
E.g. a list (a.k.a. a vector) has a single dimension, a table (matrix) has two.
A lone element (a scalar) doesn't need any indices, so it has 0 dimensions.
And there aren't a lot of data types to keep track of. Elements can be numbers, characters, or arrays. (There are a couple of more, but you don't need to worry about them for now.)
APL takes care of internal type conversions between Booleans, Ints (of various sizes), and various floats. And also between various character widths.
So Booleans are 0/1, making computations with them straight-forward.
@david OK, enough talk. Are you ready for some exercises?
 
12:11 AM
Yes, sounds good
 
I'll give you just the functions you need, and show you how to use the APL char bot. One essential function is (Greek Iota, for Indices or Integers):
⍞←⍳10
 
@Adám 1 2 3 4 5 6 7 8 9 10
 
⍞←⍳10
 
@david 1 2 3 4 5 6 7 8 9 10
 
Oh, btw, you can copy and paste the APL symbols, or look here for a more convenient way to enter them.
Right, task one: Compute the sum of all integers from 1 to 100.
 
12:15 AM
⍞←+/⍳100
 
@david 5050
 
Very nice.
Now, remember how APL always goes from right to left. If you want to alter the order, use parentheses exactly like you would in TMN. Now compute the sum of the first 17 squares.
 
⍞←+/(⍳17)*2
 
@david 1785
 
Oh, wow, you found *. Well done!
An interesting way to do this is:
⍞←(⍳17)+.×⍳17
 
12:19 AM
@Adám 1785
 
APL distinguished between minus as a function and the negative sign as part of a number. For the latter, we use a high minus (like TI-Basic, btw.): ¯42
Can you compute the sum of the first 100 odd numbers?
 
⍞←+/(((⍳100)-1)×2)+1
 
@david 10000
 
Would that even work? There has to be a better way to do that ...
 
It is right, but I'd write:
⍞←+/¯1+2×⍳100
 
12:24 AM
@Adám 10000
 
I would write 100*2 :P
 
@Quintec What is this, code bowling‽ Why not 1E4?
@david APL obviously has a function to get the number of elements of an array, but can you, using just the arithmetic functions you've learned, get the length of the built-in numeric list ⎕AVU (that's just a funny four-character name, don't worry about it)?
 
⍞←+/(⍳200)×2|⍳200 ⍝ alternative not as good solution
 
@Quintec
 
oops, but you get the point
 
12:27 AM
@Quintec But dislikes comments.
@Quintec Sure, or for that sake:
⍞←+/(2|⍳200)/⍳200
 
@Adám 10000
 
⍞←+/⎕AVU*0
 
ah yeah I completely forgot about replicate
 
@david 256
 
@david Perfect.
OK, can you now compute the arithmetic mean of ⎕AVU?
 
12:31 AM
⍞←(+/⎕AVU)÷+/⎕AVU*0
 
@david 2523.875
 
There are no forks an hooks in APL, right?
 
@david Some dialects have, including Dyalog. So in fact, the mean can be written:
⍞←(+/÷≢)⎕AVU
 
@Adám 2523.875
 
But this was for the sake of execise, not to create production or golfed code.
 
12:34 AM
Oh, okay :D Does the / really go through the closing bracket or is that a problem on my side?
 
@david That is a rendering problem in Chromium-based browser on Windows and macOS.
Let's talk assignments. APL uses = as a simple arithmetic function:
⍞←1 2 3=3 2 1
 
@Adám 0 1 0
 
We assign with which you've already seen, as means stderr. In general, you assign to variables with var←1 2 3
is the statement separator. Normally, results from a REPL (the "session") are printed without having to be explicit about it, and you wouldn't begin statements with a statement separator, but the chat bot uses these to identify messages it should react to:
⋄ var←42 ⋄ ⎕←var+var
 
@Adám
84
 
Oh, and ⎕← assigns to stdout, which for the bot means printing one or more separate lines.
Besides for the tacit functions which you got a sneak peek at, there are two other functional forms. The easiest one to master is called dfns and is indicated by putting the code in braces.
The right argument is denoted by the rightmost character of the Greek alphabet, and the (optional) left argument is the leftmost character :
⋄ MyFn←{⍺+2×⍵} ⋄ ⎕←3 MyFn 4
 
12:41 AM
@Adám
11
 
@david Are you familiar with TMN's ⌊x⌋ and ⌈x⌉ for floor and ceiling?
 
Yes
 
OK, if I tell you that the absolute value of x, that is, |x| in TMN, is |x in APL, then you can guess what floor and ceiling are, right?
 
⌊x and ⌈x, right?
 
Yup.
Can you write the function IsDivisibleBy? Thus ⋄ IsDivisibleBy←{your code here} ⋄ ⎕←15 IsDivisibleBy 5 ⋄ ⎕←15 IsDivisibleBy 6 should print 1 and then 0.
 
12:54 AM
⋄ IsDivisibleBy←{(⍵÷⍺)=⌊⍵÷⍺} ⋄ ⎕←15 IsDivisibleBy 5 ⋄ ⎕←15 IsDivisibleBy 6
 
@david
0
0
 
⋄ IsDivisibleBy←{(⍺÷⍵)=⌊⍺÷⍵} ⋄ ⎕←15 IsDivisibleBy 5 ⋄ ⎕←15 IsDivisibleBy 6
 
@david
1
0
 
Ah, that took a while ^^;
 
@david Very nice though. Do you want more?
 
12:56 AM
I would love to, but I unfortunately have to start working
 
@david No problem. You can always ping me, and anyway, all you really need now is to build your vocabulary. When you have time, check out our chat lessons.
I also recommend installing an APL locally. You can download the full system for free.
 
Thank you a lot for the introduction. You really know how to explain this clear and easy.
 
 
3 hours later…
3:47 AM
As I solve some practical tasks in APL using dfns, a dfn feels like a Haskell function with boolean guards and a where clause, except that a dfn also allows stateful computation and catching errors.
 
 
3 hours later…
6:53 AM
@Bubbler That's a good thing, right? Funny you mention that dfns have where clauses when John Scholes (who invented dfns) thought about adding where clauses.
 
7:44 AM
@Adám What a coincidence :) IMO, intermediate assignments already cover Haskell's where and let .. in in a simple sense.
 
@Bubbler Also, can be used as "where": var+var ⊣ var←42 var plus var where var is 42
@Bubbler I think John wanted to emphasise that the last rather than the first statement is the important one. A top-down definition, if you want.
 
@Adám ... except that it's more analogous to let .. in rather than where.
 
@Bubbler No, I mean in his proposal, not in the current syntax:
{
  var+var
  ; var←42
}
Here, it is clear that the main goal is to get var+var while var←42 is a necessary detail.
 
Interesting.
 
7:59 AM
Though, as he mentions, tracing through such a function would be a bit jarring, jumping up and down all the time. However, that's already the case for chained dfns where the order of execution is as follows:
{
  3
  4
}{
  1
  2
}
@EdgyNerd Hello and welcome to the APL Orchard. Interested in APL?
 
My question is, what would happen if both the main body and the where clause contains stateful computation (i.e. overwriting a variable, or "impure" code)?
 
@Bubbler The execution order is given, so whatever happens happens.
 
@Adám So "where" -> "main", I guess?
 
@Bubbler Yes, it'd start at the leaves and work its way up. Actually, when we get the new array notation, you can create "mini-environments" to isolate "wheres":
(var:42).(var+var) won't pollute its surroundings with a var
gtg, back online in about half an hour.
 
 
2 hours later…
10:04 AM
For me it was better |x was the norm of x; and operation of division is swap, and the symbol for modulus %.... Now I rethink... All operator has to be right to left: x| has to be modulus of x, x%y is the C language y%x etc etc
If APL is a language one read right to left why division and absolute module it is right to left?
Above wrong... If APL is a language one read left to right why absolute value and division are right to left???
No it is wrong the last one
I don't know for secure, but ';' as separator seems good in the paper...one write with pencil the diamond 💎 was difficult of write
 
10:35 AM
@RosLuP I agree that there are issues. In general, APL dyadic functions are designed such that the main data goes on the right and the "modifier" goes on the left. E.g. shape⍴data and amount↓data and bound|data. However, for historical reasons ÷ and - preserve their order or arguments, even though amount-⍨data and divisor÷⍨data make more sense. * is interesting, as it has two interpretations, so both * and *⍨ are meaningful. Indeed, their inverses are and .
One could construct a left-to-right APL where the primary data argument was on the left and the modifier was on the right, but then monadic function would probably need to be postfix, which somehow seems wrong. Maybe one could get used to a- being -x and x f is f(x)… It would let | be the current |⍨ and fit better with ÷, but on the other hand, monadic - and ÷ couldn't be seen as having 0 and 1 as "default" left argument.
Some things would look better in "LPA", like 101010₂ would be written as 1 0 1 0 1 0⊥2 and no statement separator would be necessary, as would do the job. However, 9√2 being the square-root of 9 would be jarring, and assignments would probably need to be trailing →name (like TI-Basic, btw), which means that long rows of definitions wouldn't line up.
x! would come back to its tradition, and n!k would fit with the "nCk" name.
Even if one could accept x- as negation and as reciprocal (though a bit odd), x* and x⍟ as e*x and e⍟x would be very weird.
 
 
5 hours later…
3:26 PM
@Adám kind of, what are some good resources to learn it from?
 
@EdgyNerd Me :-) I'll be very happy to give you a personalised intro right now (or at some other time), if you want. Otherwise, check out this page of learning resources.
 
@Adám I'll be on my computer in around an hour, could you give me an introduction then?
 
@EdgyNerd It'll be my pleasure. Give me a ping.
 
Ok, thanks :D
 
@Adám in "9√2" one can imagine √ rotate 180 °
 
3:45 PM
@RosLuP Well, most APLs don't seem to suffer terribly from not having so I guess one could keep using *∘÷.
 
Ven
4:00 PM
Took me a while to realize SE had added hats again, and it wasn't an actual avatar change...
 
@Adám I'm on my pc now, what do I need to start learning APL?
 
@EdgyNerd Having an installed interpreter is nice, but can also use tryapl.org or just use the APL chat bot right here in the room:
⍞←2+3
 
@Adám 5
 
How do you use the bot?
 
@EdgyNerd It evaluates as code any message beginning with ⍞← or ⎕← or . Use this to enter APL characters.
 
4:08 PM
Ah ok, what are the basics?
 
Can I ask you a little about your background so I can customise the intro for you?
Like, what is your programming and educational experience?
 
I use python mainly, and I know a little bit of Javascript/Scheme
 
How are you with Mathmatics?
 
Ok I guess
I'm in secondary school so I don't know any really complicated stuff
 
That's ok. Thanks. Since you've done some programming, it is easy to get a crooked view of APL. To avoid that, please let go of the notion that APL is a programming language. Instead think of APL as an alternative notation to replace the Traditional Mathematical Notation (henceforth "TMN") they teach you in school.
 
4:14 PM
Ok
 
APL is a rigorous mathematical notation without the ambiguities, peculiarities, and ad-hoc rules of TMN.
 
isn't that a reason why it's pretty good for golfing
?
 
It is indeed.
So, for very basic things, APL is identical to TMN. It uses proper mathematical symbols instead of poor ASCII substitutes. E.g. multiplication is × and division is ÷:
⍞←3×4
 
@Adám 12
 
⍞←3÷4
 
4:15 PM
@Adám 0.75
 
⍞←5+2×4
 
@EdgyNerd 13
 
What is the operator precedence?
is it left to right?
 
No, right to left.
⍞←2×4+5
 
@Adám 18
 
4:16 PM
ah ok
that makes sense
 
Cool. This means you don't need to remember a giant order. Just remember this one simple rule: the right argument of an APL function is everything as far as it can see on its right. That's it. Period.
Don't worry if you get it wrong. Initially most do, due to being accustomed to TMN. Feel free to experiment at any time.
 
ok
by 'as far as it can see', Is there a way to limit what it can see to the right (kinda like brackets)
or does it not need that?
 
@EdgyNerd Yes, you can use parentheses exactly like in TMN:
⍞←(2×4)+5
 
@Adám 13
 
ah ok
I'm probably jumping ahead here, but is ⍞← something to do with output?
 
4:21 PM
@EdgyNerd Yeah, in a normal APL system it means print to stderr. For the bot, it just means give me a simple inline answer.
OK, now lets talk lists (we'll get to general arrays later). APL lets you write a literal list simply by writing the elements next to each other. No need for parentheses of any sort or separators between elements. In fact, if you do use them, APL will remove them:
⍞←1 2 3
 
@Adám 1 2 3
 
⍞←(1,2,3)
@DyalogAPL Hey, what happened?
⍞←(1,2,3)
 
@Adám 1 2 3
 
@DyalogAPL Good bot.
(Sometimes it has a temper…)
 
haha
also I had a quick look at the tips page for APL so can't you do this?
⍞←1 2 3 + 4 5 6
 
4:23 PM
@EdgyNerd 5 7 9
 
Indeed you can. That was the next step. And also:
⍞←1+4 5 6
 
@Adám 5 6 7
 
oh wow
what happens if one list has a length of 2, and the other has a length of 3?
⍞←2 3 + 1 2 3
 
@EdgyNerd LENGTH ERROR
 
oh right
 
4:24 PM
That ^ :-)
 
that kinda makes sense
 
OK, so one of the things APL generalises from TMN is that just like - in TMN can be used with infix (between two arguments) and prefix (with an argument on its right), so can all APL functions be used in these two ways. We call them monadic and dyadic functions. E.g. The dyadic function ÷ is division and the monadic function ÷ is reciprocal (1÷x):
⍞←÷2 3 4
 
@Adám 0.5 0.3333333333 0.25
 
ok
so there's (kind of) operator overloading if there isn't a certain amount of arguments
 
Yes, but very often, the two forms are related in that the monadic form is like the dyadic but with a default argument.
 
4:28 PM
⍞←+1 2 3
 
@EdgyNerd 1 2 3
 
And it isn't really confusing as there can only ever be one or two arguments. To see which form is being used, look to the immediate left. If there's data there, it is dyadic. If there's nothing, or a function, it is monadic.
@EdgyNerd Monadic + is actually the complex conjugate, if you're into complex numbers…
 
I have no clue what complex numbers are to be honest
 
@EdgyNerd Right, I figured, which is why I didn't bring up that example. Hence my asking for your background :-)
 
also, I'm assuming that ÷÷ will just be the original list, since it's doing the reciprocal twice
⍞←÷÷2 3 4
 
4:29 PM
@EdgyNerd 2 3 4
 
Yes, except if one element is 0:
⍞←÷÷2 0 4
 
@Adám DOMAIN ERROR
 
0 is not in the domain of monadic ÷.
 
is domain what can and cannot be an argument?
(or in an argument)
 
Yes, e.g. you can't add characters, but you can compare them.
 
4:31 PM
⍞←"b" > "a"
 
@EdgyNerd SYNTAX ERROR
 
@EdgyNerd APL characters use single quotes: '
 
oh ok
⍞←'b' > 'a'
 
But you'd get a domain error anyway.
 
@EdgyNerd DOMAIN ERROR
 
4:32 PM
However, you can compare if characters are equal or not:
⍞←'b' ≠ 'a'
 
@Adám 1
 
oh right
is equal =?
 
It is.
 
also, quick question
is there a way to make the bookmark symbol bar bigger?
(it's really small for me)
 
APL only has two basic types, btw, numbers and characters. Super simple. That's why True is 1. Also 1 is the only True — none of this confusing truthiness business.
 
4:34 PM
oh ok
 
@EdgyNerd Only by increasing font size on the entire page. Sorry. You could inspect and change it though.
 
ah ok
is the characters type strings, or just single characters?
 
There are no strings, only lists of characters. And characters are atomic exactly like numbers.
 
ah ok
 
So arithmetic, logic, and comparison functions do this automatic mapping, which means that most often, you don't need a loop:
⍞←'i'='mississippi'
 
4:36 PM
@Adám 0 1 0 0 1 0 0 1 0 0 1
 
oh wow
so that's equivalent to 'i'='m' 'i' 's' 's' 'i' 's' 's' 'i' 'p' 'p' 'i'
⍞←'i'='m' 'i' 's' 's' 'i' 's' 's' 'i' 'p' 'p' 'i'
 
@EdgyNerd 0 1 0 0 1 0 0 1 0 0 1
 
Yes. In fact, there's a different function which compares its entire arguments without mapping:
⍞←'abc' ≡ 'a' 'b' 'c'
 
oh ok
 
@Adám 1
 
4:38 PM
Are you familiar with the TMN symbols ∑ and ∏ for sum and product?
 
not really
I'm guessing that ∑1 2 3 is 6
⍞←∑1 2 3
 
@EdgyNerd SYNTAX ERROR
 
Yes, but only in TMN, not in APL.
 
oh right
 
This is because the sum and the product are actually instances of a single concept, namely that of changing a list into a single element by inserting a dyadic function into all gaps:
⍞←1+2+3+4
 
4:40 PM
@Adám 10
 
⍞←1×2×3×4
 
@Adám 24
 
I'm probably jumping ahead again, but is / map or reduce (after looking at a couple of answers)
⍞←+/1 2 3
 
@EdgyNerd 6
 
Just what I was getting at. You're good.
So APL generalises this with something we call an operator. An operator is like a "super function" that returns a new function based on one or two parameters (depends on the operator in question) we call operands.
 
4:42 PM
so is +/ a "super operator"?
that takes a list and returns it's sum
 
/ is what we call a monadic operator because it takes a single operand (on its left) and derives a new function that didn't exist before. If the operand is + we call the derived function "sum", but really any dyadic function could be used.
@EdgyNerd The correct term for +/ is "derived function". We can even give this new function a name:
⋄ Sum←+/ ⋄ ⎕←Sum 1 2 3 4
 
@Adám
10
 
(if you experiment with this, then note that the bot requires a leading and then use of ⎕← instead of ⍞←)
 
oh ok
 
(⎕← normally means print to stdout but for the bot it means print as multi-line message)
 
4:44 PM
just as a guess, is ⎕ stdout, and ⍞ is stderr
 
Well, ⎕← and ⍞← but yes.
 
oh right
as another guess, does ← mean put the right argument into the left variable?
 
into the name on the left. We usually only use the word "variable" to mean data (arrays).
 
oh ok
⋄ a←5 ⎕←a+a
 
@EdgyNerd
VALUE ERROR
 
4:46 PM
@EdgyNerd Missing (statement separator)
 
⋄ a←5 ⋄ ⎕←a+a
oh ok
 
@EdgyNerd
10
 
and are actually stylised icons for the console with the inner ' symbolising strings/messages, hence stderr. If you try to fetch the value of it means stdin (but for obvious reasons, that won't work with the bot).
OK, now let me show you a really useful function, and then it is exercise time!
The Greek letter (Iota) corresponds to our English letter I which stands for Indices or Integers. Given a single number as arguments, it generates a list of that many integer indices:
⍞←⍳10
 
@Adám 1 2 3 4 5 6 7 8 9 10
 
so basically like range in python?
⍞←5⍳10
 
4:50 PM
@EdgyNerd RANK ERROR
 
@EdgyNerd Nah, not exactly, as you can see.
If you want to start at a higher number, you have to add:
⍞←4+⍳10
 
@Adám 5 6 7 8 9 10 11 12 13 14
 
oh ok
 
Now, task 1: Give me the sum of all numbers from 1 to 100.
 
⍞←+/⍳100
 
4:52 PM
@EdgyNerd 5050
 
Good. And the sum the first 100 odd numbers?
 
⍞←+/1+2*⍳50
 
@EdgyNerd 2.251799814E15
 
Oh dear. * is exponentiation, not multiplication!
 
oh yeah oops
⍞←+/1+2×⍳50
 
4:53 PM
@EdgyNerd 2600
 
@EdgyNerd Also, I asked for the first 100, that's the (not quite) first 50.
 
isn't that the first 100
due to the ×2
2×⍳50 gets all even numbers
 
No, because remember precedence. ⍳50 makes 50 numbers, no more, no less.
2×⍳50 are the even numbers until 100, but there are only 50 such numbers.
 
⍞←+/1+2×⍳50-1
 
⍞←1+2×⍳50
 
4:55 PM
@Adám 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 101
@EdgyNerd 2499
 
is that right?
 
@EdgyNerd Not quite. As I said, in the beginning, it is easy to get the precedence wrong.
 
⍞←2×⍳50-1
 
@EdgyNerd 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98
 
Note that sees everything to its right as its argument.
So it sees 49.
 
4:56 PM
oh yeah
 
:-D
No worries. You're doing great.
 
⍞←1-2×⍳51
 
@EdgyNerd ¯1 ¯3 ¯5 ¯7 ¯9 ¯11 ¯13 ¯15 ¯17 ¯19 ¯21 ¯23 ¯25 ¯27 ¯29 ¯31 ¯33 ¯35 ¯37 ¯39 ¯41 ¯43 ¯45 ¯47 ¯49 ¯51 ¯53 ¯55 ¯57 ¯59 ¯61 ¯63 ¯65 ¯67 ¯69 ¯71 ¯73 ¯75 ¯77 ¯79 ¯81 ¯83 ¯85 ¯87 ¯89 ¯91 ¯93 ¯95 ¯97 ¯99 ¯101
 
oh oops
⍞←¯1+2×⍳51
 
@EdgyNerd 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 101
 
4:57 PM
@EdgyNerd How fortunate. Now you had a chance to see what negative numbers look like. Note the high minus ¯
 
there's probably a smarter way to do that
⍞←+/¯1+2×⍳51
 
@EdgyNerd 2601
 
oops
⍞←+/¯1+2×⍳50
 
@EdgyNerd 2500
 
@EdgyNerd Not really, but you're still making only 51 or 50 numbers instead of 100.
 
4:58 PM
oh wait
I misread your question
oops
 
You have to think of as taking as argument the number of elements you want, not any kind of bound.
 
⍞←+/¯1+2×⍳100
 
@EdgyNerd 10000
 
@EdgyNerd Yeah, people tend to do that. Now you got it.
 
is there a smarter way to decrement?
instead of doing ¯1+
 

« first day (1055 days earlier)      last day (1589 days later) »