« first day (2599 days earlier)      last day (138 days later) » 

12:27 AM
@Marshall Thank you for creating apl.wiki/Direct_definition_(NARS) — is there documentation for this somewhere? Sounds similar to jsoftware.com/papers/APLDictionary1.htm#del too, which is also a likely precursor to code.jsoftware.com/wiki/Vocabulary/cor
1:02 AM
Yeah, it's the NARS manual, section 4.17.
I hadn't seen that in the dictionary. Yes, very similar. Interesting that it has that and (informally) direct definition.
I've been proposing "guarded guards" as a form of short-circuiting AND, e.g. {⎕NEXISTS ⍵:''≢r←⊃⎕NGET ⍵:r ⋄ 0}
Ah, Rationalized APL has it too, with a reference to an earlier conference paper.
But after reading about NARS's direct def, and contemplating things like BQN's , I'm thinking that maybe a better use of multiple colons in a dfn expression is to choose what to return, so 0: continues with the next statement, 1: returns what's to the right of the : while 2:not this:but this returns the second statement, etc. Thoughts, anyone?
But the APL conference was held October 1981, and the NARS manual's dated March 1981! What is going on?
1:17 AM
Wait, did NARS extend ⎕DL to negative numbers‽
The paper also starts off by proposing function assignment, which I'm thinking NARS didn't support since it's conspicuously absent in their examples. To the point of including D←'⍺÷⍵' ⋄ M←'1_⍵' then 3 (D∇M) 4.
1:45 AM
Well, a page name change is in order at least. "Direct definition (operator)" versus "Direct definition (notation)"? Iverson seems to have called the operator "function definition" or "verb definition", but that's ambiguous because of J's :, which I wouldn't consider to be the same thing.
@Marshall Growing up, the term "direct definition" was quite commonly mentioned and always refered to the notation, so I think that page merits being an unqualified name, and then the operator one can be "(operator)" but do we need a "(function)" too for Dictionary's?
It's an operator: it's under section VI. Conjunctions.
I made "Direct definition" disambiguate because J is now using that name, not for NARS.
@Marshall Indeed. My bad.
OK, then I think "(notation)" or maybe "(syntax)" — and yes, "(operator)"
(syntax) suggests it belongs to APL rather than being mostly external, so I'll go with (notation).
right
 
10 hours later…
 
1 hour later…
1:00 PM
Welcome to the last APL Quest, 2023-10! Today's quest is Partition with a Twist:
> Write a function that:
> • takes a non-negative integer left argument, N
> • takes a space-delimited character vector right argument, string
> • returns an array of length N where:
> ⠀○ if N is less than or equal to the number of sub-arrays in string, the first N-1 elements of the result are the first N-1 space-delimited partitions in string.
>  The Nᵗʰ element of the result is the remaining portion of string.
> ⠀○ if N is greater than the number of sub-arrays, pad the result with as many empty arrays as necessary to achieve length N.
I did not succeed with this one. Splitting the character vector is no problem and picking the first n is also not difficult. But appending the left over part is.
you can do it step by step
Wouldn't be surprised if this turns out to be two or three times as long as needed: {(⊢,(⊂'')⍴⍨⍺-≢)¯1↓¨⍵⊂⍨(⊢∧⍺≥+\)¯1⌽' '=⍵}∘(,∘' ')
Not terrible. The most impressively short solution from the competition was {1↓¨1↓⍺(↑,,/⍤↓)' '(,⊂⍨2,=)⍵}
I couldn't figure this one out. for the contest i had {¯1↓¨1↓(⍺+1)↑(2,2≠/⍺⌊+\(1,¯1↓' '=⍵))⊂(⊢,' '⍴⍨' '≠⊃⍤⌽)⍵}, though.
1:09 PM
Ah, I'd forgotten the numbers in the left argument to can be larger than 1
(no idea how it works)
@rabbitgrowth Right. I don't remember it, but I assume we chose this as the final (harder) problem to give the new extension feature a workout.
Here are another couple of nice ones from the competition:
{1↓¨⍺↑W⊂⍨⍺,⍨≠⍺⌊+\' '=W←' ',⍵}
{1↓¨' '(,⊂⍨⍺+\⍣¯1⍤,⍨⍺⌊1+\⍤,=)⍵}
Another thing I didn't know about :
> The maximum length of X is 1+≢Y, when the last element of X specifies the number of trailing dividers.
I should read the docs more.
I thought the lengths of the left and right arguments had to match exactly
@Adám ooh, that Unique Mask
@rabbitgrowth left can be short too, presumes trailing 0s
so you can do head and tail with 1 1⊂Y
Nice!
Why doesn't also allow short left arguments?
1:26 PM
It could, but it is mostly there for APL2-compatibility.
And further, for some reason, treats a 1-element vector left arg as a scalar, while didn't. So if we allowed short left args for then there'd be an inconsistency at length 1.
A complex one.
@Adám but this first one I can understand.
Amazing. Remember that most people think that's crazy/obfuscated/unreadable/unmaintainable…
@Richard You can keep working on your own solution and post it here when you're ready. I'll have a look before making the video.
If we are finished now, I would like to thank you and everybodies effort en adams nice video's etc. I really enjoyd it and learned a lot
@rabbitgrowth You could (not saying should) write (⊂'')⍴⍨⍺-≢as ''⍴⍥⊂⍨⍺-≢ until we get
@Richard Yeah, I'm not sure there's much to say about this problem, as it is a bit too big to go over in detail here in chat.
1:42 PM
@Adám I'll give it another go
@RubenVerg Because of prototypes, you can write ' '⍴⍨' '≠⊃⍤⌽ as ''⍴⍨' '≠⊃⍤⌽
So yeah, I guess this is it. It's been a (110-episode) blast, and I hope everyone found it worthwhile and learned things, and will continue onwards and upwards in their APL journey. Of course, we can all still hang out here and challenge each, not just on Fridays!
@Adám I did not understand this answer of you. What did you propose?
I'm in the process of adding explicit alternatives to the worst tacit APLcart entries. We could do it as a group effort at regular events.
Thats fine to me. This way we can contribute at least
@Adám Wouldn't ''⍴∘⊂⍨⍺-≢ also work, and avoid applying to ⍺-≢ uselessly?
1:53 PM
Ah, yes, since you're already commuting. Nice.
In fact, won't even help, as ''⊂⍛⍴⍨⍺-≢ doesn't bind right.
I am off now. @Adám just notify me/us if I can contribute on something
I'm off too. I'll keep you posted.
I feel the same as Richard. I really enjoyed this series and learned a lot. Thanks everyone!
same for me too, learned a lot. thanks!
 
2 hours later…
3:35 PM
try out the tinyapl interpreter! run with wasmtime
(help me find bugs)
not supported: stranding, trains, most primitives (the repl helpfully prints a list)
idk if it works on windows, its unicode support is kinda wonky
supported:
* dfns `{...}`, dadvs `_{...}`, dconjs `_{...}_`
* guards `cond:executed`
* early return statements (`■`)
* names and assignment (names must follow the convention: `abc` for arrays, `Abc` for functions, `_Abc` for monadic ops, `_Abc_` for dyadic ops)
* complex numbers (`⏨` for exponent notation, `ᴊ` for complex notation)
* character literals (`'abc'`) and strings (`"abc"`, plus `⍘` for escapes)
* arguments to dfns are `⍺` and `⍵`, left operand is `⍺⍺` if array and `⍶⍶` if function, right operand is `⍵⍵` if array and `⍹⍹` if function
4:13 PM
Not especially nice:
> (3*⊖1≠⍳3)
{ array with ⍴ = 3 and , = [3.0000000000000004,3.0000000000000004,1] }
although fortunately it'll be accepted as an integer array.
> -{⍶⍶ ⍵} ⍳10
Syntax error:Variable ⍶⍶ does not exist
But I did manage to construct a multiplication table:
> {s←2⍴l←≢⍵⋄((l*⊖1≠⍳3)↑(l+2=⍳3)⍴¯1↓,(l+1=⍳2)⍴⍵)×⍥(s∘⍴)⍵} ⍳4
{ array with ⍴ = 4 4 and , = [1,2,3,4,2,4,6,8,3,6,9,12,4,8,12,16] }
(in just O(n^3) time)
One way to catenate vectors:
> (2×⍳5) {S←(l←⍺+⍥≢⍵)∘⍴⋄m←(≢⍺)<⍳l⋄(S ⍺){⍺+m×⍵-⍺}⊖S⊖⍵} 1+2×⍳3
{ array with ⍴ = 8 and , = [2,4,6,8,10,3,5,7] }
4:39 PM
@Marshall yes, you'd spell this like -_{⍶⍶ ⍵} ⍳10
{} creates a dfn, _{} creates a d-monadic-op (and _{}_ creates a d-dyadic-op)
Got it, that makes sense.
No recursion?
> Sum←{0=≢⍵:0⋄(⊃⍵)+Sum 1↓⍵}
{...}
> Sum ⍳100
Syntax error:Variable Sum does not exist
@Marshall forgot (:
@Marshall impressive!
@Marshall (also, this is missing an Exit , guards by default don't return)
All right I don't think reduction's possible because I don't see a way to call an arithmetic function an arbitrary number of times. But you can sum a vector of natural numbers with ≢⍸a and take its product with ≢,⍳a, or ≢,a⍴0.
Well, I shouldn't throw out recusion so quickly; maybe there's a Z combinator. Although it doesn't seem likely with the array/function/operator system.
love how you've been trying to work inside the constraints!
@Marshall what's a Z combinator?
This thing, like the Y combinator but you don't need lazy evaluation.
4:59 PM
ah, a thing to do recursion?
i'm adding ∇ to dfns rn
Takes all the fun out of it really...
(: feel free to not use it!
⍸{(1↓⍵)-¯1↓⍵}⍸a is prefix sum of a vector of natural numbers, drops the last element although that could be fixed. And {(1↓⍵)-¯1↓⍵}⍸{(1↓⍵)-¯1↓⍵} is -inverse-ish, also dropping some stuff.
5:50 PM
Transpose←{t←3⍴r←⊖s←⍴⍵⋄r⍴(t*3≠⍳3)↑(t+2=⍳3)⍴¯1↓,(s+1=⍳2)⍴⍵}
Fl←{⍵-2÷⍨1+¯1⍟¯1*1-⍨2×⍵}
Pd←{n←≢⍵⋄⍵-(1≠⍳n)×(-n)↑(n+n-1)⍴⍵}
Ap←{n←1+≢⍵⋄r←n⍴⍵⋄r+(n=⍳n)×⍺-r}
SumRows←{Pd 1-⍨⍸Pd(≢⍵)Ap(⊃⊖⍴⍵)Fl⍤÷⍨0.5-⍨⍸,⍵}
SumRows is +/ on a matrix of natural numbers! Unfortunately the floor function Fl is not terribly accurate, so it's liable to get numbers that don't round to integers and break because of that.
if you redownload the file now it has support for (and _∇ and _∇_), but i have a feeling you won't use those
SumRows←{Pd 1-⍨⍸Pd(≢⍵)Ap 1-⍨1+(⊃⊖⍴⍵)Fl⍤÷⍨0.5-⍨⍸,⍵} is more reliable.
@Marshall oh, I'm missing monadic and ? that's definitely unintentional
@Marshall what do Pd and Ap do?
Pairwise differences, append (extra element goes on the left).
@Marshall (for completeness, stuff like {0=≢⍵:■0⋄(⊃⍵)+∇ 1↓⍵}⍳100 works now)
6:10 PM
All right, {⍸2=SumRows ⍵{s←⍺⍮⍥≢⍵⋄(Transpose s⊖⊸⍴⍺)=s⍴⍵},Transpose⊸×(2⍴≢⍵)⍴⍵} ⍳n should get primes up to n, but due to numerical issues the largest n I was able to use it with is 2.
No, it works on 4 and 6 as well!
Transpose←{t←3⍴r←⊖s←⍴⍵⋄r⍴(t+(1-t)×3=⍳3)↑(t+2=⍳3)⍴¯1↓,(s+1=⍳2)⍴⍵}
Fl←{⍵-2÷⍨1+¯1⍟¯1*1-⍨2×⍵}
Pd←{n←≢⍵⋄⍵-(1≠⍳n)×(-n)↑(n+n-1)⍴⍵}
Ap←{n←1+≢⍵⋄r←n⍴⍵⋄r+(n=⍳n)×⍺-r}
SumRows←{Pd 1-⍨⍸Pd(≢⍵)Ap 1-⍨1+(⊃⊖⍴⍵)Fl⍤÷⍨0.5-⍨⍸,⍵}
Primes←{i←⍳⍵⋄⍸2=SumRows i{s←⍺⍮⍥≢⍵⋄(Transpose s⊖⊸⍴⍺)=s⍴⍵},Transpose⊸×(2⍴⍵)⍴i}
Collected definitions; stopped using * for transpose as it doesn't always work.
7:12 PM
@Marshall I added floor and ceiling, now works for all numbers as far as I can tell
I've been trying to understand how these work but they're a bit too complicated for me
7:35 PM
I found a floor-less way to do +/ on a boolean matrix, although the shape management gets rather extreme.
T3←{m←≢⍵⋄n←⊃⊖⍴⍵⋄(m⍮3×n)⍴(n Ap m⍮3)↑((n×m)Ap m⍮4)⍴(-n)↓,(n Ap 4⍮m)⍴⍵}
CountRows←{m←≢⍵⋄t←3×n←⊃⊖⍴⍵⋄r←T3 ⍵⋄i←(⍴r)⍴⍸3⍴n⋄(1+n×1-⍨3×⍳m)-,(m⍮1)↑(m⍮-n)↑(m⍮2×n)⍴⍸,(r∧3≠i)≠(0=r)∧1≠i}
The 1D version is just {t←3×n←≢⍵⋄r←t⍴⍵⋄i←⍸3⍴n⋄(1+2×n)-1↑n↓⍸(r∧3≠i)≠(0=r)∧1≠i}.
In SumRows, the whole Pd 1-⍨⍸Pd(≢⍵)Ap thing is more or less ⍸⍣¯1, going around the square of power from "target indices" to "division lengths". So the floor-division thing gives you a list of row indices and this section adds up how many times each row appears.
All right, the version with floor is quite a bit faster.
Also, I noticed there's multidimensional , so SumRows←{Pd 1-⍨⍸Pd(≢⍵)Ap⊃¨⍸⍵} would work, except, I don't know how to do ⊃¨.
I could easily add ¨ but what's the fun in that? (:
Using nested arrays at all is a sign of moral decline, of course.

« first day (2599 days earlier)      last day (138 days later) »