16:00 - 20:0020:00 - 00:00

4:37 PM
To participate in tonight's learning session without 20 Stack Exchange rep points, click lower-left giant avatar, then click "user profile" and there will be a number in the URL; that's your chat ID. Email your chat ID to adam@ with the domain being dyalog.com.

5:31 PM
Adám is hosting another informal APL learning session tonight at 18:30 UTC in https://chat.stackexchange.com/rooms/52405/apl. The subject is "APL primitive functions' marathon". To participate you will need 20 Stack Exchange rep points or if you don't have them see https://chat.stackexchange.com/transcript/message/41299896#41299896

@Feeds 1h to go \o/

6:15 PM

@EriktheOutgolfer Yeah, my idea is to start from one end of the language bar and blast through as many functions as we can.

@Adám well, not sure how many we could in 90 minutes, but let's try
)lb

@EriktheOutgolfer ← +-×÷*⍟⌹○!? |⌈⌊⊥⊤⊣⊢ =≠≤<>≥≡≢ ∨∧⍲⍱ ↑↓⊂⊃⊆⌷⍋⍒ ⍳⍸∊⍷∪∩~ /\\\\⌿⍀ ,⍪⍴⌽⊖⍉ ¨⍨⍣.∘⍤@ ⍞⎕⍠⌸⌺⌶⍎⍕ ⋄⍝→⍵⍺∇& ¯⍬

6:17 PM
Maybe we can try to make a program with as many primitives as possible?

@J.Sallé Try searching for "meaning" in my APL idiom list.

@J.Sallé here is one:
+-×÷*⍟⌹○!?|⌈⌊⊥⊤⊣⊢=≠≤<>≥≡≢∨∧⍲⍱↑↓⊂⊃⊆⌷⍋⍒⍳⍸∊∪∩,⍪⍴⌽⊖⍉⍎⍕
yes, it's a valid program
;p

@Adám What's the built in for logical NOT? I can't find it in the primer

@cairdcoinheringaahing Monadic ~.

~
ninja
13 seconds

6:30 PM

Welcome to the APL learning session

Does it output 42 though?

My plan is to blast through as many primitives as we can. Any protests?

Nope. Let's go \o/

OK. Please interrupt with questions as we go along!
Dyadic +-×÷ are what you expect from math.
0÷0 is 1 by default, but you can make all n÷0 into 0 by setting ⎕DIV←1.
Monadic - is negate. Monadic + is complex conjugate.

6:32 PM
@Adám how can we make 0÷0 throw?

@EriktheOutgolfer A×÷B

@Adám What does monadic + do on reals?

@Adám so ×∘÷

@cairdcoinheringaahing On any data which doesn't have an imaginary part, nothing happens. I.e. + always negates the imaginary part.
@EriktheOutgolfer If going tacit, yes.
@EriktheOutgolfer For golfing, you can also use ⌹ but it only works on two scalars.
Monadic ÷ is reciprocal, i.e. ÷n is 1÷n.
Monadic × is direction, i.e. a number which has magnitude 1 but same angle as the argument. For real numbers this means signum.
Dyadic * is power, and the default left argument (i.e. for the monadic form) is e.
So, monadic * is e-to-the-power-of.

@Adám Correct me if I'm wrong, but are the backtick shortcuts for ⍝ and ⍪ the same on the primer? They seem to both be <

6:39 PM
@cairdcoinheringaahing ⍪ is Shift <.
The inverse of * is ⍟ logarithm. The monadic is natural logarithm and the dyadic is left-arg logarithm, so 10⍟n is log(n).

@Adám there's a bug that says ⍝ is < instead of ,...

@EriktheOutgolfer You're right. I'll report that.
⌹ is matrix division. Give it a coefficients' matrix on the right and it will invert the matrix, put also a vector of on the left and it will solve your equation system. If over-determined, it will give you the least squares fit.
Monadic ○ multiplies by pi.
Dyadic ○ uses an integer left arg to select which trigonometric function to apply. The most common are 1 2 3 which are sin, cos, tan. ¯1 ¯2 ¯3 are arcsin, arccos, arctan.

@Adám Oh cool, that's new for me hahahah

The entire list of ○'s left args is here.
Monadic ! is factorial. Note that it goes on the left (like all other monadic APL functions) as opposed to mathematics' ! .
Dyadic A!B is the number of ways to take A items from a bag of B items, generalised to be the binomial function.

6:50 PM
Yeah that's combination, right?

@EriktheOutgolfer Never heard it called that.

@masaldaan you should have write access now

@masaldaan Any questions on what we've covered so far?
Monadic ?B returns a random integer among the first B integers. But ?0 returns a random float between (but not including) 0 and 1.

you mean the first B positive integers right?

@EriktheOutgolfer Is 0 positive?

6:54 PM
non-negative, perhaps?

Dyadic A?B returns a random one of the ways A!B counted. I.e. it returns A random numbers among the B first integers.

well
      ?10/10
┌→───────────────────┐
│4 3 1 9 3 10 9 8 5 9│
└~───────────────────┘
I've never got a 0 with ?
of course ?0 is another story

@EriktheOutgolfer @J.Sallé It picks from ⍳B so it depends on ⎕IO. Hence my vague language.

⍞←10?10⊣⎕IO←0

6:55 PM
@Adám 1 3 8 5 7 4 9 6 2 0

@all OK, we've blasted through the first language bar group. Any questions so far?

Nope, all clear so far.

@EriktheOutgolfer Yes, I think so. Did I miss something?

0/0 in mathematic is not defined It would be one error... So in Apl is 1 instead

6:57 PM
@RosLuP You can chose to have it be 0 or 1, as you wish.

@RosLuP not because of that, just the default

Both 0 and 1 have reasons (as long as you don't allow infinities or NaNs) so we let you have a choice.

@ngn You can always force an error with A×÷B.

@Adám I know, but it's not the same as A÷B

7:00 PM
@ngn but {(⍺÷⍵)⊣÷⍵} is ;)

@EriktheOutgolfer Ah, that's neat.

@EriktheOutgolfer if we could do ÷←that, but we can't

@ngn we can do div←{(⍺÷⍵)⊣÷⍵} :p
won't recommend overwriting a builtin primitive

@EriktheOutgolfer yes
@EriktheOutgolfer and lose the "power of notation" :)

7:03 PM
@EriktheOutgolfer or div←÷⊢⊣∘÷⊢

Q: Does ¬ have any meaning? If not, why doesn't APL allow me to do ¬ ← {code}?

if not golfing, let's rather keep it comprehensible enough

OK, this is getting a bit off topic for this lesson. It is an interesting discussion, but can we have it another time?

well, let's move on to the second group I guess then

@cairdcoinheringaahing What would happen if we later decided to add ¬ as a primitive? (rhetorical question)
@EriktheOutgolfer Yeah:
Monadic | is absolute value |x|

7:05 PM
well, magnitude to be precise

@Adám You could use the same argument for any symbol/word, but I'll wait til after the lesson for any discussion about that.

@EriktheOutgolfer Yes, right. Sorry.
@cairdcoinheringaahing APL has no, and will never have reserved words. They are exclusively for the users. The symbols are exclusively for the language.
Dyadic A|B is division remainder ("mod") when B is divided by A. Note the reversed order of arguments. "normal" mod is |⍨.
Monadic ⌈ is ceiling ⌈x⌉.

@Adám Is there a reasoning behind the reversed arguments?

@cairdcoinheringaahing I'm not sure, but I think it is an attempt to keep the left argument as what is "being done to" the right argument. Thus ÷ and - should really be reversed, but are kept as is for historic mathematics' reasons.

husk reverses them :p

7:09 PM
@cairdcoinheringaahing In other words n∘f should be meaningful if possible. (n is an array, f is a function).
"Mod-2" is more meaningful than "SpecificNumber-mod-…".
Dyadic A⌈B is max(A,B)

@cairdcoinheringaahing in my experience, most often the modulus is a fixed number and on the other side of | you could have a complicated expression, so given APL's parsing rules, reversed order is more convenient

@ngn I find that too, but caird asked for the reasoning, and I doubt that was taken into consideration.
⌊ is floor/min in the same manner as ⌈ was ceiling/max.
A⊥B is evaluate digits B as (mixed) base A, e.g.:

@Adám side note: this is a case of mathematics borrowing notation from APL

⍞←2⊥1 0 1 0 1 0

@Adám 42

7:14 PM
Are there some types? are there boolean type, range type, int type, float types? What is the true boolean value in Apl? What range has one int, or one float? Thank you

@ngn Rather, both getting their notation from Iverson, APL's father.

### Lesson 1 - Introduction to Arrays in APL

Oct 18 at 17:18, 1 hour 54 minutes total – 364 messages, 7 users, 4 stars

Bookmarked Nov 1 at 13:42 by Erik the Outgolfer

⌉ ⌋ aren't used by APL btw

@RosLuP But in summary: In APL, you can usually get away with assuming that a number is a number. And Booleans are just the numbers 0 and 1.
@EriktheOutgolfer Right, for the same reason as magnitude being just a left-hand-side |.

@EriktheOutgolfer that just means we get 2 more built-ins in the future :D

A⊤B is the inverse of ⊥, turning B into a list(s) of digits in (mixed) base A.

7:17 PM
@J.Sallé it's not a golfing language to account for that :D

@EriktheOutgolfer killjoy

⍞←24 60 60⊤10000

@Adám 2 46 40

Ten thousand seconds is the same as 2 hours, 46 minutes and 40 seconds.
Dyadic ⊣ is the left argument unmodified. Monadically, it just returns its sole argument.
Dyadic ⊢ is the right argument unmodified. Monadically, it just returns its sole argument.
@all And that's group 2. Any questions?

Nope, sounds good so far.

7:20 PM
let's move on to third group

@Adám How would you convert to regular base 2?

@H.PWiz 2∘⊥⍣¯1

@H.PWiz (NumberOfBits⍴2)⊤N
⍞←(8⍴2)⊤42

@Adám 0 0 1 0 1 0 1 0

Thanks

7:23 PM
= is comparison (not assignment!) and penetrates all structures, giving a single Boolean (0 or 1) per leaf element.
≠ is the negation of that.
≤<>≥ work as you'd expect, again penetrating all structure.
A≡B compares the entire arrays A and B in all respects, even the invisible prototype:
⍞←''≡⍬

@Adám 0

and that's how '' differs at all from ⍬

And A≢B is the negation of A≡B. (Note that it may render wrong on Chrome and Opera for Windows and Mac.)
@masaldaan Welcome!

@Adám you have mixed up expected behavior and actual behavior :p

@EriktheOutgolfer Huh? How so?

7:28 PM
> What is the expected behavior?
A display similar to ̸≡ (U+0338,U+2261) and ̸≈ (U+0338,U+2248).
waaat

@EriktheOutgolfer If you look at it using the faulty rendering engine, it will look "right".

@EriktheOutgolfer for me on vivaldi expected behaviour looks correct (and the wrong looks wrong)

@dzaima Right, Vivaldi≈Opera, i.e. uses Blink.
Monadic ≡B gives the "depth" of B, which is the amount of nesting. A simple scalar is 0, a vector is 1, a vector of vectors is 2, etc. If the amount of nesting is uneven throughout the array, the result will be negative, and indicate the maximum depth.
≢ B (again, may render wrongly as ≡/B) is the tally of B, i.e. how many major cells B has. For a scalar, that's 1. For a vector, it is the number of elements, for a matrix it is the number of rows, for a 3D array it is the number of layers, and so on.

⍞←≡(1 2 (3 4 5 (6 7 8)))

@J.Sallé ¯3

7:32 PM
Nice, that's something else I didn't know :p

@J.Sallé Great. Then this lesson is not for nothing.

of course you can't get ¯1 as a result for obvious reasons

@EriktheOutgolfer Right, or ¯0 which is anyway the same as 0 in APL.
@all That's group 3. Continue?

Yup, let's go

∨ is logical OR. And it is Greatest Common Divisor for for other numbers (which happens to fit with OR for 0s and 1s)

7:35 PM
In (8\rho2)T42 what is the return object or number from (8\rho2)? It is one list? Thanks

A 2x0x1x4 array is 0?

@RosLuP It increases the rank by one, so since 42 has rank 0, the result will have rank 1, i.e. be a vector.
@FrownyFrog I don't understand that question. A 2-by-0-by-1-by-4 array is exactly that; an empty 4D array.

⍞←8⍴2

@ngn 2 2 2 2 2 2 2 2

@RosLuP it's a vector of eight twos

7:37 PM

@RosLuP Oh, sorry, I misread. Yes, what @ngn said. Thanks, @ngn!
∧ is logical AND. And it is Lowest Common Multiple for for other numbers (which happens to fit with AND for 0s and 1s)
⍱ is NOR, and ⍲ is NAND. They only work on Booleans (arrays with nothing but 1s and 0s).
(Note that you can use ≠ as XOR and = as XNOR)
(And you can use ≤ as logical implication. Similarly for the other comparisons.)
@all And that's that group. Questions?

let's go to group 5

@Adám "2b ≥ 2b that is the question"

@ngn to be is implied by "to be" that is the question?
duh

@EriktheOutgolfer it's equivalent to 2b ∨ ~ 2b :)

7:42 PM
@ngn Then the answer is always "Yes" ;-)

@ngn um no
it's equivalent to 1 ;-p

So "(8\rho2)T42 is expand to (2 2 2 2 2 2 2 2)T42 that is expand in the first 8 bit of 42 (from right to left)

@Adám only if ⍺ or not ⍵; but not if (not a) and ⍵ :)
@RosLuP correct

⎕←(∘.≥⍨0 1) ⋄ ⎕←∘.(∨∘~)⍨0 1

@Adám
1 0
1 1
1 0
1 1

7:44 PM
@EriktheOutgolfer ^

@Adám Thanks, no questions so far. I'm all caught up now

@Adám heh, I had (≥/¯1+⍳2 2) ≡ ((∨∘~)/¯1+⍳2 2)

Anyway, A↑B takes from B. If A is a scalar/one-element-vector, it takes major cells, if it has two two elements, the first element is the number of major cells, and the second the number of semi-major cells, etc.:
⎕←3 4⍴⎕A

@Adám
ABCD
EFGH
IJKL

⎕←2↑3 4⍴⎕A

7:47 PM
@Adám
ABCD
EFGH

⎕←2 3↑3 4⍴⎕A

@Adám
ABC
EFG

If you take more than there is, ↑ will pad with 0s for numeric arguments, and spaces for character arguments:
⍞←6↑3 1 4

@Adám 3 1 4 0 0 0

You may also "overtake" a scalar to any number of dimensions:
⎕←2 3↑4

7:49 PM
@Adám
4 0 0
0 0 0

Negative numbers indicate taking from the reverse:

...that's something new to me :p

⍞←¯6↑3 1 4

@Adám 0 0 0 3 1 4

⎕←3 4⍴⎕A

7:50 PM
@Adám
ABCD
EFGH
IJKL

⎕←¯2 ¯2↑3 4⍴⎕A

@Adám
GH
KL

Monadic ↑ exchanges one level of depth (nesting) into one level of rank. See lesson 1 if this is unclear:
⎕←↑(1 2 3)(4 5 6)

@Adám
1 2 3
4 5 6

Because rank enforces non-raggedness, monadic ↑ will pad with the prototype element (0 or space) just like dyadic ↑:
⎕←↑(1 2 3)(4 5)

7:53 PM
@Adám
1 2 3
4 5 0

⎕←↑(1 2 (3 4) 5 6) ⍝ does this work?

@J.Sallé
1 0
2 0
3 4
5 0
6 0

@J.Sallé Sure, you gave it a vector of vectors, and it returned a matrix.

Interesting, I thought it'd just return 1 2 3 4 5 6

7:53 PM
@J.Sallé No, that's ∊ "enlist".

@Adám it's a vector of scalars and vectors

@ngn Good point, but ↑ will pad all cells to have same rank and shape as their siblings.

@J.Sallé that'd be flattening, but ↑ doesn't lose shape data

@dzaima It does lose raggedness.

7:55 PM
@Adám the only feature I've implemented in the interpreter, actually :)

@ngn Oh, you did that one? Good job!
Let's do ↓ too before we call it a night.
Dyadic ↓ is just like dyadic ↑ except it drops instead of taking:

⎕←3 4⍴⎕A

@Adám
ABCD
EFGH
IJKL

⎕←1↓3 4⍴⎕A

7:56 PM
@Adám
EFGH
IJKL

⎕←2 1↓3 4⍴⎕A

@Adám
JKL

Note that the last result is still a matrix, it just only has one row.

@dzaima losing too, what if it has trailing prototype elements?

@EriktheOutgolfer I'd not call that losing, but rather ambiguating, if that's a word.
Monadic ↓ is the opposite of dyadic ↓ in that it lowers the rank and increases the depth:

7:58 PM
And how to find one element of one matrix only? Example element 1,2

⎕←↓3 4⍴⎕A

@Adám
┌────┬────┬────┐
│ABCD│EFGH│IJKL│
└────┴────┴────┘

@RosLuP ⌷

⍞←1 2⌷3 4⍴⎕A

@Adám B

7:59 PM
@RosLuP or just use brackets to index:

⎕←1 2⌷2 3⍴⍳6

@EriktheOutgolfer
2`

(3 4⍴⎕A)[1;2]

16:00 - 20:0020:00 - 00:00