Re: [Bug-apl] Non-bug: Help comparing solutions
On 5 March 2014 19:12, Daniel H. Leidisch 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.) As for tacit programming, I enjoyed reading Backus's FP and FL articles in college. But years later, when I had a chance to try that programming style with J I found it utterly unusable. 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. On 5 Mar 2014, at 12:24, Elias Mårtenson wrote: > What is a fork and a train? I've heard the expression before, but I don't > know what it is. 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. 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. 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. 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 :-) Tobia
Re: [Bug-apl] Rank operator and function assignment
Hi Juergen > how does NARS2000 define f⍤B and A f⍤B (the standard does not)? I can answer this. f⍤y is just the function that would be applied to B in f⍤y B, so that one can give it a name: g←f⍤y and then apply it: g B A f⍤B is a syntax error, because f⍤B becomes a function, which then lacks the right argument. > In GNU APL you can put the y in axis brackets to resolve the ambiguity. > I personally believe ⍤[y] B is a clearer syntax than ⍤y B. > > {'foo',⍵}⍤[1] 4 5⍴⍳10 This ambiguity between the right argument of the operator and that of the derived function (⍵⍵ and ⍵) or more rarely between the two left arguments (⍺ and ⍺⍺) is usually resolved using either parentheses around the derived function or using the right identity function ⊢ This is true even for other common operators: ⊂⍣3⊢⍳3 ⍝ enclose ⍳3 three times (⊂⍣3)⍳3 ⍝ same Parentheses around the right argument mean something else in dialects with "strands" such as Dyalog: ⊂⍣3(⍳3) ⍝ this produces the derived function ⊂⍣(3,⊂⍳3) which will give an error when applied I would be wary of bracket notation on the rank operator, because it has a different meaning in Nars2000 (which I'm not sure I understand entirely) see http://wiki.nars2000.org/index.php/Rank That page mentions conforming to ISO 13751, so I would check whether the bracket notation should have a particular meaning according to it (maybe where they define bracket notation in general?) Tobia
[Bug-apl] (no subject)
Hi I'd like to work on a beginner's documentation or tutorial on APL and GNU APL in particular. The website mentions: "A Quick start document for APL is planned but the work has not started yet. Is there any existing work I'd have to coordinate with? Or can I start from scratch? Tobia
[Bug-apl] Ctrl-D and )off
Hello Is there a reason why GNU APL does not exit on EOF, aka. Ctrl-D on cooked input? Every shell and interpreter I have ever used does so by default. Maybe there are people who are used to typing "exit" or "logout" by hand, but for those of us who have always hit Ctrl-D to exit from any interactive line-oriented application, GNU APL's persistent refusal to do so is quite annoying ;-) Even Bash, when it has background jobs still running (that would become orphaned or receive sighup) will print a warning at the first Ctrl-D, but comply without further ado at the second one. If there is no valid reason, meaning that it's just some historic behaviour of APL interpreters, I would suggest changing it so that it's more coherent with the rest of GNU CLI tools. If instead there are valid reasons, could there be an option in the preferences file to enable it? Tobia
Re: [Bug-apl] Ctrl-D and )off
Thank you Jürgen. I'm not sure values > 1 are working properly, but maybe that's just my system. I've set it to 1 anyways. As for the output messages, I suggest the attached changes, because 1) readline is already ending CIN on Ctrl-D, so we don't need to output another endl; 2) that "*** end of input" can be silenced with uprefs.silent ;-) Tobia Index: src/Command.cc === --- src/Command.cc (revision 516) +++ src/Command.cc (working copy) @@ -1120,7 +1120,6 @@ Command::cmd_OFF(int exit_val) { cleanup(true); - COUT << endl; if (!uprefs.silent) COUT << "Goodbye." << endl; exit(exit_val); } Index: src/LineInput.cc === --- src/LineInput.cc (revision 516) +++ src/LineInput.cc (working copy) @@ -727,8 +727,7 @@ { if (control_D_count >= control_D_count) { - CIN << endl; - COUT << " *** end of input" << endl; + if (!uprefs.silent) COUT << " *** end of input" << endl; Thread_context::kill_pool(); Command::cmd_OFF(2); // exit()s return; // not reached @@ -736,7 +735,6 @@ } else if (control_D_count < 5) { - CIN << endl; COUT << " ^D or end-of-input detected (" << control_D_count << "). Use )OFF to leave APL!" << endl; @@ -750,8 +748,7 @@ // of 10 ms or faster. That looks like end-of-input rather // than ^D typed by the user. Abort the interpreter. // - CIN << endl; - COUT << " *** end of input" << endl; + if (!uprefs.silent) COUT << " *** end of input" << endl; Thread_context::kill_pool(); Command::cmd_OFF(2); // exit()s return; // not reached
Re: [Bug-apl] Ctrl-D and )off
Actually, by setting CONTROL-Ds-TO-EXIT 1, I have to type it twice and I still get the message, plus the extra blank lines: $ apl ^D ^D *** end of input $ If I set it to 2, I have to type it 3 times, with the message, and so on. I have tried the latest svn head on both GNU/Linux and OS X. Tobia On Mon, Dec 22, 2014 at 12:31 PM, Juergen Sauermann < juergen.sauerm...@t-online.de> wrote: > Hi Tobia, > > thanks, fixed ^D count in SVN 517. > > Actuallly, we are not using readline. And the message should not occur if > you > set the control-D count > 0. I would leave the message as is because this > is a > rather unusual situation and the user should always be informed about it. > > /// Jürgen > > > On 12/20/2014 01:13 PM, Tobia Conforto wrote: > > Thank you Jürgen. > > I'm not sure values > 1 are working properly, but maybe that's just my > system. I've set it to 1 anyways. > > As for the output messages, I suggest the attached changes, because 1) > readline is already ending CIN on Ctrl-D, so we don't need to output > another endl; 2) that "*** end of input" can be silenced with uprefs.silent > ;-) > > Tobia > > >
[Bug-apl] Strange bug with /⍨ in a lambda
/⍨ by itself seems to work: (2|⍳3) / ⍳3 1 3 (⍳3) /⍨ 2|⍳3 1 3 But inside a lambda I get a syntax error: {(2|⍵) / ⍵} ⍳3 1 3 {⍵ /⍨ 2|⍵} ⍳3 SYNTAX ERROR λ1[1] λ←⍵/⍨2∣⍵ ^ ^ Tobia
Re: [Bug-apl] Bug in the parser?
Hello Sorry for opening a new post above, I did not realize this was already being discussed here. I'm far from being an APL expert, but I humbly believe the current behavior to be a bug. Consider this expression, where A and B are arrays (or scalars): A F / B If F is a function, then / should perform N-wise reduction (ISO 13751 §9.2.3, shown being used without parentheses.) But if F is an array, then A F is a nested array and / should perform the replicate function (§10.2.5, again shown being used without parentheses.) I'm not sure if the ambiguity inherent in the symbol / (and others) is mentioned anywhere in the standard. But I'm quite sure other APL implementations solve the issue by always treating / and other such symbols as operators. When such an operator receives an array as the left operand it will perform replication; otherwise it will perform reduction. This is also the only way an APL programmer may define a symbol like that, because a given name may only be defined to be either a function or an operator, not both. Tobia On Thu, Nov 27, 2014 at 10:56 AM, Jay Foad wrote: > Hi Jürgen, > > Thanks for doing the analysis. > > > 2. Alternatives > > - > > > > I have tested what happens if we would introduce a M M pattern into GNU > APL > > in order to > > get IBM APL2's behavior. > > I don't understand this bit. Monadic operators don't bind like this in > APL2. > > Surely the way to get APL2 behaviour is: > - never downgrade / to a function > - introduce an A M pattern to allow operators to have arrays as left > operands > > Jay. > >
Re: [Bug-apl] Bug in the parser?
Thanks. I understand that there is a tradeoff involving run-time lookahead. It's still not entirely clear to me why simple cases would parse correctly, even with a user-defined symbol as the left argument (A/B) while applying an operator would break the parser (A/¨B). I'll have to study the parser to understand the issue. In the meantime, I propose adding an explanation to the docs (see attached patch) since it's an implementation choice that differs from some other well-known APL interpreters. Tobia On Sun, Dec 28, 2014 at 7:43 PM, Juergen Sauermann < juergen.sauerm...@t-online.de> wrote: > Hi Tobia, > > I have fixed the special case > > {(2|⍵) / ⍵} ⍳3 > > that you reported, SVN 519. > > There remains a handful of border cases related to / ⌿ \ and ⍀ caused by > the ambiguity of these symbols > because, for example, function / parses differently than operator /. > > In order to avoid lengthy and complicated run-time lookaheads of the left > argument of / and friends, > GNU APL tries to resolve this ambiguity at ⎕FX time. This works well > except if the left argument is a > user-defined symbol, say *U*. In that case the rule in GNU APL is that > *(U)* is assumed to be a value > while *U* alone is assumed to be a function. Then *U/* takes / as an > operator (and *U/ *a derived function), > while* (U)/ *takes / as a function and *(U)* i.e. *U* its left argument. > > Neither the ISO standard nor the APL2 manual provide enough information to > cleanly resolve these border cases. > I have tried the "/ is always operator" approach earlier but it was > breaking quite a few GNU APL testcases > so I decided not to follow it. > > /// Jürgen > > > > On 12/28/2014 05:12 PM, Tobia Conforto wrote: > > Hello > > Sorry for opening a new post above, I did not realize this was already > being discussed here. > > I'm far from being an APL expert, but I humbly believe the current > behavior to be a bug. Consider this expression, where A and B are arrays > (or scalars): > > A F / B > > If F is a function, then / should perform N-wise reduction (ISO 13751 > §9.2.3, shown being used without parentheses.) But if F is an array, then A > F is a nested array and / should perform the replicate function (§10.2.5, > again shown being used without parentheses.) > > I'm not sure if the ambiguity inherent in the symbol / (and others) is > mentioned anywhere in the standard. But I'm quite sure other APL > implementations solve the issue by always treating / and other such symbols > as operators. > > When such an operator receives an array as the left operand it will > perform replication; otherwise it will perform reduction. > > This is also the only way an APL programmer may define a symbol like > that, because a given name may only be defined to be either a function or > an operator, not both. > > Tobia > > > On Thu, Nov 27, 2014 at 10:56 AM, Jay Foad wrote: > >> Hi Jürgen, >> >> Thanks for doing the analysis. >> >> > 2. Alternatives >> > - >> > >> > I have tested what happens if we would introduce a M M pattern into GNU >> APL >> > in order to >> > get IBM APL2's behavior. >> >> I don't understand this bit. Monadic operators don't bind like this in >> APL2. >> >> Surely the way to get APL2 behaviour is: >> - never downgrade / to a function >> - introduce an A M pattern to allow operators to have arrays as left >> operands >> >> Jay. >> >> > > slash_docs.patch Description: Binary data
[Bug-apl] Base64
Hi Jürgen, here's a little fix. The base64 chars had S and T misplaced. Tobia --- src/QuadFunction.cc(revision 520) +++ src/QuadFunction.cc(working copy) @@ -413,8 +413,8 @@ const ShapeItem full_quantums = B.element_count() / 3; const ShapeItem len_Z = 4 * ((B.element_count() + 2) / 3); Value_P Z(new Value(len_Z, LOC)); - alpha = "ABCDEFGHIJKLMNOPQRTSUVWXYZ" - "abcdefghijklmnopqrtsuvwxyz" + alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; const Cell * cB = &B.get_ravel(0); loop(b, full_quantums) // encode full quantums
[Bug-apl] Lambdas
Hello It semes the parser does not like it when I juxtapose two lambdas: {⍵} ⊢ {⍵} 3 3 {⍵} {⍵} 3 SYNTAX ERROR {⍵}λ1 3 ^ ^ Is this related to function / operator parsing? Tobia