Re: [Bug-apl] Non-bug: Help comparing solutions

2014-03-05 Thread Tobia Conforto
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

2014-03-05 Thread Tobia Conforto
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)

2014-12-04 Thread Tobia Conforto
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

2014-12-17 Thread Tobia Conforto
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

2014-12-20 Thread Tobia Conforto
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

2014-12-22 Thread Tobia Conforto
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

2014-12-28 Thread Tobia Conforto
/⍨ 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?

2014-12-28 Thread Tobia Conforto
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?

2014-12-29 Thread Tobia Conforto
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

2014-12-29 Thread Tobia Conforto
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

2014-12-30 Thread Tobia Conforto
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