« first day (1913 days earlier)      last day (164 days later) » 

1:05 AM
@Adám Well, thanks for helping with it
5 hours later…
5:53 AM
What are good ways to deal with an argument being either a vector of characters or a single string scalar when trying to partition? For example, the following expression partitions to words by including only alphabet characters, but it fails to work with a single character input:

{(⍵∊(⎕A, ⎕C ⎕A))⊆⍵}'hello, world' ⍝ working as expected

{(⍵∊(⎕A, ⎕C ⎕A))⊆⍵}'a' ⍝ RANK ERROR
6:48 AM
Try using ravel (i.e. ,) on ⍵ to ensure you have a list.
@doug 0
@doug 1
It can be confusing that the syntax for a scalar character resembles the syntax for a character vector.
7:17 AM
]box on -style=max is useful to get proper visual data on an array
2 hours later…
9:14 AM
@doug good one, thanks!
1 hour later…
10:24 AM
So much good advice, thanks! Yeah, ravel is much nicer than (≢⍴⊢)
1 hour later…
11:45 AM
When reducing over a vector, using a tacit function for the reduction is robust enough to deal with the empty case:


But when using a dfn, and trying to use ⍺ or ⍵ directly, APL doesn't like it:


I'm trying to join an array of words with space as a delimiter, using reduce. When using a dfn it works as expected, but again, except for the empty vector case:

⊃{⍺,' ',⍵}/'hello' 'world'
hello world
⊃{⍺,' ',⍵}/''
⊃{⍺,' ',⍵}/''

I assume that if I use a tacit form, it will take care of the empty vector case, but I'm not sure how to write suc
12:42 PM
@BoazC For one thing, your standard argument here is a nested vector of character vectors, while your "empty case" is an empty character vector
whereas an empty equivalent of your regular input would be ⊂'' or ⊂,'' I think
You can check the depth of the argument with ≡⍵ and you can pre-process your argument with "enclose if simple" ⊆⍵ to make sure it's nested
Interesting point about the dfn vs tacit + though, I'll have to ask @Adám because, apart from special code, I'm not really sure what's up with that
I'm guessing it's because the 'terp "knows" that the identity for + is 0, but doesn't "know" what the identity for a given dfn is, so can't apply it to an empty vector
given dfn → arbitrary function is what I meant
@RikedyP in task 2, question 3, phase 2 of the competition problems, the description states "the number of people who registered but did not attend either day that year". I find that a bit ambiguous. Does it mean "registered, but failed to show on one or both days" or "registered, but failed to show both days"?
⋄,⍉('here' 'there'),[.5]' '
│here│ │there│ │
@xpqz the 2nd one
@RikedyP ok, great! thanks
How many days must I miss to be a no-show, 1 or 2?
12:50 PM
ignore that last thing
Using reduce to join strings feels more functional than array-oriented.
@doug There is a nice example I like to use when comparing AOP vs FP which is this
I'll paste it now
and maybe I made a video? if not I'll make a video and/or blog about it
Join←⊃(⊣,' ',⊢)/
Join 4↑' 'Split'take the first four words'
@RikedyP Nice!
{⍵⌿⍨4≤+\' '=⍵}
Conor Hoekstra (@code report) already has these examples in a couple of videos, but I would make a 5 min one framing it as a direct comparison
@xpqz FWIW, I posted to an issue on Learning APL.
12:55 PM
@doug thank you -- it's on my list of things.
Cool. Just wanted to make sure you saw it.
@RikedyP I think MDAPL mentions the laminating trick I posted above. Obviously it leaves a trailing space but that’s easy to deal with.
@doug I have so much more to learn :-)
@doug oh yeah - didn't see that sorry. You can also code it as 1↓∊' ',¨
@RikedyP Yeah, this is probably a wrong assumption based on a single example. When trying the tacit way of an empty vector reduction, it also fails with a DOMAIN ERROR.
@BoazC That’s what keeps it fun!
1:25 PM
@BoazC FWIW, ⍣≡ is another cool trick.
⋄,/⍣≡⍉('here' 'there'),[.5]' '
│here there │
@doug @RGS I checked the .ttf file I serve against the one from apl385.com/fonts -- and they are indeed different, as you suspected. Not sure how I managed to screw that up.
It keeps on applying the function until it stabilizes.
Cleaning up from here isn’t hard.
@xpqz It looks like you might have downloaded the page referring to the font instead of the font itself.
@doug oh dear gods, yes
1:42 PM
@doug Brilliant
@xpqz Looks great now!
@doug It works?
1:59 PM
@xpqz ahahaha that's brilliant 🤣
Well well well
who's ready for another riveting round of APL problem solving?!
@RikedyP I am 🖐️
nevermind... it's in 1 hour
15:00 UTC ≠ BST
silly clocks
@RGS I deserve any ridicule you want to dish out.
@xpqz I don't want to dish out, but I did smile when I read the explanation for your mistake!
2:46 PM
@RikedyP Where is this going to take place?
@BoazC here
Oh, nice :-)
Alright time for take 2
Welcome to the APL Quest! Today's quest is How Tweet It Is:
> Write a dfn which takes a character vector and removes the interior vowels from each word.
i am not ready for this one at all...
anyone care to start the bidding?
3:00 PM
{{⍵/⍨⌽(1@1)⌽(1@1)~⍵∊'AEIOUaeiou'}¨⍵⊆⍨' '≠⍵}
But as explained, edge cases not ok :(
And my attempt to do it without regex: ⊢(/⍨∘~)(((((0,⍨1↓⊢)∧0,¯1↓⊢)∊∘⎕A)∧∊∘'AEIOU')1∘⎕C)
ok @Richard give me a moment to parse yours, @rabbitgrowth yours is similar to a couple I have prepared (thanks @Adám)
also @Richard looks like you'll want to do some joining with spaces (see conversation from earlier today, above, on how to do this)
Okay so the nice thing here is that all of these pretty literally take the problem description and translate it into code
@RikedyP I'll have a look at that.
3:03 PM
@Richard splits into words (classic idiom is ' '(≠⊆⊢)⍵) and then looks for vowels but overwrites the starting and ending characters
Here's mine (not working on a single character case): {¯1↓∊,⍉({(1↑⍵),((¯1↓1↓⍵)~'aeiouAEIOU'),¯1↑⍵}¨(⍵∊(⎕A,⎕C ⎕A))⊆,,⍵),[0.5]' '}
I believe the single char workaround is to basically just ravel your input, unfortunately
The single char case gives me a wrong result (it doubles the character).
@RikedyP yes that worked.
But the empty vector is more difficult, cause ⊆ doens't like that
But I have a feeling that we are going to see a binary array that will compress the original input soon ;-)
3:07 PM
@Richard ⎕←' '(≠⊆⊢)''
@RikedyP Response looks like a 3-by-0 matrix.
@xpqz Okay before we get golfy I just want to cover a couple more verbose and shifty ones
{{⍵/⍨(⍵∊'aeiouAEIOU')⍲(⊢∧⍥~1∘⌽∨¯1∘⌽)' '=⍵}' ',⍵,' '}
the shifting @rabbitgrowth does with dropping can be achieved with rotate, but then you have to surround with spaces... :(
First time anyone's called me 'golfy'. I feel grown-up.
@xpqz lol
3:09 PM
oh wait nevermind, you're also surrounding with 0's so same diff
Adam follows the same principle, but with just drops:
{⍵/⍨(⍵∊'aeiou')≤¯1↓∨⌿' '=0 1 2↓⍤0 1⊢' ',⍵}
@BoazC you'll have to give me a moment to parse this one also, sorry
Oh wow, (⍷⍨∨⌽)⍣2 is really nice
@BoazC And actually, it looks like the principles covered in this part of the conversation basically apply here - you can use a more "functional" approach which is likely to involve nesting
but to keep it flat is better
@BoazC Yeah the issue here appears to be your "putting back" of the original boundary letters. with a single char it indeed duplicates
@RikedyP Exactly
@xpqz I think you're supposed to keep the first and last letters of every word, not the entire string
@BoazC in which case, you'll note that most other approaches here get to a Boolean vector fairly early on and manipulate that, rather than directly on the characters
Alright I have a couple of stencils and another regex left, but @xpqz would you care to explain (⍷⍨∨⌽) ?
3:19 PM
yes please :)
'⋄ {⍵/⍨(⍷⍨∨⌽)⍣2~⍵∊'aeiou'}, 'This is a test''
@Richard Did you forget to add backticks around your code (`⋄ code`)? You can edit your message and I will edit my reply.
although there does seem to be one issue...
@xpqz sadly it's chopping the "u" off of "you" in the example no?
⋄ {⍵/⍨(⍷⍨∨⌽)⍣2~⍵∊'aeiou'},'if you can read'
@RikedyP if y cn rd
And it drops the word 'a' in my example
as far as I can tell, ⍷⍨ is just doing 1@1?
and then it's not exactly obvious to me how just reverse can know anything of value about the word boundaries...
is this just a coincidence that it looks like it almost works?
3:23 PM
I think so, (⍷⍨∨⌽)⍣2 just makes the first and last numbers 1
Hmm. Must have bungled it.
@rabbitgrowth but how?
But yes, (⍷⍨∨⌽)⍣2 sets first and last to 1
@xpqz yeah I was surprised it was so short, but looking now there's no mention of either ⍵∊⎕A or ' '=⍵ or anything
@xpqz oh so this could work as part of a solution like @Richard had
if you apply it to each of the words after splitting
I've dropped the split on space
3:25 PM
then it's just an obfuscated ⌽1@1⌽1@1 (which I must now try to think of a cleaner way)
I mean if you make a temporary variable, 1@(1,≢s)⊢s works fine
⍷⍨ is a binary vector of length of its arg, of all 0 but the first 1
@xpqz ah now that is a good golfing tip
OR with the reverse, twice
@xpqz It works better compared to 1@1 because thats falls on an empty vector
{{⍵/⍨⌽(⍷⍨∨⌽)⍣2~⍵∊'AEIOUaeiou'}¨(,⍵)⊆⍨' '≠⍵} 'This is a test'
It now works on emtpy vectors and a single letter
3:29 PM
@Richard indeed, pretty nice! although perhaps in production you'd just explicitly check? at least you'd have to comment the reason for using ⍷⍨∨⌽
@Richard Isn't splitting by spaces instead of by alphabet problematic with input like: 'hello, there'? Won't the 'o' in 'hello' be considered in the middle of the word and be dropped?
@BoazC Yes, and this is a common point made with a few text processing problems in the competition
so you've basically got to decide if you want a dictionary of non-word characters or a dictionary of word characters
because you might want áâà etc.
@BoazC yes that's true!
@rabbitgrowth or, as we'll see just now...
@Richard Looks like you put an extra in there, after ⍵/⍨?
3:32 PM
What constitutes a vowel differs between languages, too
@rabbitgrowth I have a regex but can you explain ?<= in yours first?
@rabbitgrowth Yes, I mirrored the vector to change the first position again, and then mirrored it again to be in the orriginal order, before doing the binary mask
(?<=...) is positive lookbehind and (?=...) is positive lookahead, so (?<=\w)[aeiou](?=\w) means "vowel surrounded by letters"
@rabbitgrowth ah thanks ! was needing lookarounds earlier but didn't have time, I'll see if I can use it in my other thing
@rabbitgrowth ah, sorry. Now I see what you mean. A left over from the original wrong solution.
3:35 PM
interested to compare these actually:
'\b.|.\b' '[aeiou]' ⎕R'&' ''⊢
(?<=\w)[aeiou]+(?=\w) maybe?
For repeated vowels?
..or maybe that comes out in the wash..
@xpqz doesn't matter apparently
the one above says: "if boundary, replace with match, else if vowel, replace with nothing, else do nothing (leave alone"
@rabbitgrowth's is better and faster for using regex properly and only invoking a single pattern
Okay if there's nothing else, let's finish up with our friend stencil:
{⍵/⍨{' '∊⍵:1 ⋄ ~⍵[2]∊'aeiou'}⌺3⊢⍵} this version returns bitmask
∊{' '∊⍵:2⊃⍵ ⋄ ⊂⍵[2]~'aeiou'}⌺3 this one uses the same logic but returns the characters we want to keep
Didn't know you could use multiple patterns like that with ⎕R
@rabbitgrowth Yeah, check out this example of swapping two substrings: 'ab' 'ra'⎕R'ra' 'ab'⊢'abracadabra'
⋄ 'ab' 'ra'⎕R'ra' 'ab'⊢'abracadabra'
@RikedyP raabcadraab
3:41 PM
Cool! Learned a lot today :)
I feel like the first stencil shouldn't need a diamond...
Don't understand the stencil operator, but should study it first perhaps
Ok, which version wins the drag race?
My tip: not stencil.
@Richard this applies to overlapping length-3 windows
if there is a space, we're leaving alone (either we are the space or we are next to one)
⋄ 3,/'hel lo'
│hel│el │l l│ lo│
3:44 PM
It's like this catenate windowed-reduce
well it applies to windows like this, but with the contents as ⍵, where as windowed- reduce has a different structure provided to the operand:
⋄ 3{⊂⍺⍵}/'hel lo'
│││h│┌──┐│││││e│┌──┐│││││l│┌──┐│││││ │┌──┐│││
│││ ││el││││││ ││l ││││││ ││ l││││││ ││lo││││
│││ │└──┘│││││ │└──┘│││││ │└──┘│││││ │└──┘│││
Well unless someone else is able to figure out if this can be done with 3F/ for some function F, I think we'll leave it there fore today
Sometimes my learning proces feels like one step forward and two back, but really enjoying it
that was a meaty one
3:51 PM
Interesting. So when the window size is 3, the operand is being called twice!

⋄ `3{⍺,'-',⍵}/'hel lo'`
@Richard the hardest part at that point for me feels like knowing which approach to use in which scenario, but once it starts to "feel right" it's quite satisfying
sometimes you can never be sure, and just try to write something that works and makes sense to you
@BoazC wrap it in backticks `
⋄ 3{⍺,'-',⍵}/'hel lo'
│h-e-l│e-l- │l- -l│ -l-o│
Yes exactly, thanks for today
@BoazC well its called (¯2+≢⍵) times, no?
@RikedyP Twice per window I meant
3:54 PM
@BoazC still not quite sure I follow...
there is that the arguments seem to have as the first element and as the last two
and in fact for all windowed reductions it's like that
⋄ 5{⍺,'-'⍵}/'123456789'
││ │ ││2│-│┌─┬─┬───┐││││ │ ││3│-│┌─┬─┬───┐││││ │ ││4│-│┌─┬─┬───┐││││ │ ││5│-│┌─┬─┬───┐││││ │ ││6│-│┌─┬─┬───┐│││
││ │ ││ │ ││3│-│4-5│││││ │ ││ │ ││4│-│5-6│││││ │ ││ │ ││5│-│6-7│││││ │ ││ │ ││6│-│7-8│││││ │ ││ │ ││7│-│8-9││││
⋄1 1⊂'12345'
For every window of 3 characters, there's a reduction iteration that happens twice. The first time it's called with the first and second. The second time it called with the result of the previous iteration, and the last element. That's why there are two dashes in the example above, no?
@BoazC ah yes ! okay I see what you mean now
sorry, that was my brain being slow
3:58 PM
@RikedyP ⋄5{⍺,'-',⍵}/'123456789'
You missed a comma
Thank you. I learned so much today.
@BoazC sorry - I really am being slow - the truth is that the definition is F/⍵ applies on each size N window
⋄ {⍺,'-',⍵}/¨3,/'hello'
4:01 PM
Yeah, that makes total sense!
but, you know, with something about the shape not being quite that nested... I think
anyway I have to bounce now
thank you all so much for participating, I'm sure @Adám will enjoy reading this and making a video
see y'all around !
⋄ (⊃{⍺,'-',⍵}/)¨3,/'hello'
1 hour later…
5:32 PM
how do i list vars and assign a var with it inside a namespace?
2 hours later…
7:40 PM
not sure if this is what you are looking for:
a←2 2⍴⍳10
1 hour later…
9:05 PM
@BrianBED For a namespace N, you can do:
      N.⎕NL 2
to list the vars, and to assign vars into the space. Alternatively you can use )cs N to step into N, and do )Vars and unqualified assignment.
)cs N
Var     Var2
Same technique for named and unnamed namespaces.
@PaulMansour ah ⎕NL was exactly what i was looking for! thanks a lot :D
btw, N.⎕NL 2 did make my ⎕SI 508000 which did break the interpreter but hey, ⎕NL by itself works wonders.
funnily enough my RIDE session says syntax error when i press the close window button
1 hour later…
10:23 PM
@RikedyP I missed the discussion, but here's what I had: {(⊢{⍵/⍺}((~∊∘'aeiou'∧((1↓¯1∘⌽∧⊢∧1⌽⊢)(0,(819⌶⎕A)∊⍨⊢)))819⌶))⍵}
I had to use 819⌶ for ⎕C to make it Dyalog 17 compatible.
1 hour later…
11:36 PM
It’s surprising that the simpler {(⊢{⍵/⍺}((~∊∘'aeiou'∧((1↓∧⌿)¯1 0 1⌽⍤0 1(0,(819⌶⎕A)∊⍨⊢)))819⌶))⍵} is actually longer.
But I think golfing is over-valued…

« first day (1913 days earlier)      last day (164 days later) »