Hm, the first three elements are 1 2 3 then I suppose you're calling those X, Y, Z (correct me if I'm wrong!) but it isn't true that 1=2 so we should return ⍬, no?
It is a dyadic operator, so it will bind the array or (single) function to its immediate right, and the array or function (phrase) on its left.
E.g. f∘g∘h is (f∘g)∘h
Similarly, +/⍣2 is (+/)⍣2
In other words, if you want a composite right operand, you need to parenthesise it. You do not need a parenthesis for a composite left operand.
Compare to functions: If you want a composite left argument, you need to parenthesise it. You do not need a parenthesis for a composite right argument.
E.g. =∘|⍥(2⊃⊢) and (2+3)×4+5
We only need to parenthesise ⍥'s right operand and ×'s left argument.
Tbh when I said "recommendations on how to improve it are very welcome" I mostly meant "how to make it more idiomatic", but a performance improvement showcase was a good surprise
@AndréLeria OK, but changing the picking into multiplication is more idiomatic, imo, and so is generalisation to higher ranks. Idiomatic APL tends to perform well.
@FawnLocke Yes, imo Key should have been a dyadic operator allowing you to give it an alphabet (or a function to compute the alphabet) as right operand. E.g. f⌸∪ for current f⌸ or f⌸{⍵[⍋∪⍵} for a sorted alphabet or {≢⍵}⌸'ACGT' for counting DNA bases.
"Historical" issues with APL were what made me look into BQN. But I think I still prefer APL (I don't know either enough, so I will still study both more)
BQN is very sensible, and is a natural improvement over APL from what we've learned is good design. I still use APL because the glyphs are prettier and Dyalog has an excellent ecosystem. HTTP requests, being able to create C bindings, html rendering & plotting, etc, etc. I don't think there's much you couldn't do in Dyalog (if, anything)
I'd risk saying Dyalog is such an improvement it can't even be compared to other APL distributions. I tried using GNU APL before Dyalog, but it's so limited
APL's historical issues aren't that bad, I think ⎕IO is the worst contender. It's mostly annoying because there's a lot of them, and through-out the course of a program it's easy to notice them stack up
@Adám Curious how you'd improve stencil.
At least with APL's issues they're directly apparent, compared to other languages where they might be hard to address due to many layers of abstraction
Continuing from my last message, I think this largely explains why so many people are interested in completing their own APL impl. Even beginner to intermediate APLers, such as myself, can find ways to improve or change the notation to benefit themselves. TLDR; APL's lack of abstraction is nice :)
First, I want to implement a programming language for almost 10 years. Even before I learned functional / declarative programming were things. And now, I learn about array programming, which has me amazed once more.
Second, APL seems relatively easy to implement, at least the basics. Of course, making a Dyalog 2 would be daunting, but I'm not that ambicious
@FawnLocke Yeah, while people recognise inconsistencies and bad design in other languages, but it is so much more noticeable in APL because things are so regular… so close to perfect.
@AndréLeria Yes, the core language is fairly easy to implement. It is the "packaging" that's hard. That's why I'm dreaming of Dyalog creating a switch for a fixed version, so that the same interpreter can execute both old and new code, and the two "languages" can share all the tooling, and can seamlessly call each other.
One thing that sometimes bothers me is that if a function has a large sub-function that manipulates its variables, and the outer function gets called in a loop, then if formulated as dfns, the sub-function must be defined inside the outer function. But this means that the large sub-function gets defined again and again, every time around the loop. With tradfns, the sub-function can be defined just once, outside the outer function.
@Adám I couldn't watch the webinar live and I just finished watching the recording. Nice animations, which really help to understand what's going on. Thanks, @Adám.
I think I'm just too deep into front-end reactive programming to be able to think of other ways of handling state
Which is kinda sad, I miss back-end development
How is APL used more often? To create full applications, or as a piece? (for example, to do some specialized computations via April inside a CL application)
My issues with it are mostly ideological though prefixing with ⊢⍤ isn't the end of the world. being able to pass a / to an operator which is later used itself as an operator is :/
@Adám not only because it's regular, but also because it has almost no syntax and no glue between language elements; some of the problems appear more strikingly visible because of APL's terseness. In other languages, you add a bit more glue (another function call) that hides problems under the rug.
@Adám I always get the impression that tradfn's look like imperative language, whereas dfn's (and even more so tacit) look like functional language. I think there's a beauty to behold in arrays+pure functions.
@FawnLocke isn't this an unintended consequence of the / glyph also being used for a function? I tried a few times with other operators whose glyphs are not overloaded and they are not being substituted to ⍺⍺. I get syntax error. @Adám, what do you say?
@AlexB Yes, absolutely. It is what Fawn had in mind too. It is solely because of /'s hybrid nature; preferring to be an operator; acting as function only while you force it to.
@Adám maybe we need to indicate operator arguments with ⍺⍺⍺ :-)
(in case we want to create meta-operators)
@Adám this is what a repeat...until typically do in Pascal and other languages. Condition is checked at the end. Those languages also offer while... constructs for this reason, but it is clearly a duplication.
But a more general solution is to have a clean way to arrayify functions (and de-arrayify them) so they can be passed around. Dyalog's way is really clunky. BQN's is better — I came up with it :-)
@Adám yes please! the fact that functions are not first-class citizens in APL bothers me, because you can have arrays everywhere and functions everywhere, except that you cannot have arrays of functions (which are very useful).