« first day (708 days earlier)      last day (2243 days later) » 

00:28
doing random speed tests is fun
https://tio.run/##zZU7TsNAEIZ7TjGKhERkebWzG6/JATgGRRRRUJCCRyoqCguQggQWEgegoKPgBjnKXsRs7LUd4n04yMZYLtY7tufX7PfPzGeL5ewqyyC/Ti9vFtfnF2cQzmEkk@dA3r8dydUXUjpefxQLOspDepuOA/l4V6xVAKpt9SUJ6n25eqhCoPbfESjo8AF0fKkf2sQXL8jkBZBMT9afE7hVz/QQ5NPrILcWaygnbGuNtNaQsZ61/iij8TxrXYIIpSva6BJiH13uw3PRousxKevBsZ96NDTt2gNs5gCzNWSSWsyhIn9tD/CaIxrKHE30jJaYkrhEj4uOFFo6Seo2ARJewojYf612tPmtEmt1AbJh25xnwrQZMdYZ4xsyPdjIMGeMXoqrZrWXmfyJTfWB7by1hwPsKq@5@nXWiGCZNeRu4Nr0KdeR5vlY7j6@4Zv9O8DBijdY4LZ0G/@Y6Atw8OHNybEH75aJPDjzGucQm3la@zX1AIyEVUDRX/dzp4IWUItSQxSLAaHOsm8
oh i probably shouldn't be counting the ⍉ there
https://tio.run/##zVY7TsQwEO05xWglJKIolh3H@RyAY1CsVhQUbMGvoqKIEBJIECFxAAo6Cm6wR/FFgknibLyxnWi1TohSODOK52n83jyvluu75XVZnl3drm8uLs8hWMGC568@f/w44c8/BGNv81Uv8KJKNWHs@fzpoV6LBLRh8Sfye3EPROyTAAa52REc9hH7mYBXeZ6/AUHp6eY7gnvxjY@Bv7zP8jZYNZ2EDlTaQA3C2CVUtYXac2xBMcQEKPYHKs7GgRo6MyNBqoIpwrIgY/t2wVRcIT2YKA96wvO8MFB@m5mE9DBE@ei/UB6shM9QJo@ahm6A9udFYaX7VoMQpJP3rgdSL5HOoCDhtCA1MlJH8BjzMLqHmnAupb6B6OSUuJGTAYyuXdDBglt6sgNhsc5o9Xg6rhC1VrWfTEb4g5H9oahNRW0/Tuccb0YzGXYTi53sptyrYNdSdCKgnWvUgArGVLOznFZ3jrpYYLl0jNN3YacyQUTSiWQupqkVkoHhiYREaTIjxcvyFw
 
3 hours later…
03:47
Anyone know the motivation behind the fact that Stencil takes subarrays going "over the edge" of its right argument so the remainder are filled with zeros?
 
2 hours later…
05:46
@lirtosiast I guess it's to keep the top two dimensions the same.
06:41
@lirtosiast How else would you be able to compute the next generation on the edges of a Game of Life board?
 
3 hours later…
ngn
ngn
09:23
@lirtosiast another theory: f⌺m n⊢⍵ keeps the centre of the stencil within ⍵'s boundaries. to keep the whole stencil, there already was n-wise reduction: f¨m⍪⌿n,/⍪¨⍵ or f¨n,/⍪¨m⍪⌿⍵
 
8 hours later…
16:56
Did you know that does allow short ⍵⍵? It then works on (more) major cells. TryAPL!
ngn
ngn
17:41
@dzaima so what's the best version's timing? 0.35ms?
@ngn there are 4 tests there, each with a different, separate score
first 2 test with 100×1000, next 2 with 1000×1000, 1st & 3rd test returning a matrix, 2nd & 4th test returning a vector of vectors
ngn
ngn
@dzaima yeah, but they are doing similar things, i was curious about the fastest one
and whether it's faster than mine
fastest for a matrix seems to be (⍳1000)∘.+⍳100 at 0.055ms for 100×1000, and 0.54ms for 1000×1000
ngn
ngn
ok, so (!1000)+\:!100 should be the equivalent to that, which in my case is twice as slow as (!100)+\:!1000
my \t output is in ms, i ran it 1000 times... so my timing is 0.1ms
@ngn oh right, for a vector of vectors different orders of non-equal sides should be tested too
ngn
ngn
17:54
so my time for (!100)+\:!1000 (the better version) is almost exactly the same as your (⍳1000)∘.+⍳100
@ngn k doesn't have matrices though, does it? Dyalogs best vector-of-vectors is (⍳1000)+⊂⍳100 at about 0.1ms
ngn
ngn
@dzaima well, a vector of vectors serves as a matrix...
@ngn but it has overhead (at least I'd expect it to)
ngn
ngn
@dzaima it has some but it should be small
in Dyalog it's about a 2x speed difference for the fastest per a test between matrix and vector vector
ngn
ngn
18:03
@dzaima ]runtime reports in ms, i can't even measure it :)
here's my attempt
@ngn you can do ]runtime -r=100 to repeat 100 times
ngn
ngn
thanks
and ]runtime -c does the repeating automatically afaict
Or -r=30s to repeat for 30 secs. Or even -r=30s⌈100 etc.
@Adám oh didn't know about the last one o.O
ngn
ngn
18:06
0.029ms and 0.023ms for the solid matrix and vec-of-vecs
doesn't sound plausible to me, but that's what it reports...
@ngn I seem to get 0.143ms for (⍳1000)+⊂⍳100, are you using something other than that?
ngn
ngn
@dzaima i was using (⍳100)+⊂⍳1000
oh that does make it ~2x faster than ∘.+ o.O
ngn
ngn
and (⍳100)∘.+⍳1000 for the solid matrix version, but argswapping shouldn't matter there
^ mhm, it seems so
ngn
ngn
18:14
ok, so this seems consistent - in all langs we get a 1:2 ratio for 100x1000 vs 1000x100
dyalog is faster than ngn/k, most likely because it's using a smaller type. ngn/k always uses 8-byte integers
@ngn oh wow, even in dzaima/APL :D
it is ~2x slower overall than Dyalog, but that's to be expected (though I expected a bigger gap, as always)
same test in Dyalog but with 100×1000 too and labels
https://tio.run/##zZfPTsIwHMfvPMUvJCaSZUvb/WPefQwPhHDgAAdU4sGTB2JMNFFi9AE8ePPgG@Cb7EVm161by9puKGwsQKAN/L5rP99vf4xH8@XoMkkwQujnjb6e9XoXi@v51XQ2AXsM/Xj1bMX376fx4zedHWw@szeoz6byYTSw4oe77D2dgGKYftOxKuMDoGMfGBDwH@sB6ApBesWrF8BOdL758uCWfkYnED@9dvKATKvizkGQ6uVSbRIeTCpI12x0tZjeUHHK1S@k@Uyan0oLSQNpYLyEcpVNZeWGTsDL@f5fV0JXXCYVdJyCmtJ4tdZwWs4oSYU6Tv1j4RRqKMWtU7qcjNMn89DaCKrgIdzyMnK0DRxUJJIWJXL8ezgP7ZrULimVUluAQkpnYTdk@2wtQjW1y0LFNgZOmAdAd24AObPF@wZBKA9GGlWtC9VkuLQXQoYjHqokaMW4UpZsYZCvXsRXzyJdhp7@TJBcAGoPCI7fcoEYVwofgNkFLjsTMhfsYIOmR68SaLGmTfZSUxnfak
 
3 hours later…
21:36
Is there a way to turn a string into a vector of codepoint numbers, such that I could do 'ABC' × 0 1 0 and get something like ` B ` ?
@TessellatingHeckler ⎕UCS
that'd be ⎕UCS 0 1 0 × ⎕UCS 'ABC', but 0 as a codepoint isn't a space
@TessellatingHeckler There may be interesting alternative methods available. What are you trying to do?
^ for spaces specifically, (' '@{~0 1 0}) 'ABC' works
Well, ¯1 1 ¯1/'ABC' is probably nicer
@H.PWiz Curiously, {⍵\⍵/⍺} is shorter than {⍺/⍨¯1+2×⍵}
@dzaima {⍺⍀⍺⌿⍵} can be written as ⊣⍀⌿ in your APL, right?
21:47
@Adám yeah, except is not implemented :p
@dzaima Oh.
nor are negative numbers to
@dzaima You don't need that for ⊣⍀⌿
@Adám yeah, I'm just mentioning that as an aside note of my laziness
@dzaima You call single-handedly implementing a pretty complete APL system with graphics "laziness"‽
21:50
@Adám replicate is one of the most important builtins of apl though, beyond what's necessary for anything to be possible to be done
@dzaima Sure, but not expand, and certainly not the extended domains of the two.
@Adám ok sure
@Adám half of it is massive bodging though
i honestly have no idea why trains work in my apl. i keep trying to find examples of it failing, but can't :|
aha, ⎕UCS is the map(chr, ...) I was hoping for
@Adám I'm looking at something from a Morten Kromberg (Dyalog) presentation, where he showed (x y flags) ← (1 2 3 4) (10 20 30 40) (1 0 0 1) to set up a left vector, a right vector, and a flag vector, then used (x × flags) + (y × ~flags) to take items from the left where the flag was 1 and items from the right where the flag was 0
and I was trying to do the same, but chars from a string - two strings, and a flag vector the same length, take from the left string or the right string into a new string
personally I'd do something like 'abc' (0 1 1{f←⍺⍺ ⋄ (f/⍺) @ {f} ⍵}) 'ABC' for that, but no idea how that'd do for performance compared to other solutions
@TessellatingHeckler ^ but as a simple expression: (b/X)@{b}Y
22:05
hmm, while back at my apl, I should implement f⍣g for until. Any reason why Dyalog chose to have the newest argument as ⍺, not ⍵?
I ... have no idea what either of those is doing :D
@TessellatingHeckler @ is at - I'd read that expression as "insert X replicated by b at positions b in Y"
what is f in yours, dzaima? and what is b in yours, Adám?
@TessellatingHeckler the flag vector
@TessellatingHeckler @{b}Y where b is a Boolean vector replaces the elements of vector (or string) Y as indicated by the Boolean mask. (b/X) applies the mask b to the vector (or string) X
22:09
@dzaima imo it feels way more natural doing 1∘+⍣{⍵=3}⊢0 for repeating until the value is 3, as ⍺ is usually the more optional argument
@dzaima {}2⊣⍣{1⊣⎕←⍺ ⍵}3 prints 2 3
Perhaps it seems more natural to do ⍣< if you want the value to become < the previous value
hmm, ok; b/X is the "filter()" I was looking for , and I think I see how that works then
let's seee
what does it mean when the {b} or {f} is alone in a ... scriptblock(?) like that?
@TessellatingHeckler Ah, so you could sure do that with characters exactly as you describe as ⎕UCS (flags×⎕UCS x) + (~flags)×⎕UCS y
@TessellatingHeckler it just makes it a function returning that value. it's a hack to get around how @ works for plain vector right operand
22:13
@TessellatingHeckler It is just a function that ignores its argument(s) and returns a constant.
oh, roughly a lambda/anonymous function so it can be .. passed to something expecting a function?
@TessellatingHeckler {} is just an anonymous function.
@TessellatingHeckler Exactly. @ needs a function on its right to use a mask (otherwise, if given an array, it uses the array as indices. In a sense, {} is a quoting mechanism here).
@TessellatingHeckler In fact, you could also write ((b/X)@(⍸b))Y since is a function that transforms a mask into a set of indices.
@TessellatingHeckler You may enjoy these lessons, but never hold yourself back from asking here :-)
@Adám so having a left arg to makes it the new latest result? For me it'd make more sense for it to be the previous one
@dzaima No, it just happens to be that 2⊣3 is 2. However, all this does politely hint at the potential benefit of a LtR APL, no?
@Adám oh a left arg to f⍣g makes it the left arg to all calls of f. how does that give any reason for my question?
22:22
@dzaima You start off with what's produced to the left of being and what comes from the right of being .
Thank you, both :) I will look at the lessons link in a bit, Adám, I have a pile of tutorial style links open right now, hah.
But, I'm pretty happy, I have a function which will take a string and generate a vector the same length of a 20% chance of mutating each character: `mutateVec←20>{?(≢⍵)⍴100}` and a random string the same length `randomString←{'ABCDEFGHIJKLMNOPQRSTUVWXYZ '[?(≢⍵)⍴27]}` and now a merge to make a mutant string combination of the two:
`mutantString ← {flags←(mutateVec ⍵) ⋄ ⎕UCS((⎕UCS ⍵)×~flags)+((⎕UCS(randomString ⍵))×flags)}`
@TessellatingHeckler you can use ⎕A for the uppercase alphabet for less noise in the function
it's uppercase + space at the end, so (⎕A,' ') ?
@TessellatingHeckler yeah
also markdown doesn't work in multiline messages as you may have noticed
I haven't yet learned to tell if ⎕ is quad or a browser font display error ;)
22:26
@TessellatingHeckler is indeed called quad :)
"break the fourth wall" function
@TessellatingHeckler You should get used to being right-associative, so you don't need function application of the formf(args); just f args: {flags←mutateVec ⍵ ⋄ ⎕UCS(⎕UCS ⍵)×~flags)+flags×⎕UCS randomString ⍵}
@TessellatingHeckler I have yet to come across any setup that displays any APL character as tofu, so whenever you see in an APL expression, rest assured that it is indeed a quad.
notepad displays alpha as tofu :(
@TessellatingHeckler the default notepad of windows? why is that even a thing you've tested? :p
@TessellatingHeckler Hm, you must have some odd font selected, or your system doesn't do fallbacks properly.
@TessellatingHeckler It is an icon for the console or the "box" (=computer) if you want.
22:30
partly because I'm in TryApl.org and it threw "expression time limit exceeded" and wouldn't ]defs display my mutatestring, and I wanted to keep it somewhere, so my default habit is to open a new notepad and paste into it
and partly because my way here was via Aaron Hsu's talk about his co-dfns compiler which he writes in notepad, so I assumed it would "just work"
@TessellatingHeckler Yeah, I've noticed that faulty error happening on TryAPL. Probably my fault. I'll see if I can fix it.
@TessellatingHeckler It should if you choose an appropriate font. You can either download an APL font or use a good Unicode font.
@Adám i still don't quite understand why that's something to be taken over the much more general fact of being the more important argument
I appear to have 'Consolas' as notepad's font
@dzaima Not my only complaint with . I'd like it to do a test first so I can do nothing if the condition is already true.
@TessellatingHeckler shows fine in my Notepad with Consolas selected, but clearly Windows is falling back to some other font.
@TessellatingHeckler yeah, sadly Consolas doesn't seem to have APL chars. Otherwise I'd use it everywhere
@Adám right, that too. How about making as the previous output (as you can easily bind the left arg to f otherwise), so that'd be possible?
i.e. ⍬ (1∘+⍣{5=⍵}) 5 would return 5, as the input already is 5, and the left argument doesn't matter
@dzaima Can you show an example where does matter?
@Adám right, that's a thing I'm stuck on too
@dzaima I think I'd rather have X f⍣g Y be X f⍣(X g Y)⊢Y (and that too in general of such operators)
E.g. X f@g Y should have been X f@(X g Y)⊢Y while @ should always have expected indices, never a mask.
However, I think @ is strictly unnecessary in light of .
@Adám imo the mask feature of @ is way more useful than the indices one
22:43
mutantString ← {((V←mutateVec ⍵)/randomString ⍵)@{V}⍵} that also works, hooray
@Adám what, how does replace @
@dzaima Sure, but sometimes you end up with indices, and it is easier to transform a mask to indices () than vice versa (the not-yet-implemented ⍸⍣¯1 plus allowing all kinds of primitives to take short args).
@dzaima f@g is f⍢(g∘⌿) and f@B is f⍢(B∘⊇)
@Adám that'd require special-casing ⌿⍣¯1 there, no?
@dzaima No. ⍢f doesn't actually call f⍣¯1 on structural functions, it just does (f Y)←
@Adám so special case the whole for specific builtins? imo the whole (f A)← thing is strange
22:51
@dzaima No, neither. is able to analyse its operand to determine whether it is a structural or computational function.
@Adám "analyze"? would it recognize ⍢{3 3⍴⍵}? {0,1↓⍵}?
@dzaima Yes. But it will fail due to not being able to invert them.
@Adám but {3 3⍴⍵} is a structural function :|
@dzaima Sure but we "never" invert dfns.
is one built-in in APL you can't remake using other builtins. Why that is, I understand. though adding more to that list feels wrong
@Adám but doesn't do any inverting on structural functions
22:56
@dzaima Oh, you mean because of negative exponents?
@Adám yeah
@dzaima It does. Take fore example -⍢(2∘↑). First it takes the the first two, then it inverts them, then it puts the first two back.
Unfortunately, I've clobbered my extended APL with too much fanciness, causing everything else to break, but it sure worked before.
{((V←20>?(≢⍵)⍴100)/(⎕A,' ')[?(≢⍵)⍴27])@{V}⍵} 'HELLO WORLD' - I can embed both my mutationVec and randomString into the one definition; is that .. too crowded?
@Adám but (2∘↑)⍣¯1 ⊢ 1 2 can really give anything it wants beyond the 1st 2 elements
23:01
@dzaima Correct. My definition of disconnects it from ⍣¯1
@TessellatingHeckler I'd personally keep it in one function, but split it into multiple statements:
ah, simply a multiline function?
can't seem to do that in TryAPL, right? or is this something where 'del' comes in?
no that doesn't seem right from the definition
mutantString←{
  len←≢⍵
  mask←20>?len⍴100
  abc←⎕A,' '
  substs←mask/abc[?len⍴27]
  substs@{mask}⍵
}
mutantString 'HELLO WORLD'
@TessellatingHeckler No, you can't (easily) make multi-line functions in TryAPL, but you can easily have multiple statements by separating them with :
mutantString←{len←≢⍵ ⋄ mask←20>?len⍴100 ⋄ abc←⎕A,' ' ⋄ substs←mask/abc[?len⍴27] ⋄ substs@{mask}⍵} is valid on TryAPL.
@Adám still feels weird to me to do that since it still fallbacks to ⍣¯1 and having fallbacks anywhere in apl feels weird to me
@dzaima OK, that's only in my model. Obviously, the real primitive would just use the internal inversion capabilities, and would be a means to specify.
structural assignment feels somewhat okay to me if thought of as an alternate mini-language for the left of , but bringing it beyond that feels very wrong
23:10
@dzaima My model actually relies on a bug to circumvent APL's checking for valid structural assignments :-)
imo either should use ⍣¯1 everywhere or nowhere, making it the same builtin for 2 completely different things is what upsets me i guess. like imo -⍢(2∘↑) 1 2 should technically be allowed to return ¯1 ¯2 'Hello World!' and it not doing that shouldn't be taken as a given
that does look cleaner with variables like that, @Adám and I see the diamond-version working too
neat
@dzaima That's an argument against ⍣¯1 in general. There are a few cases where it cannot be determined if the user meant computational or structural Under, but in those cases, the computational Under is equivalent to an Over, so there is no point in using the more complex Under, and so it is safe to assume structural. That being said, maybe they should have been separate if we hadn't blundered @.
@TessellatingHeckler APL can easily become hard to read, so I try to be strict on myself in keeping it ultra clean. One of my rules of thumb for achieving this is to avoid parentheses, instead opting for introducing meaningful names. By the way, if you dislike the "jumps" in execution (diamonds from left to right, but the actual contained expressions from right to left) you can use which is pretty much like but "mirrored". You can read it as where. As follows:
mutantString←{substs@{mask}⍵ ⊣ substs←mask/abc[?len⍴27] ⊣ abc←⎕A,' ' ⊣ mask←20>?len⍴100 ⊣ len←≢⍵}
@Adám tbh, I have mostly seen you around posting answers in the CodeGolf StackExchange, and that's roughly the only APL I've ever seen, so I had little background context that APL even had variables used the same way as most languages.
@Adám I didn't make an argument against ⍣¯1 there, I feel perfectly okay with it giving garbage in places where it technically can. When it's forced to do specific things is when I don't like it
23:23
I have been wondering what left-tack was for. It's a different "where" to iota-underbar which TryAPL primer calls 'Where'
@TessellatingHeckler Dyalog APL also has classes, namespaces, and in tradfns you can even have readable control flow as :if / :for var :in arr, ect
@TessellatingHeckler it's mainly for being an argument to operators where the alternative would be writing an annoyingly long {⍺}
@dzaima I have seen mention of those, and also saw the sad face Morten Kromberg pulled in a presentation when he got to arrays containing instance references and how they're no longer "immutable"
@TessellatingHeckler :-) Production APL looks very different. My code golf posts are to get people intrigued that there exists a "real life" language with the expressive power of a golfing language.
@dzaima Not just Dyalog APL, btw.
@TessellatingHeckler It can be used for a few things. Officially it is called left/same but you can read it as "where", e.g. Y←X+2 ⊣ X←⍳10 "Y is X plus two where X is the integers up to ten".
Aha, that makes sense.
Diamonds for left-to-right feels more readable, because the definitions build up before they are used
@TessellatingHeckler Sure. Use whatever feels right, and you can mix'n'match too.
23:36
so I have a mutateString function, and I can each it over multiple strings with mutateString ¨ ('HELLO WORLD' 'ZZZ QQQ') which does work
and I can duplicate a string, sort of, with 4 {⍺ (≢⍵) ⍴ ⍵} 'hello' but if I try to mutateString over those, I get a rank error
@TessellatingHeckler that makes a matrix, which is very very different from a vector of vectors
@TessellatingHeckler That doesn't make a vector of "strings" (they are character vectors), but rather a matrix. applies f to the elements of an array (each of which is a vector in your first case), but now you want to apply f to the subarrays of one lesser rank, so use (f⍤¯1)
is it wrong to describe 'ABC' as a string?
also that reminds me of an idea for another extension to where some special value in ⍺ would specify copying the shape of ⍵, so that could be written as 4 {⍺ ⍬ ⍴ ⍵} 'hello' if were that special value
@TessellatingHeckler Colloquially, no, but people may get the wrong impressing that it is scalar. APLers tend to say "character vector"
@dzaima Ah, as opposed to supplying the missing value.
23:41
but not "codepoint vector"; I'm not even going to ask what happens to combining codepoints or surrogate pairs, ok character vector it is
1 dimensional
@TessellatingHeckler A character is a character. Unicode "just works".
and the reshape is a 2 dimensional character matrix
@TessellatingHeckler Correct.
@TessellatingHeckler if you want to get a vector of 4 character vectors, you could do 4 ⍴ ⊂'hello'
(dzaima is faster than me)
@TessellatingHeckler ⊂'hello' is more akin to what you would call a string, as it behaves as a scalar.
@dzaima ↑⍤⍴∘⊂ or (↑⍴∘⊂) without any extensions. Not as versatile, but often what you want.
23:48
I don't know why I'm nitpicking, but i.imgur.com/vo1Jh9z.png
a single codepoint e with an accent, and a two-codepoint e with a combining accent, should be one character and compare as equal
@dzaima So would x ⍬ y ⍴ z mean x (≢z) y ⍴ z or (x,(⍴z),y) ⍴ z?
@Adám my thought was that you'd need to specify as many s as the rank, so all could be filled in
@TessellatingHeckler That would require Unicode normalisation. The arrays are not the same.
which is why I suggested codepoint vector instead of character vector - they are the same character, but the arrays are not the same
@dzaima Ah, so if z is shape 10 20, you could do 3 ⍬ 4 ⍬ 5⍴z to get 3 10 4 20 5⍴z?
23:50
anyway, what was that interesting and relevant bit about vectors of vectors that I need to read
@Adám probably, or something of the sort. I haven't thought much about it in higher dimensions
@TessellatingHeckler I see, and good point. I think a case could be made for a utility to do Unicode normalisation, including an option for normalising case. Unfortunately, that makes the language definition depend on a third party table with periodic updates. Somewhat undesirable.
@TessellatingHeckler Heheh, see my name!
@TessellatingHeckler combining characters are a necessary, horrible evil.
even if e + combining character would be counted as a single character though, I feel like that a combined version and a raw character should still not be equal by default
@TessellatingHeckler If you have not already done so, you should definitely apply for a free licence for the full offline Dyalog APL system. Incidentally, the Windows IDE treats logical characters as separate characters, which looks odd, but helps keep things sane:
There was a discussion like this in the other chat room: chat.stackexchange.com/transcript/message/48084171#48084171. I'm with feersum on this one
23:58
@H.PWiz yeah, this reminded me of that. unicode in general is just horrible :p
@dzaima The alternative is worse.
@Adám well yeah, obviously, but that just says a thing about internationalization & languages as a whole

« first day (708 days earlier)      last day (2243 days later) »