On 6 March 2014 08:01, Tobia Conforto <[email protected]> wrote:
> On 5 March 2014 19:12, Daniel H. Leidisch <[email protected]> wrote: > > > Jokes aside, while I'm all in favor of such extensions for tacit > > programming (composition, currying, hooks/forks/trains, as in NARS2000, > > NGN, newer versions of Dyalog, J), I think proper lambdas are a much > > more important and fundamental issue. > > I feel the same way. Lexical scoped d-fns are what keeps APL a modern > language. They are much easier and safer to work with, not to mention more > powerful. I heard on a recent conference video that younger APL programmers > don't even bother looking at traditional ∇ functions (I certainly subscribe > to this view.) > I agree. It's kinda sad in a way because I really think my external function editor in the Emacs mode is nice, but I find myself not using it much in favour of the lambdas. > Even the classic example of a fork (+/÷≡) is harder to read than its > functional version {(+/⍵)÷≡⍵} and it goes downhill from there with longer > trains. But maybe it's just me being unfamiliar with the syntax. > Did you intend to use ⍴ instead of ≡ there? I can't see how {(+/⍵)÷≡⍵}could ever be useful? > They are expressions made by juxtaposing functions by themselves, without > any explicit arguments. They were invented in J to allow for a programming > style called function-level or point-free programming (or "point-less" as > Wikipedia suggests.) They were then ported to Nars2000 to experiment with > them in APL. > Is "point" a J concept of which I am not aware? > Two juxtaposed functions (f g) are called a "hook" and if I'm not > mistaken, they behave like the classical jot composition f∘g which in most > interpreters means {⍺ f g⍵}. Compare it to "hoof" composition f⍥g as > implemented in Nars2000 (or "paw" f⍤g in Sharp APL) which means {(g⍺) f > g⍵}, leaving aside considerations about rank, which complicate matters. For > completeness, "hoof" f⍥g in Sharp APL means something else entirely: {f > ⍺g⍵}. Notice how the explicit functional syntax {...} is always the > clearest and less ambiguous one. > I agree. I somehow feel the hook syntax to be somewhat pointless(:-)). That said, there may be some opportunity for optimisation by the interpreter if it doesn't have to run arbitrary lambda functions? > Three functions (f g h) are called a "fork" and behave as {(⍺f⍵) g ⍺h⍵}. > Of all these, the fork is the only one that has a basis in traditional > usage, where functions are sometimes applied between other functions in a > kind of "shorthand" to yield new ones: f + g traditionally means the > function {(⍺f⍵) + ⍺g⍵}. This isn't necessarily a good thing though, given > that APL was invented to overcome the idiosyncrasies of traditional math > notation. > I can understand these forks if they were invented before the introduction of lambdas, but with anonymous functions, I just don't see how these forks are in any way useful. And it seems we are in agreement on this. > Longer sequences are called "trains", but IMHO they get harder to read as > their length increases. Notice the different purpose of functions in odd > and even positions in the trains, but also the qualitative difference > between dyadic trains with odd and even numbers of functions: > > Monadic trains: > > (X A) ≡ {⍵ X A⍵} > (B X A) ≡ {(B⍵) X A⍵} > (Y B X A) ≡ {⍵ Y (B⍵) X A⍵} > (C Y B X A) ≡ {(C⍵) Y (B⍵) X A⍵} > (Z C Y B X A) ≡ {⍵ Z (C⍵) Y (B⍵) X A⍵} > (D Z C Y B X A) ≡ {(D⍵) Z (C⍵) Y (B⍵) X A⍵} > > Dyadic trains: > > (X A) ≡ {⍺ X A⍵} > (B X A) ≡ {(⍺B⍵) X ⍺A⍵} > (Y B X A) ≡ {⍺ Y ( B⍵) X A⍵} > (C Y B X A) ≡ {(⍺C⍵) Y (⍺B⍵) X ⍺A⍵} > (Z C Y B X A) ≡ {⍺ Z ( C⍵) Y ( B⍵) X A⍵} > (D Z C Y B X A) ≡ {(⍺D⍵) Z (⍺C⍵) Y (⍺B⍵) X ⍺A⍵} > > I hope you can see the "point-less" programming style :-) There are no points to be found where I'm looking. Thank you for the clarification! Regards, Elias
