« first day (1308 days earlier)      last day (1332 days later) » 
01:00 - 18:0018:00 - 00:00

1:43 AM
@Adám I've made a pull request to APLCart with 5 TIO links, that should be enough to see if it works and whether you approve :)
 
 
2 hours later…
3:55 AM
      ⎕using←'System'
      IO.MemoryStream ⊂101 102 103 104 105
DOMAIN ERROR
      (⎕NEW⍠(Type.GetType ⊂'System.Byte[]')) IO.MemoryStream⊂101 102 103 104 105
DOMAIN ERROR
but why, what's the right way to make an IO.MemoryStream using the byte[] constructor?
I don't believe it
I've just got it
~30-40 tries of guessing combinations, and right when I give up and ask; it's byteStream←(⎕NEW⍠(Type.GetType⊂'System.Byte[]'))IO.MemoryStream(⊂b)
why is (⊂100 102 103) different from ⊂101 102 103? They have the same depth, the same shape, the same rank, they look the same in max boxing, what does that () do which makes the call work!?!
 
@TessellatingHeckler They are exactly the same in isolation (assuming your first 100 is a typo for 101). You need to provide the whole line of code to see how they differ.
@TessellatingHeckler Ah, I guess I got what you mean. IO.MemoryStream is a class, which is treated the same as an "array" in terms of syntax. So IO.MemoryStream ⊂b tries to call dyadically (Partitioned Enclose) between IO.MemoryStream and b, which obviously DOMAIN ERRORs. On the other hand, IO.MemoryStream(⊂b) creates a two-item array by stranding IO.MemoryStream and ⊂b.
 
4:14 AM
@Bubbler Grargh, thank you, that is ringing a bell, did you (or Adam) tell me this last time I got stuck here?
I probably also asked why that makes any sense at all, but nevermind that
the next line is

deflateStream.CopyTo inflatedStream
if I leave it like that, the dfn returns on that line as if it had an output. but if I try assigning the result to a variable, it errors because no result is provided. I think the method is void. If I trace it, stop before that line, and run that line in the interactive session, it works without any error or visible return value and does the copy
 
Yeah, using no-result functions in dfns is also a hassle. Check dfns.do.
More directly, you can hack it with _←⍎'void_line_of_code⋄⍬'
@TessellatingHeckler ^
 
@Bubbler HAHA! That does it!
Thank you :)
bit much to inline
Half the length of the C# version. The grouping and UTF-8 decoding of bytes was a massive frustration in C#, a non-issue in APL. The decompression, the other way round.
@Bubbler my PowerShell frontend still has a problem with ⍎ and no-result functions; when I tried that kind of diamond approach, it swallowed all the results when there were some.
 
4:47 AM
Dyalog APL is such fun for the novice.
I was looking at Dyalog v18 Nub Sieve example on aplwiki.com.
I observed that (~≠'HELLO, WORLD')/'HELLO, WORLD' is LOL.
I decided to go without parentheses.
'HELLO, WORLD'/⍨ ~≠ 'HELLO, WORLD'
I wrote the dfn version.
{⍵/⍨~≠⍵} 'HELLO, WORLD'
I learned much writing the train version for (~≠'HELLO, WORLD')/'HELLO, WORLD'
(~∘≠ {⍺/⍵} ⊢) 'HELLO, WORLD'
Another train using the partition operator giving a boxed LOL, assuming ]box on
(~∘≠⊆⊢) 'HELLO, WORLD'
So fun to get LOL in APL using that Nub Sieve and the string 'HELLO, WORLD' :)
 
5:05 AM
@TessellatingHeckler I can't think of a way to handle it properly. A simple (but buggy) workaround is to apply to the expression (which may give or not give a result) and catch any VALUE ERRORs (error code 6), but it also catches the same error from user code and may give obscure results.
 
5:57 AM
@RGS Probably the extensions to and , unless you have other ideas.
@TessellatingHeckler Well, you're abusing dfns. Maybe try your hands on tradfns?
@TessellatingHeckler You don't need parentheses in hash←('/'@{⍵='_'})('+'@{⍵∊'@-'})WebUtility.UrlDecode⊂hash.
@TessellatingHeckler The "massive frustration can be done entirely without parentheses:
deflateStream←⎕NEW IO.Compression.DeflateStream((⎕NEW IO.MemoryStream(⊂zBytes)) IO.Compression.CompressionMode.Decompress)
deflateStream←⎕NEW IO.Compression.DeflateStream,⊂IO.Compression.CompressionMode.Decompress,⍨⎕NEW IO.MemoryStream,⊂zBytes
@brgal (If you enter multiple messages in quick succession, SE Chat will merge then visually, and then you can still use markdown's backticks to make your code look better.)
In 18.0, you can use ⊢⍤/ instead of {⍺/⍵}
 
6:40 AM
@Adám Thanks !!!!
 
6:54 AM
(~∘≠ ⊢⍤/ ⊢) 'HELLO, WORLD'
(~∘≠ ⊣⍤/ ⊢) 'HELLO, WORLD'
I found it beautiful in this v18 form !
Thanks again Adám
 
@brgal There's also a non-train derived form: /⍨∘~∘≠⍨
 
7:36 AM
@Adám Thanks again for your teaching ;) I am pretty slow...I really need to practice.
Steps to your elegant form:
`(~≠ 'HELLO, WORLD') / 'HELLO, WORLD'`
`(~∘≠ 'HELLO, WORLD') / 'HELLO, WORLD'`
`'HELLO, WORLD' /⍨∘~∘≠ 'HELLO, WORLD' `
`/⍨∘~∘≠⍨ 'HELLO, WORLD'`
LOL
@Adám Sorry I do not know how to use the markdown's backticks to make the code look better.
 
@brgal Pretty much exactly like you did it. You just need to split the lines into separate messages. Alternatively, you can put all the code into a single message and click the "fixed font" button or hit Ctrl+K.
 
@Adám Now I know ! Sorry again ! Thanks.
 
No worries. Btw, you can use the sandbox room to experiment with markdown.
Also, if you begin code with a diamond, the bot should execute it for you:
 
Great !
 
⋄ /⍨∘~∘≠⍨ 'HELLO, WORLD'
Hm, that doesn't look like it is working: ⋄ 'bot?'
 
7:45 AM
@Adám bot?
 
Oh.
How about ⋄ /⍨∘~∘≠⍨ 'HELLO, WORLD' then?
 
@Adám LOL
 
⋄ /⍨∘~∘≠⍨ 'HELLO, WORLD'
⋄ /⍨∘~∘≠⍨ 'HELLO, WORLD'
 
@Bubbler LOL
 
moon-child: Code blocks not working any more?
 
7:48 AM
Apparently the bot is ignoring indented code blocks
 
One of my favorites APL LOL now:
⋄  (~∘≠ ⊣⍤/ ⊢) 'HELLO, WORLD'
 
ngn
8:46 AM
cmc1 proved too hard for this room, so here's something more basic:
cmc[0.5]: given two numbers ⍺ and ⍵ as vectors of decimal digits (possibly very long vectors; endianness - up to you), find the residue of ⍺ mod ⍵ in the same format. (hint)
 
8:59 AM
@ngn {⍎¨⍺|big⍥(∊⍕¨)⍵⊣'big'⎕CY'dfns'}
 
ngn
@Adám well, valid :)
 
@ngn Best form of answer.
 
ngn
@Adám why ∊⍕¨ instead of ?
 
@ngn Because ⋄ ⍕1 2 3 gives a charvec with spaces.
 
@Adám 1 2 3
 
ngn
9:06 AM
oh.. right
 
ngn
9:18 AM
@Adám interesting. john's divi function computes both quotient and remainder, discards the remainder, and returns the quotient. instead of reusing it for mod, he computes mod as (the bigint equivalent of) ⍵-⍺×⌊⍵÷⍺
i mean he reuses divi as a function, but he could have reused the remainder directly, without wasting resources on × or -
 
@ngn I hope to build the workspace from git in the near future. Then we can take GitHub PRs for issues like this.
 
ngn
@Bubbler not shitty at all, it's smaller than the one in dfns, and it appears to work
obviously you don't need the multicharacter variable names :)
btw, the point i wanted to make with cmc[0.5] was that long division of big integers is so much more complicated than long division of polynomials over GF(2) :)
 
10:01 AM
APL cultivation in 4 hours woohoo
 
10:12 AM
@TessellatingHeckler You don't need to output the original array (and then you don't need ⎕←'' either). Also, no need for parenthesising (3 3⍴⍳9), however it could be valuable to show that =⍨ and ≠⍨ penetrate structure, e.g. for 1(2 3) or 1 2 'abc'
 
Hey there @xash
 
RGS
11:18 AM
I was reading Dyalog APL's 13.0 changelog, which states
> The Index Generator function was changed so that ⍳⍬ would return ⊂⍬ rather than ⎕IO. The former behaviour was considered a bug because ⎕IO is not a valid index into an array with empty shape (that is, a scalar).
 
@RGS Yeah, and?
 
RGS
But I don't understand that statement, because ⋄ (⍳⍬)⌷ 2 gives an error, so it is still not a valid index
 
@RGS LENGTH ERROR
 
RGS
Whereas ⋄ (⊃⍳⍬)⌷ 2 is a valid index, so why wasn't ⍳⍬ changed to return ⍬..?
 
@RGS 2
 
11:22 AM
@RGS takes a vector (or scalar) of indices for each dimension, and returns a vector of indices. For a scalar, needs a length-zero vector (to match the number of dimensions): ⋄ (0⍴⍳⍬)⌷2
 
@Adám 2
 
However, it is maybe easier to understand for bracketed scatter-indexing ⋄ 2[⊂⍬] where the brackets contains an array of vectors. Each vector has to have a length corresponding to the rank of the array being indexed into.
 
@Adám 2
 
RGS
@Adám so for ⍺⌷⍵ we must have (≢⍺)=≢⍴⍵, is that what you mean?
 
@RGS Well, ⍺≤⍥≢⍴⍵ because allows omitting trailing axes. Of course, this means that an empty doesn't really index into a scalar, as it leaves any array as-is.
 
RGS
11:31 AM
@Adám But prepending 0⍴ to ⎕IO also works... ⋄ (0⍴⎕IO)⌷2 so that doesn't feel like a reasonable explanation
 
@RGS 2
 
RGS
re: " The former behaviour was considered a bug because ⎕IO is not a valid index", and the "new" ⍳⍬ is also not a valid index.
 
@RGS The new behaviour does indeed return an array of indices that are all valid indices for a scalar.
 
13
Q: Is it in the polygon?

nphThe challenge Given point and a path of points, say whether or not the point is in the polygon that is created by the path. Also return true if the point is on an edge of the polygon. Input A list of pairs of integers. The first 2 integers represent the point. The remaining pairs (3rd and 4th, 5t...

APLcart has a full answer to this lol

Mv{⍵∊⍺:1 ⋄ (¯1∊×d)∨1<|+/⍟d←(⊢÷1∘⌽)⍺-⍵}Ns
 
@RGS Think of ⍳Jv as a table of all combinations of ⍳¨Jv. Clearly, ⍳¨⍬ must give 0⍴⊂⍬, no?
 
RGS
11:37 AM
@Adám I'm still reasoning about this one
 
@Razetime Feel free to post. You can credit APLcart if you want.
 
doesn't feel right
If I understood something in it, sure lol
 
@Razetime So make it a task for yourself to fully explain it in your post!
 
ok, I'll try!
 
RGS
@Adám this just confuses the hell out of me ⋄ {(≢⍴⍵),(≡⍵),(≡⍳∘⍴⍵)}¨1 ⍬ (1 2 3) (⍳2⍴2) (⍳3⍴2) (⍳4⍴2)
 
11:50 AM
@RGS 0 0 2 1 1 1 1 1 1 2 2 2 3 2 2 4 2 2
 
RGS
It is just so not uniform
Could you try explaining again what is the relationship between ⊂⍬ and a scalar?
I think there might be some identity(ies) here I am missing
@Adám although this one seems sensible to me
Basically I expect some identity of the form ⍵⌷⍨f⍵, where f makes use of ⍳⍵, such that prior to 13.0 it was broken when ⍵ was a scalar and that now is fixed
I think I got what my problem is: the sentence "The former behaviour was considered a bug because ⎕IO is not a valid index into an array with empty shape (that is, a scalar)." makes it look like ⍳⍬ now is a valid index into an array with empty shape, it just doesn't specify the indexing method for which ⍳⍬ is a valid index
I was assuming such a method would be through use of the ⌷ primitive
but in using ⊃ or [] indexing, ⍳⍬ works as an index to a scalar
Ok, so I think this identity must hold: (⊢≡{⍵[⍳∘⍴⍵]}) array, and it did not hold with the old ⍳⍬ giving ⎕IO:
I ← (⊢≡{⍬≡⍴⍵: ⍵[⎕IO] ⋄ ⍵[⍳∘⍴⍵]})
I ⍳2 2
I 1 2 3
I ⍬
I 3
Hm I thought the bot handled this, but this gives a RANK ERROR on the last one, whereas just using {⍵[⍳∘⍴⍵]} works for all "test cases"
 
12:27 PM
@RGS The depth of ⍳v is 1 if the length ≢v is 1 and 2 otherwise. This inconsistency is caused by the fact that the NARS "extension" of to vector arguments isn't actually compatible with the old version: see APL Wiki.
 
@Adám 'need'? I thought they would be helpful for comparison. ⎕←'' spaces the output pleasantly. Trying to show that =⍨ penetrates structure without boxing looked more confusing than helpful when I attempted it.
 
@Marshall dzaima/APL improves this by giving a simple array result if the argument has rank 0 (instead of length 1) and a nested one otherwise, so that ≡⍳v ←→ ≢⍴v. BQN fixes it by using single-number indices if the argument isn't an array and vector indices if it is (in which case it must have rank exactly 1), so that ≡↕v ←→ 1+≡v.
 
(I'm suspicious that it's sleep/resume which breaks the AltGr keyboard on Windows and then makes it need AltGr+Ctrl)
 
RGS
@TessellatingHeckler (fwiw, I don't think I had any problems with that :/)
 
@TessellatingHeckler The example is interactive. The user can easily remove the function and reexecute. Btw, you could do 'disp'⎕CY'dfns' in the header and use disp to show structure.
@TessellatingHeckler I often make my PC sleep. No issues here.
 
12:45 PM
@Adám While both those are true, is that not contradictory to suggest both removing and adding unnecessary helper code for clarity in the output, in the same reply?
 
@Marshall Is there a better way than ⊏⥊ to get the array corresponding to a scalar?
@TessellatingHeckler :-) The helper code would also assist in further experiments, while being non-obvious for the uninitiated to add themselves. I don't really feel strongly about this, so if you do, then I'll just merge it as-is. Better to have more examples than to be overly pedantic about their exact spelling.
 
@Adám >< is a fun way (and also leaves all arrays alone)
 
@Adám I'd probably use <⍟(0=≡). It shouldn't be very common because you should generally know what depth a value has.
 
@dzaima @Marshall Oh wait, just < does the trick, no?
 
@Adám ah, i thought you wanted to leave arrays alone. but for just non-arrays, < of course works
 
12:50 PM
@Marshall Is there a reason why ↕<4 shouldn't be valid?
 
@Adám Yes, because <4 can't be used to select elements. Try (<4) ⊑ "abcd".
 
@Marshall OK, I guess. Btw, (<3) ⊏ "abcd" gives the odd message right argument must have rank at least 1 when = "abcd" gives 1.
 
@Adám OK; I don't know how strongly I feel about it, or whether that feeling is justifiable.
 
ngn
right, argument must have rank at least 1 :)
 
@Adám That should work! Compare (<3) ⊏ 3‿2‿1‿0.
@Adám Oh, it's a problem with the formatter not working on enclosed characters.
@Adám Now it works.
 
1:16 PM
@Marshall Confirmed.
 
 
1 hour later…
2:30 PM
Welcome to APL Cultivation!
 
Do we have a topic?
 
Having treated new 18.0 features in the previous lessons, I was thinking to describe some of the language enhancements next. Unless we have other requests.
 
Sounds like a plan...
I really should install 18 on this box...
 
Yeah, but at least you can now use the bot for access to 18.0: ⋄ #⎕WG'APLVersion'
 
@Adám Illegal code
 
2:32 PM
@DyalogAPL Oh, of course it is. My bad.
 
ngn
^^^this code, officer!
 
So, I think one of the most exciting extensions is that of partitioned enclose X⊂Y which now allows the generation of empty segments.
⋄ 1 0 0 2 2 0 0 0 0 0 0 ⊂ 'KenEIverson'
 
@Adám Ken E Iverson
 
That's kind of hard to interpret, how about ⋄ {↑(⍳≢⍵)⍵}1 0 0 2 2 0 0 0 0 0 0 ⊂ 'KenEIverson'
 
@Adám
   1  2  3  4        5
 Ken     E     Iverson
 
2:36 PM
Let's say we have some sorted data, and we'll like to group it by interval.
values  ← 3 14 15 35 65 89 92
cutoffs ← 0 20 40 60 80 100
We want to reach (3 14 15) (,35) ⍬ (,65) (89 92)
That is, all the numbers in the interval [0,20) and in [20,40) etc.
To get the index of each value's interval, we apply Interval Index: ⋄ values ← 3 14 15 35 65 89 92 ⋄ cutoffs ← 0 20 40 60 80 100 ⋄ cutoffs ⍸ values
 
@Adám 1 1 1 2 4 5 5
 
RGS
@Adám is this a question? should we finish what you started?
 
If you want.
Now, you might think that Key could do the trick, but then we'd have to insert all the possible intervals.
⋄ values ← 3 14 15 35 65 89 92 ⋄ cutoffs ← 0 20 40 60 80 100 ⋄ (cutoffs ⍸ values) {⊂1↓⍵} ⌸⍥{⍵,⍨⍳≢cutoffs} values
 
@Adám 3 14 15 35 65 89 92
 
Can we do this in a more elegant fashion?
 
RGS
2:45 PM
This doesn't have the ⍬ in the middle:
⋄ values ← 3 14 15 35 65 89 92 ⋄ cutoffs ← 0 20 40 60 80 100 ⋄ where ← cutoffs ⍸ values ⋄ (1,(1↓where)>¯1↓where) ⊂ values
 
@RGS 3 14 15 35 65 89 92
 
Right, that is close.
 
@RGS If you change > to -, I think you'll get the correct result
 
@RGS The problem you have is that you are detecting if a value belongs to a new segment relative to its neighbour on the left, rather than how many segments ahead it is.
 
⋄ values←3 14 15 35 65 89 92 ⋄ cutoffs←0 20 40 60 80 100 ⋄ (1,2-⍨/cutoffs⍸values)⊂values
 
2:47 PM
@Bubbler 3 14 15 35 65 89 92
 
@Bubbler Exactly.
 
RGS
@Bubbler gosh, how could I forget about 2 f/... xD
 
This did not work in 17.1 because partitioned enclose only allowed a Boolean left argument.
 
(I hope the bot gets dfns autoloading and/or ]boxing option)
 
(Haven't seen moonchild here for a while ― downside of relying on 3rd parties.)
 
RGS
2:49 PM
@Adám "how many segments"?
 
ngn
(⎕io←0 would be nice too)
 
RGS
@RGS ah I think I got it! when we had a boolean, a 1 indicated a new partition would start there, or rather, we would have to jump 1 partition to the right; an integer n means we jump n partitions to the right, meaning we create n-1 empty partitions if n≥1
 
@RGS Yes, you were comparing interval indices, to see if they were growing or not. Instead, - computes the difference in interval index numbers, i.e. how many segments ahead of its neighbour on the left, any given value belongs in. 0 means "in the same segment". 1 means "in the next one". 2 means "skip one".
@ngn It can already do that: ⋄ ⎕IO←0 ⋄ ⍳3
 
@Adám 0 1 2
 
RGS
⋄ values←3 14 15 35 65 89 92 ⋄ cutoffs←0 20 40 60 80 100 ⋄ ⎕SE.Dyalog.Utils.repObj (1,2-⍨/cutoffs⍸values)⊂values
 
2:51 PM
@RGS Illegal code
 
ngn
@Adám the point is to not have to type that
 
RGS
oh ok :/ it would be annoying to type, but at least one could be sure of what one was getting
 
@ngn It originally used ⎕IO←0 by default, but having the bot use a different default than the main system (however wrong you may thing that default is) would be quite confusing.
⋄ values←3 14 15 35 65 89 92 ⋄ cutoffs←0 20 40 60 80 100 ⋄ ⎕JSON (1,2-⍨/cutoffs⍸values)⊂values
 
@Adám [[3,14,15],[35],[],[65],[89,92]]
 
ngn
@Adám same argument goes for ]box
 
2:53 PM
:-D
@ngn True, but there you don't get different values, just different display form, and ]box is on by default on TryAPL and in Jupyter Notebook.
Anyone up for making that expression a neat train?
 
RGS
@Adám a couple of minutes to give it a try would be nice, yeah
⋄ values←3 14 15 35 65 89 92 ⋄ cutoffs←0 20 40 60 80 100 ⋄ cutoffs (⊢⊂⍨1,2-⍨/⍸) values
 
@RGS 3 14 15 35 65 89 92
 
Beautiful.
OK, so what more can we do with the new improved ? How about splitting at a given set of indices? E.g. ⋄ 'KenEIverson'∊⎕A
 
@Adám 1 0 0 1 1 0 0 0 0 0 0
 
⋄ ⎕JSON 1 0 0 1 1 0 0 0 0 0 0 ⊂ 'KenEIverson'
 
2:59 PM
@Adám ["Ken","E","Iverson"]
 
Well, it's boolean left arg
 
But if instead of the mask, we started with the indices of the 1s: 1 4 5?
 
⋄ (⍸⍣¯1⊢1 4 5)⊂'KenEIverson'
 
@Bubbler DOMAIN ERROR
 
Huh.
I thought the bot was updated. Well well, that should indeed work:
     (⍸⍣¯1⊢1 4 5)⊂'KenEIverson'
┌───┬─┬───────┐
│Ken│E│Iverson│
└───┴─┴───────┘
 
3:03 PM
So the bot's not running the Issue 2?
 
That worked from initial release.
 
That's weird.
 
RGS
@Adám but the bot accepts the new left argument to ⊂ so smth weird is going on
⋄ 1 ,⍥⊂ 2 3
 
@RGS 1 2 3
 
⋄ 1 0 0 1 1⊂'KenEIverson'
 
3:04 PM
@Bubbler Ken E Iverson
 
The bot is using a cover for and that wasn't updated to handle this.
 
Ah.
 
Anyway, this shows another extension in 18.0, namely that ⍸⍣¯1 conveniently works, but what you might not notice is that it also shows a further extension of . Observe:
     (⎕←⍸⍣¯1⊢1 4 5)⊂'KenEIverson'
1 0 0 1 1
┌───┬─┬───────┐
│Ken│E│Iverson│
└───┴─┴───────┘
Notice that the length of ⍸⍣¯1⊢1 4 5 doesn't match the length of the string!
 
RGS
@Adám yup, that's nifty
 
Until 17.1, the arguments of had to have exactly the same length.
Now, the left argument can have any length up until 1+the length of the right argument. Anyone care a guess why the 1+ ?
 
RGS
3:07 PM
@Adám in the "bin these values" prob above, it would be useful if any values where larger than the larger cutoff
is that it?
 
To allow some empty partitions at the end.
 
Yes, indeed. That'd be the way to say how many trailing empties you want.
 
⋄ ⎕JSON 1 0 0 1 1 2⊂'Hello'
 
@Bubbler ["Hel","l","o","",""]
 
So will assume that any "missing" elements in its left argument are 0.
Sometimes, you want to split into a head and a tail, like 1(↑{⍺⍵}↓)vector. What is now the shortest way to do this?
 
3:11 PM
⋄ ⎕JSON 1 1⊂'Hello'
 
@Bubbler ["H","ello"]
 
Spot on.
 
RGS
@Bubbler very clean
 
Another challenge: {(0↑⍵)⍵}vector
 
RGS
Just gonna share that ⋄ 3 (⊢⊂⍨1,⍨↑∘1⍤⊣) 'Hello' splits a larger head
 
3:15 PM
@RGS Hel lo
 
@Adám ⋄ ⎕JSON 2∘⊂ 'Hello'
 
@Bubbler ["","H","","e","","l","","l","","o"]
 
@RGS Sure, but at that point, ⋄ 3 (↑,⍥⊂↓) 'Hello' might be cleaner.
 
Wat.
 
@Adám Hel lo
 
RGS
3:16 PM
@Bubbler I had the same idea
@Adám indeed; just wanted to generalise the construct
 
@Bubbler You've discovered scalar extension. If the left argument is a scalar, will use that for all elements.
 
⋄ ⎕JSON 2 0∘⊂ 'Hello'
 
@Bubbler ["","Hello"]
 
Yup, you got it.
OK, how about ⋄ ⎕JSON ⊃,/{(0↑⍵)(1↑⍵)}¨'Hello' ?
 
@Adám ["","H","","e","","l","","l","","o"]
 
3:19 PM
That'd be Bubbler's 2∘⊂.
Not sure if this last one is very useful, but now you at least know about it.
Any more questions about X⊂Y?
Great.
Now that we mentioned ⍸⍣¯1 I should also throw in here that ⍸Y now works with duplicates in Y.
 
⋄ ⍸ 1 2 3 4
 
@Bubbler 1 2 2 3 3 3 4 4 4 4
 
(There must be a code golf challenge for this...)
 
It is now (almost) equivalent to {(,⍵)/,⍳⍵} where it only handled Booleans before.
@Bubbler If there isn't, we must make one. APL and K will be tied on this.
You can think of this as representations of sets.
Given a total set, e.g. 'abcdef' you can think of 1 3 5 and 1 0 1 0 1 0 as representation of a subset thereof.
Then 1 4 4 would be a representation of a multi-set.
The corresponding "Boolean mask" representation of that would be 1 0 0 2 0 0.
A better name might be a "counts" representation, as it gives you the count of each possible member of the full set, in the subset.
then converts the counts representation to an indices representation.
⍸⍣¯1 does the inverse transformation (save for leaving out any trailing 0s).
Any questions on the extension of ?
Great.
I won't go over the extensions to ↑[ax] because it really requires visuals. I'll show that in my next webinar.
Instead, let's go over the news in system functions for the remainder of this Cultivation.
We used ⎕JSON to visualise arrays here, but what can we do about matrices like ⋄ ⎕JSON 2 3⍴⍳6 and other high-rank arrays?
 
3:35 PM
@Adám DOMAIN ERROR
 
Exactly. JSON can't really represent those.
However, when speaking with the world outside, we probably want our matrices to be converted to lists of lists: ⋄ ⎕JSON⍠'HighRank' 'Split' ⊢ 2 3⍴⍳6
 
@Adám [[1,2,3],[4,5,6]]
 
⋄ ⎕JSON⍠'HighRank' 'Split' ⍳2 2 2
 
@Bubbler [[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]]],[[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]]]
 
Cool.
 
3:38 PM
Of course, this works universally, recursing even into namespaces: ⋄ mat←⍳2 3 ⋄ cube←2 2 2⍴2 ⋄ ⎕JSON⍠'HighRank' 'Split'⎕NS'mat' 'cube'
 
@Adám Illegal code
 
Oh, yes, we don't allow namespaces that simply, do we now?
      mat←⍳2 3 ⋄ cube←2 2 2⍴2 ⋄ ⎕JSON⍠'HighRank' 'Split'⎕NS'mat' 'cube'
{"cube":[[[2,2],[2,2]],[[2,2],[2,2]]],"mat":[[[1,1],[1,2],[1,3]],[[2,1],[2,2],[2,3]]]}
Oh, here's a challenge for APL hackers: Make the bot give you access to a namespace!
Anyway…
 
⋄ (dfns←⎕JSON '{}').⎕CY'dfns' ⋄ dfns.disp (1 2)3(4 5)
 
@Bubbler
Illegal code
VALUE ERROR
 
⋄ ⎕JSON '{}'
 
3:43 PM
@Bubbler ⎕CY is not allowed either (for quite obvious reasons).
 
@Bubbler #.[JSON object]
 
Nice.
 
⋄ ⎕SE
 
@Bubbler Illegal code
 
OK.
 
3:45 PM
There are a couple of other ways too.
Another thing that ⎕JSON can now do is to understand and create JSON5: ⋄ (ns←⎕JSON⍠'Dialect' 'JSON5'⊢'{noQuotes: [0xdecaf,0xC0FFEE] /* comment */}').noQuotes ⋄ ⎕JSON⍠'Dialect' 'JSON5'⊢ns
 
@Adám
912559 12648430
{noQuotes:[912559,12648430]}
 
Maybe most importantly, JSON5 allows trailing commas in lists and objects: ⋄ ⎕JSON⍠'Dialect' 'JSON5'⍠'Compact'0⍳3
 
@Adám
[
  1,
  2,
  3,
]
 
Compare with ⋄ ⎕JSON⍠'Dialect' 'JSON'⍠'Compact'0⍳3
 
@Adám
[
  1,
  2,
  3
]
 
RGS
3:50 PM
That's interesting
 
How so?
 
RGS
@Adám I am saying that the trailing commas now being allowed is interesting; I'm used to them, that is all :)
 
You're used to them from JavaScript. JSON doesn't allow them.
 
RGS
@Adám *Python; I know JSON didn't allow them
 
Ah, fair enough.
So, if there are no more questions, I'll close for today.
 
RGS
3:55 PM
@Adám Thank you very much for your time ○/
 
Of course. Let's start thinking about what else we might want to see in lessons like these, or if we should bring the season to a close.
Thank you for participating!
@Bubbler Counting that as 9 characters, I can do it in only 7.
 
Huh.
 
(Not using ⎕JSON of course.)
 
Then I absolutely have no idea.
 
RGS
@Adám what does it mean to "bring the season to a close"? some time without APL Cultivations?
 
3:58 PM
@Bubbler TryAPL doesn't currently allow ⎕JSON, but my 7 works there too.
@RGS Yes, like there weren't May 16, 2018–Nov 28, 2019.
 
RGS
@Adám a world with no APL Cultivations is a sadder world... If I come up with any ideas I'll let you know
 
How many nontrivial inverses does Dyalog APL have?
like ⊥⍣¯1 and ⍸⍣¯1
@Adám Still have no idea
 
@Bubbler Dunno. ∘.×⍣¯1 and then there's the numeric solving.
 
RGS
What is the numeric solving?
 
⋄ !⍣¯1 ⊢ 3628800
 
4:05 PM
@Bubbler DOMAIN ERROR
 
@Bubbler That's just the bot. Works offline.
 
      !⍣¯1⊢3628800
10
Or, solving x^2+2x+3=10:
      (3++⍨+×⍨)⍣¯1⊢10
1.828427125
 
@RGS Let's say you have a polynomial like x⁵+2x³–4x=10 which cannot be solved symbolically…
 
RGS
@Adám ah that is what you meant; well 5th degree polynomials still have closed formulas, but I get what you mean
 
      (*∘5+(2×*∘3)+¯4∘×)⍣¯1⊢10
1.545022035
      (*∘5+(2×*∘3)+¯4∘×)1.545022035
9.999999988
 
4:11 PM
Too bad ⊥∘poly⍣¯1 doesn't work
 
RGS
@RGS hmm I think I'm getting my numbers wrong with that "5th degree polys [...]"
 
@Bubbler what comes to mind is +.×⍨⍣¯1
 
@RGS So how about xᵉ+2xᵠ+x⁻ⁱ=10?
      (*∘(*1)+(2×*∘(2÷¯1+5*÷2))+*∘0j¯1)⍣¯1⊢10
1.715686353J0.04639259191
      (*∘(*1)+(2×*∘(2÷¯1+5*÷2))+*∘0j¯1)1.715686353J0.04639259191
10J¯1.340200173E¯11
 
RGS
@Adám yup, really good
Actually amazing, tbh; how Dyalog APL takes a train of mathematical functions and is able to invert it numerically
 
I dunno, maybe that too is possible to solve symbolically, but we didn't learn to do so in school. ;-)
@RGS Black (box) magic.
 
4:18 PM
A caveat is that it only finds one solution.
 
RGS
@Adám ugh, now that I think of it, when we solve equations F(x) = 0 we don't need to invert F, we just need a nice numerical method
What method(s) do you use? And is it a one-method-fits-all? Or do you adapt the method for the function at hands?
 
I don't know. But I can probably get you access to see the C code that does it. You signed an NDA, right?
 
RGS
@Adám The C code probably just calls some FORTRAN code, no? :P I'm pretty sure I did
 
afaik, there's no Fortran in the interpreter, all the Fortran and Cobol functionality has been reimplemented in C.
 
RGS
@Adám ah cool
also, "yes", there's some NDA clauses in my paperwork
 
4:22 PM
OK. Well, time to feed the family. See you tomorrow at 9:30!
 
RGS
○/ enjoy your meal
 
@RGS the couple times i've needed to "solve" some function (not in APL unfortunately), 1) it was complicated enough for wolfram engine to not be able to solve it (definitely too much for me), and 2) i needed (aka wanted) all the solutions (i ended up going with code assuming the solutions are relatively non-hidden)
 
RGS
@dzaima ok... but I think I missed your point
 
@RGS as far as i'm considered, single solutions don't give me much. i see they can be useful sometimes, but dyalog's inverses giving just one possible result is a pet peeve of mine
(there's nothing really preventing ⍸⍣¯1⊢1 1 giving 1000↑2)
 
RGS
@dzaima ah ok, I get it; I was just sharing my disappointment as soon as I realized Dyalog APL didn't really have to "invert" anything, per se...
On the other hand I am glad maths can save the day :D
 
4:29 PM
@RGS dyalog still attempts to invert using more logical means before resorting to numerical solving afaik
 
RGS
@dzaima that's smart and I expected it :D! even though it may not need to if the numerical methods are picked in a nice way
 
(numerical solving cannot do 1∘,⍣¯1⊢1 2 anyways)
interesting error message on ,⍨⍣¯1⊢'abcabc'
this was a fun and mostly pointless adventure
 
4:47 PM
whats the syntax coloring there
 
RGS
@Razetime LSD effects
 
@Razetime BQNs; separating highlighting for code and REPL results is pretty much impossible so i don't do it; feel free to remove #BQN at the end of the URL for no highlighting/font
 
nonono why
why would I do that lol
Is APL cultivation over?
 
@Razetime yeah
 
RGS
@Razetime ended ~50 min ago
 
4:51 PM
cool cool
 
 
1 hour later…
5:55 PM
@Beliod Hi and welcome. Interested in APL?
 
01:00 - 18:0018:00 - 00:00

« first day (1308 days earlier)      last day (1332 days later) »