Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Please justify-who is right?

20 views
Skip to first unread message

Pol...@acm.org

unread,
Nov 19, 2009, 1:39:02 PM11/19/09
to
The following expressiion 2 // 2 4 1 3 7
produces a different result in all five versions of APL.. Could all
justify your result? (who is right?)

APL2: Valence error
Dyalog APL: the nested vector 4 4 1 1 1 1 3 7 7 7
APLX: a simple vector of 16 sevens
APL+WIN: Nonce error
VisualAPL: 2

Jane Sullivan

unread,
Nov 19, 2009, 2:02:27 PM11/19/09
to
I guess this has something to do with the interpretation of //

I read it as "replicate reduce"
In Dyalog APL,
n fn / arg
applies function fn to the argument with the elements taken n at a time.
In this case, the // derived function is applied to 2 4 1 3 7, with
items taken 2 at a time, i.e.
(//2 4)(//4 1)(//1 3)(//3 7)
which, from the definition of the / (reduce) operator, becomes
(2/4)(4/1)(1/3)(3/7)
i.e.
(4 4)(1 1 1 1)(3)(7 7 7)

Is this right? I think "yes".

If we omit the leading left operand 2,
//2 4 1 3 7
returns a vector of 24 sevens, which is the same as
2/4/1/3/7.

Do the other APLs allow a left operand to reduce?
--
Jane

<Pol...@acm.org> wrote in message
news:009a4c49-4860-4e94...@j9g2000vbp.googlegroups.com...

James J. Weinkam

unread,
Nov 19, 2009, 9:10:12 PM11/19/09
to
According to the language specification used by APL2, / is a monadic operator.
If its left operand is a dyadic function, the operator is called reduce and
the derived function is ambivalent. Used monadically it is simple reduction,
e.g., +/ yields summation; used dyadically it is n-wise reduction. If the left
operand is an array, the operator is called compress if the array is boolean
otherwise it is called replicate. In the example at hand, the rightmost slash
has as its left operand the derived function of the leftmost slash whose left
operand is a non boolean array. This is therefore replicate, which yields a
monadic derived function. Since the rightmost slash requires either an array
or a dyadic function as its left operand, the supplying of a monadic function
is a valence error.

I don't know enough about the language specifications used by the other
versions of APL listed to offer an explanation for those results.

David Liebtag

unread,
Nov 19, 2009, 11:35:59 PM11/19/09
to
APL2's binding rules cause the 2 on the left to be bound with the left slash
to produce the derived function 2/

2/ is then applied with the reduce operator.

Reduce requires a dyadic function.

2/ is monadic.

Hence, Valence Error.

For further information about APL2's binding rules, consult Chapter 3.
Syntax and Expressions, Evaluating Expressions, Name and Symbol Binding in
APL2 Programming: Language Reference, SH21-1061 which is available at this
URL:

http://www.ibm.com/software/awdtools/apl/library.html

David Liebtag
IBM APL products and Services


AAsk

unread,
Nov 19, 2009, 11:56:07 PM11/19/09
to
In Visual APL, // is equivalent to the APL lamp i.e. it denoted the
start of a comment. Therefore. the (executable) expression is simply
scalar 2 - hence the result.

Bob Smith

unread,
Nov 20, 2009, 5:03:48 PM11/20/09
to

...and what does

2 / / 2 4 1 3 7

(note the extra space) do?

--
_________________________________________
Bob Smith -- bsm...@sudleydeplacespam.com

To reply to me directly, delete "despam".

AAsk

unread,
Nov 20, 2009, 6:26:33 PM11/20/09
to
.. the extra space Bob mentions separates the pair of /

the result is 2 2 4 4 1 1 3 3 7 7

With Visual APL, // (consecutive /) marks the start of a single line
comment as APL lamp does; separating consecutive / by a space returns
it to APL 'behaviour'.

Bob, what does NARS make of this expression?

James J. Weinkam

unread,
Nov 20, 2009, 7:56:54 PM11/20/09
to
AAsk wrote:
> .. the extra space Bob mentions separates the pair of /
>
> the result is 2 2 4 4 1 1 3 3 7 7
>
But that is what 2/2 4 1 3 7 should produce; what is the role of the extra slash?

How does Visual APL define /? Is it always an operator as in APL2? Does it
require a function left operand to be dyadic?

James J. Weinkam

unread,
Nov 20, 2009, 8:07:58 PM11/20/09
to
David Liebtag wrote:
> APL2's binding rules cause the 2 on the left to be bound with the left slash
> to produce the derived function 2/
>
> 2/ is then applied with the reduce operator.
>
> Reduce requires a dyadic function.
>
> 2/ is monadic.
>
> Hence, Valence Error.
>
We both came up with the same explanation based on our understanding of the
manual. However, after reading some of the other replies in this thread, I
decided actually to try the expression in APL2 for OS/2, Service level 19.
APL2 for OS/2 gives a DOMAIN error (which also makes sense but might be more
likely to puzzle the user).

The OP did not state which version of APL2 gave a VALENCE error.

David Liebtag

unread,
Nov 20, 2009, 11:46:19 PM11/20/09
to
We have been working on cleaning up the workstation interpreter so the
errors more accurately mimic mainframe APL2 behavior. This is one of those
cases. If you had a recent Workstation APL2 service level rather than APL2
for OS/2, which has not had service for many years, you would see Valence
Error.

David Liebtag
IBM APL Products and Services


Morten Kromberg

unread,
Nov 21, 2009, 4:42:08 AM11/21/09
to

I don't think that I can justify who "is right", but I'll try to
discuss what is happening in Dyalog APL in a bit more depth:

/ is an "ambivalent symbol" in Dyalog APL: When it has an array on the
left, it is a function (replicate), when there is a function on the
left it is an operator. This is hard work for our parser, and perhaps
a source of mild embarassment at the theoretical level. Until
recently, I was in favour of trying to clean this up if an opportunity
should arise (we are considering starting the implementation of a
completely new APL interpreter in the near future - come to APL2010 in
Berlin to hear more about this ;-)).

However, when the discussion about "what an operator reallly is" arose
during the writing of Bernard Legrands new APL book "Mastering Dyalog
APL" (which we hope should be available from Amazon very soon),
Bernard and others argued quite convincingly that this was indeed "the
most useful definition" for users, and that your average APLer on the
street is actually more comfortable with the idea that something is a
function if given data and an operator when given a function, than
with replicate being an operator. Many - perhaps most - APLers think
that the defintion of an operator *is* "something that takes a
function as one of its arguments". There is no question in my mind
that the Dyalog definition is "more useful" than forcing the slash
always to be an operator: Dyalog APL gives a ...ah ... useful result
in Ray's example, and also allows you to use replicate with each (or
other operators), for example:

vowels←'aeiou'
string←'hello'
m←string∊vowels
(m (~m))/¨⊂string
eo hll

On the other hand, it is trivial to use a "dfn" to force / "into a
function" even if it were always an operator:

(1 0 1) (0 1 0) {⍺/⍵}¨'ABC' 'DEF'
AC E

... and we could idiomize the above to avoid any performance
penalty... So perhaps this slightly odd definition is not worth
hanging on to... But if it really is true that most quote ordinary
users unquote feel comfortable with the ambivalent definition, there
seems no reason to change things...?

Finally, given unicode, we could perhaps come up with two different
symbols (make that four to include reduction/replication along the
first dimension)?

Bob Smith

unread,
Nov 21, 2009, 7:47:09 PM11/21/09
to

Alas, I missed that one, but NARS2000 now handles it as Dyalog does.

I agree with Morten's description as how it should work (and especially
with the part about it being hard work).

To my mind, slash and slope are (unfortunately) ambiguous symbols with
dual meanings (sometimes a wave, sometimes a particle). I would rather
go the extra mile to make them work as ambiguous symbols (and, if we've
done it well, the average user never notices the ambiguity) than force
them to be operators and then try to explain the cases when they are
applied via other operators. Theoretically, the APL2 definition of
always an operator is logical, but I don't see it as practical.

AAsk

unread,
Nov 22, 2009, 2:32:32 AM11/22/09
to
If I came up with that expression, the Dyalog result is what I'd
expect to see as well - it is consistent with comparable expressions
where the initial / is replaced by say +.

I just wondered what 3//2 4 1 3 7 will return: must try it out.

Ibeam2000

unread,
Nov 22, 2009, 2:49:28 AM11/22/09
to
Dyalog APL has this Thing called []VFI, which is the tried and true (I
would not say "legacy") []FI and []VI rolled up into one. The
rationale was perhaps that []FI and []VI are often used together, and
thus made sense being implemented as one function. (I think this
would have been better off left as []VI and []FI, but that is another
story for another time)

To review,

Suppose X := '1 2 3 junk 5 0'

[]FI does a permissive numeric conversion of a character string, where
items are separated by spaces. []FI returns the corresponding number,
or a zero where the substring failed to convert.

[]FI X would return 1 2 3 0 5 0

[]VI returns a boolean indicating whether or not the corresponding
substring would convert to numeric at all.

[]VI X would return 1 1 1 0 1 1

These were often used together

([]VI X) / []FI X would return 1 2 3 5 0.

Some of the STSC / Manugistics PC interpreters had nice, non-intrusive
features to []VI and []FI (using []POKE etc.) which would allow a low
minus to pass as a high minus in evaluating negative numbers. Perhaps
also a feature to allow commas to separate numbers. Don't remember
offhand.

Dyalog's []VFI combined both functions together.

[]VFI X would return (1 1 1 0 1 1) (1 2 3 0 5 0)

So, if I wanted to do the []VI / []FI thing, I could write

A := // []VFI X

Cool.

The coolness, however, abruptly ends here.

1+//[]VFI X - this returns (1 1 1 0 1 1) (1 2 3 0 5 0)

Why? (1+/) / []VFI X - this does an n-wise reduction reduction

first // []VFI X - length error

first (//) []VFI X - returns the first element

I am not saying that this is wrong, but it may not necessarily be
intuitive.

The original designers of the APL keyboard and symbols evidently had a
problem with symbol pressure, i.e. finding glyphs to fit all of the
functions and operators. The / and \ and first dimension counterparts
are the only examples of such symbol overloading and represent one of
the few syntactic anomalies originally designed into the language.
(Others being the old ; list notation for output and arguably the A
[B;C;D] indexing) 15 or so years later, extensions made to the
language to accommodate for nested arrays and extended operators cause
this one decision to break. One solution would be to find new glyphs
for either the compression (a function) or reduction (an operator).

Stan Clitherdawes

unread,
Nov 22, 2009, 3:12:00 AM11/22/09
to
On Sat, 21 Nov 2009 01:42:08 -0800 (PST), Morten Kromberg wrote:

>[... deleted ...] But if it really is true that most quote ordinary
> users unquote feel comfortable with the ambivalent definition,[... deleted ...]

Just so's we know that "most" isn't synonymous with "all" - I personally
prefer simplicity and consistency when there's a conflict with convenience.
And would prefer an unambivalent definition.

I think the original language designers put a lot of thought into APL -
it's a pity when elegance starts to ebb away.

But I'm just argumentative.

Phil Last

unread,
Nov 22, 2009, 4:19:39 AM11/22/09
to

There are a number of code snippets I use in the first draft of a
function that I almost always end up removing when I have more time
because they are slower or are likely to be mis-understood at a later
stage. "//" appears to be one of them as I've just searched the entire
ws I'm working on and every single example is a quoted string in some
other language (TCP, FlipDB-script ...) that happens to be embedded in
an APL function.

My reasons for removing them are close to Ibeam2000's comments above.
Even the r←//⎕VFI at one stage was impossible without the parenthesis
because the left arrow would get sucked in as left operand to the left
slash and pre-existing r would be taken as the derived function's left
argument or cause a VALUE error if it didn't exist. As Morten pointed
out either using the dfn {⍺/⍵} or keeping a predefined named version
of it clarifies the intent both to the human reader and the
interpreter.

And of course, if any APL2 users are unfathomably jealous of Dyalog's
behaviour they can do exactly the same thing with a defined function:
'r←a Rep w' 'r←a/w'.

A Dyalog defined operator to emulate the APL2 behaviour is slightly
more complicated. But only slightly.

Morten Kromberg

unread,
Nov 22, 2009, 4:55:53 AM11/22/09
to
On Nov 22, 9:12 am, Stan Clitherdawes <d...@dickbowman.org.uk> wrote:
>
> Just so's we know that "most" isn't synonymous with "all" - I personally
> prefer simplicity and consistency when there's a conflict with convenience.
> And would prefer an unambivalent definition.
>
> I think the original language designers put a lot of thought into APL -
> it's a pity when elegance starts to ebb away.

I actually agree with most of this sentiment. But to claim that the
original implementors designed this carefully is a bit of a stretch.
As I understand it, the fact that the / in (1 0 1 / 'ABC') was an
"operator" was a rationalization at the time when APL2/NARS/SHARP APL
were implemented and it suddenly mattered - until that time it didn't
make any real difference how you classified it, and I don't recall
anyone describing "compress" as an operator before that time (it is a
looong time ago, though, and I was a "newbie", so I might well have
missed it).

So... I think your choice here is between simple OR consistent. Simple
AND consistent isn't an option. ... Which is what allows "convenience"
becomes a strong(er) argument that it would otherwise be.

Two separate symbols would be a good idea, if we could find them.
We're certainly considering separating other symbols which have
multiple meanings, the dot being the prime candidate (decimal
separator, name segment separator, inner product ...). Using a
centered dot for inner product would make a lot of sense now that we
have Unicode (obviously, we'd accept both symbols for a while - but
not in a new APL interpreter, for example).

Phil Last

unread,
Nov 22, 2009, 5:15:32 AM11/22/09
to

Exactly so and the irony is that it was replicate and expand that
became the models for what an earlier correspondent pointed out is
still largly misunderstood that an operator can take either a function
or an array for an operand.

As I recall rank (in SAPL) was the only addition to the list of
primitives with this capability until Dyalog introduced power.

Stan Clitherdawes

unread,
Nov 22, 2009, 6:23:11 AM11/22/09
to
On Sun, 22 Nov 2009 01:55:53 -0800 (PST), Morten Kromberg wrote:

> On Nov 22, 9:12�am, Stan Clitherdawes <d...@dickbowman.org.uk> wrote:
>>
>> Just so's we know that "most" isn't synonymous with "all" - I personally
>> prefer simplicity and consistency when there's a conflict with convenience.
>> And would prefer an unambivalent definition.
>>
>> I think the original language designers put a lot of thought into APL -
>> it's a pity when elegance starts to ebb away.
>
> I actually agree with most of this sentiment. But to claim that the
> original implementors designed this carefully is a bit of a stretch.
> As I understand it, the fact that the / in (1 0 1 / 'ABC') was an
> "operator" was a rationalization at the time when APL2/NARS/SHARP APL
> were implemented and it suddenly mattered - until that time it didn't
> make any real difference how you classified it, and I don't recall
> anyone describing "compress" as an operator before that time (it is a
> looong time ago, though, and I was a "newbie", so I might well have

> missed it).[... deleted ...]

Well, they weren't omniscient. Or maybe there were some areas where they
couldn't decide and left gaps for people to clean up in the light of
experience?

Let's talk about bracket-indexing, perhaps?

Maybe I feel an APL2010 punchup topic is coming into view - "Rational APL
for the 21st Century" - (TM), (C), etc.

Ibeam2000

unread,
Nov 22, 2009, 9:52:36 AM11/22/09
to
PS:

One glaring omission:

> Suppose X := '1 2 3 junk 5 0'
>

> A := // []VFI X
>
> Cool.

In the above example, A is nested scalar.

A := disclose (//) []VFI X

Somewhat less cool.

Morten Kromberg

unread,
Nov 22, 2009, 11:41:26 AM11/22/09
to
On Nov 22, 11:15 am, Phil Last <phil.l...@ntlworld.com> wrote:

> As I recall rank (in SAPL) was the only addition to the list of
> primitives with this capability until Dyalog introduced power.

And "Cut", I believe (also SAPL)

Phil Last

unread,
Nov 22, 2009, 12:35:27 PM11/22/09
to

Now you mention it there's also compose (∘) in Dyalog. Not so rare
then! Nevertheless replicate WAS the justification for the rest.

Phil Last

unread,
Nov 22, 2009, 12:55:25 PM11/22/09
to

In case anyone had noted APLX's conspicuousness by its absence I just
installed APLX for another 30 days and it turns out that / IS an
operator:

1 2/¨3 4
3 3 3 4 4 4
//1 2 3 4
SYNTAX ERROR
//1 2 3 4
^
They have implemented n-wise reduction so the derived function is
ambivalent. It just happend that if its left operand is an array it
ignores any left argument it might happen to have. Hence

2 // 2 4 1 3 7

is equivalent to:
(2/)/ 2 4 1 3 7
is equivalent to:
⊂2(2/)4(2/)1(2/)3(2/)7
⊂2/2/2/2/7
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
which can be replicated (npi) in Dyalog with:
{⍵}∘(2∘/)/2 4 1 3 7
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7

Just in case.

Morten Kromberg

unread,
Nov 22, 2009, 5:30:35 PM11/22/09
to
On Nov 22, 12:23 pm, Stan Clitherdawes <d...@dickbowman.org.uk> wrote:

> Let's talk about bracket-indexing, perhaps?

I think Adin Falkoff got this exactly right when he said (something
along the lines of): Square brackets are the cockroaches of APL: They
will still be here when we are all gone...

That isn' to say that functional forms of selection are not good
supplements, of course.

Catherine Lathwell

unread,
Nov 23, 2009, 2:18:57 PM11/23/09
to
Well said, Morton!

Incidentally - I will be doing a full interview of Adin with Alex
Morrow's help hopefully before March 2010. If anyone has any
questions they'd like to throw into the pot, please feel free to speak
up and let me know (via email or the blog).

Catherine

Björn Helgason, j-programming

unread,
Nov 24, 2009, 6:26:56 AM11/24/09
to

Square brackets as they are used in APL are not used in J

Richard Nabavi

unread,
Nov 25, 2009, 4:31:38 AM11/25/09
to
On 22 Nov, 17:55, Phil Last <phil.l...@ntlworld.com> wrote:

>
> In case anyone had noted APLX's conspicuousness by its absence I just
> installed APLX for another 30 days and it turns out that / IS an
> operator:
>

Yes, that is quite right. Our view on this is that the APL2 designers
got this wrong, and that it is absurd that Compress (which, based on
what it does, is obviously a function) is regarded as an operator
simply because it happens to share a symbol with Reduce. It causes
immense confusion because users cannot understand why Compress doesn't
work with Each in the way you'd expect. To make it even more
confusing, if you write a one-line function with simply returns A/B,
it does behave as you would expect when combined with Each. However,
we took a design decision that we would be APL2-compatible as far as
possible, so we deliberately followed what we believe to be IBM's
design mistake.

For efficiency, though, we try to short-circuit the process since (as
others have pointed out above) it is a pain to implement Compress as
an operator, and we had to put in extra code to implement this
'feature'. The APLX source code includes the following comment at the
point where it is parsing the Slash:

// Reduce left operand & slash to a single derived fn.
//
// To comply with dogma, left operand can be an array.
// However, for efficiency we detect the normal compress/expand cases
and
// go straight to them.

In the particular example given at the start of the thread, we should
strictly speaking signal a Valence Error to be compatible with APL2,
but our primary goal is to be compatible with valid APL2 expressions,
not invalid ones.

Richard Nabavi
MicroAPL Ltd


Phil Last

unread,
Nov 25, 2009, 11:25:35 AM11/25/09
to
On Nov 25, 9:31 am, Richard Nabavi <micro...@microapl.demon.co.uk>
wrote:

An attitude worthy of emulation in many other realms!

David Liebtag

unread,
Nov 25, 2009, 12:40:20 PM11/25/09
to
Folks,

I am sure that Jim Brown and the other original APL2 implementors would
agree that it was an unfortunate choice to use slash for both compress and
reduce. But, it was not their choice. The original APL-360 used slash for
both compress and reduce. The APL2 implementors simply produced an upwardly
compatible enhancement when they added replicate and n-wise reduce.

And, I believe the APL2 designers would say that APL2's increased
flexibility required that APL's rules of evaluation also be enhanced. This
lead Jim to write APL2's binding rules.

For me, APL2's binding rules provide a consistent way to determine how
symbols are combined in preparation for evaluation.

Nevertheless, as I said before, the choice to use slash for both compress
and reduce was unfortunate, but it wasn't the APL2 folks who did that. It
was the generation before. And, I think the APL2 folks did the correct
thing; they maintained compatibility. Changing either compress or reduce to
use a different symbol would have broken almost all VS/APL and APL SV
applications and made migration to APL2 prohibitively expensive.

James J. Weinkam

unread,
Nov 27, 2009, 2:57:18 AM11/27/09
to
David Liebtag wrote:
> ... Changing either compress or reduce to
> use a different symbol would have broken almost all VS/APL and APL SV
> applications and made migration to APL2 prohibitively expensive.
>
Why would it be so expensive? It seems to me that it would be trivial to write
a tool that would find all slashes outside of strings or comments and either
change them to the correct symbol if the left operand was obviously either a
function or an array or replace them with, say,
{deltaunderscore}sl{deltaunderscore}. {deltaunderscore}sl{deltaunderscore}
would then be defined as a user defined operator that would examine its left
operand and do the needful.

WildHeart

unread,
Nov 27, 2009, 3:23:37 AM11/27/09
to

Given that APL posses an "execute" primitive, why limit the
substitution only to slashes outside strings? Comments can hide
runnable code as well... One of the error handlers in APL*PLUS is
based on meaningful comments...

Then you have people like us who store executable code in packages à-
la Sharp-APL into component files...
Doable, but not trivial, no...
--
Stefano

James J. Weinkam

unread,
Nov 27, 2009, 3:52:09 AM11/27/09
to
WildHeart wrote:
> On Nov 27, 8:57 am, "James J. Weinkam" <j...@cs.sfu.ca> wrote:
>> David Liebtag wrote:
>>> ... Changing either compress or reduce to
>>> use a different symbol would have broken almost all VS/APL and APL SV
>>> applications and made migration to APL2 prohibitively expensive.
>> Why would it be so expensive? It seems to me that it would be trivial to write
>> a tool that would find all slashes outside of strings or comments and either
>> change them to the correct symbol if the left operand was obviously either a
>> function or an array or replace them with, say,
>> {deltaunderscore}sl{deltaunderscore}. {deltaunderscore}sl{deltaunderscore}
>> would then be defined as a user defined operator that would examine its left
>> operand and do the needful.
>
> Given that APL posses an "execute" primitive, why limit the
> substitution only to slashes outside strings? Comments can hide
> runnable code as well... One of the error handlers in APL*PLUS is
> based on meaningful comments...

Good point.I overlooked that. That does raise the difficulty of identifying
which strings get executed. I am unfamiliar with how comments hide executable
code. Is there a good reason for such a thing? It sounds to me like a recipe
for unmaintainable software.

David Liebtag

unread,
Nov 27, 2009, 9:04:16 AM11/27/09
to
James,

You thinking rationally; that's not how it works. :-)

Remember, this change was made in 80's and would have effected many many
multinational corporations who are very, very slow to embrace change. Even
though the migration of most applications from VS/APL to APL2 required only
an )MCopy, many customers took years years and years to make the change. If
we had told them there was an actual incompability in a major language
element, they would have been even more resistant.

Think about it, if you had applications which were critical to the operation
of your multibillion dollar business and someone suggested you change
significant numbers of lines of your source code just so the language was a
little more elegant, would you be quick to do it?

David Liebtag


phil chastney

unread,
Nov 27, 2009, 3:28:19 PM11/27/09
to

I used to use comments to embed SQL code in APL functions

the line before the comments would invoke a routine which used ⎕LX and
⎕CR to locate the following comments, extract the SQL statement and
throw it at the Oracle interpreter

and I should think most people have assembled operating system commands
from short pieces of string, so it's not just a question of which
strings get executed, but which strings get executed by which interpreter

it's not unmaintainable -- having the foreign code visible at the
point at which it gets executed makes a lot of sense

SQL code which writes SQL, though -- now that is difficult to read

all the best . . . /phil

P.S: the APL "execute" primitive is horrible, and should be excised


phil chastney

unread,
Nov 27, 2009, 8:23:26 PM11/27/09
to
Stan Clitherdawes wrote:
>
> Let's talk about bracket-indexing, perhaps?
>
> Maybe I feel an APL2010 punchup topic is coming into view - "Rational APL
> for the 21st Century" - (TM), (C), etc.

OK, let's talk about bracket-indexing...

could someone please explain to me, in words of one syllable or less,
why brackets and parentheses produce such feelings of antipathy within
the APL community?

other languages seem to take brackets/braces/parentheses in their
stride, along with similar constructs such as "begin ... end"

in logic, parentheses are recognised as a topic in need of special
treatment, but without any obvious need for garlic and crosses

in computer science, the use of parentheses marks the transition from
regular languages to stack-based languages, but I've never known anybody
object to the necessity of making that step

in APL, Iverson attempted at one point to make the syntax
parenthesis-free, but the proposal was not a popular success

so, is it the brackets themselves that trigger such ire, or the list
structure between the brackets, or what?

it's a shame the list structure wasn't made more general ... /phil

Stan Clitherdawes

unread,
Nov 28, 2009, 3:11:47 AM11/28/09
to
On Sat, 28 Nov 2009 01:23:26 +0000, phil chastney wrote:

> [... deleted ...]


> could someone please explain to me, in words of one syllable or less,
> why brackets and parentheses produce such feelings of antipathy within

> the APL community?[... deleted ...]

I don't think it's general antipathy so much as as a tendency to stir up
disagreement.

For me, what I dislike about bracket-indexing is two fold (and I guess the
two are somewhat linked).

Firstly that it introduces something to the language that isn't a function
or operator.

Secondly, that when working with data that may have different ranks,
bracket-indexing pushes the programmer toward constructing executable
character strings to get the stuff that sits inside the brackets right.

Just this week I finally decided that the index operator was also
distressing me - and I'm experimenting with ridding my code of that as
well.

As for parentheses - my take is that they're clutter - the more of them
there are, the more muddled the thinking of the programmer is likely to
have been.

Not sure how many syllables that was - but that's my perspective.

Jane Sullivan

unread,
Nov 28, 2009, 7:41:36 AM11/28/09
to

"Stan Clitherdawes" <di...@dickbowman.org.uk> wrote in message
news:1nk1cqiasgepn.b4fv9ua1fnd1$.dlg@40tude.net...

> On Sat, 28 Nov 2009 01:23:26 +0000, phil chastney wrote:
>
>> [... deleted ...]
>> could someone please explain to me, in words of one syllable or less,
>> why brackets and parentheses produce such feelings of antipathy
>> within
>> the APL community?[... deleted ...]
>
> I don't think it's general antipathy so much as as a tendency to stir
> up
> disagreement.
>
> For me, what I dislike about bracket-indexing is two fold (and I guess
> the
> two are somewhat linked).
>
> Firstly that it introduces something to the language that isn't a
> function
> or operator.
>
> Secondly, that when working with data that may have different ranks,
> bracket-indexing pushes the programmer toward constructing executable
> character strings to get the stuff that sits inside the brackets
> right.

You can get around that (well A+ has done so) by assuming any trailing
semicolons which may be missing, thus for a 5-dimensioned array A
A[2;3] is the same as A[2;3;;;]

>
> Just this week I finally decided that the index operator was also
> distressing me - and I'm experimenting with ridding my code of that as
> well.
>
> As for parentheses - my take is that they're clutter - the more of
> them
> there are, the more muddled the thinking of the programmer is likely
> to
> have been.

I have come across many muddled-thinking programmers in my time. They
generally have degrees in computer science. Are you really trying to
reduct the population of people who are capable of programming in APL?

Morten Kromberg

unread,
Nov 28, 2009, 11:53:53 AM11/28/09
to
On Nov 28, 2:23 am, phil chastney
<phil.hates.s...@amadeus.munged.eclipse.co.uk> wrote:

> could someone please explain to me, in words of one syllable or less,
> why brackets and parentheses produce such feelings of antipathy within
> the APL community?

Not I. But here are some thoughts...

I think we need to separate the discussions regarding parentheses from
brackets. I'm not really aware of MUCH antipathy against
parentheses... I know some people are very keen on using the "commute"
operator in order to keep the number of parentheses down - usually (in
my opinion) without making the code more readable.

Regarding brackets: The Rank Operator is "clearly" :-) a more elegant
solution than the so-called "Axis Operator" that modifies functions in
APL2 dialects. It is only a question of time before we implement Rank
in Dyalog APL. OK, axis gives shorter expressions for a couple of
cases but the irregularity makes rank more attractive to me.

Re. Indexing: In my mind, there are somehow two different forms.

1) "Array Oriented" Indexing of rectangular arrays using an integer
array for each dimension, with []IO identifying the "first" item on
each dimension. The shape of the result is the concatenation of the
shapes of the indices.

2) "Object Oriented" Indexing, which is actually a method invocation
on the "Getter" method of the object (or property) being indexed: This
function is free to interpret the argument in any way that it likes.
This allows the use of strings as indices, or indeed any form of array
or object.

I think my personal preference is to use functional forms (squad,
from, merge) for the first kind of indexing (it feels essentially like
another structural "function"), but I feel very comfortable with
square brackets as a notation for the latter. The functional/
structural forms don't seem to make these statements easier to read -
for me.

In practice the distinction between the two forms can be a little
fuzzy. A few years ago, we designed indexing on "objects" for version
11 of Dyalog APL, and provide slightly different support for these two
types of indexing. Properties can be either NUMBERED or KEYED:

A NUMBERED property must provides a "Shaper" method (which returns the
shape of the property being indexed) in addition to the Getter (and
Setter). In this case, APL provides services like adjusting indices
for differences between the index origin of the consumer and the
provider - and "lazy evaluation" of the application of structural
functions to an object (negative one take on an object which
represents a component file only causes a singe file read).

For a KEYED property, the indexing argument is passed unmodified to
the getter function. We DID decide that APL would validate that the
shape of the result still has to have the same shape as the catenation
of the indices (or signal a LENGTH ERROR), which means that you really
need to index using scalars (so a character vector would generally be
enclosed before being used as an index). We can relax this in the
future but it still "feels right".

For more on that, see http://www.dyalog.com/help/12.1/html/properties.htm

We certainly have no plans to abandon square bracket indexing, and I
think we would probablly re-implement them if we were to start again.
Whether we'd implement []IO is, of course, the big question! Time to
run and hide :-).

Morten

Phil Last

unread,
Nov 28, 2009, 2:36:07 PM11/28/09
to
> For more on that, seehttp://www.dyalog.com/help/12.1/html/properties.htm

>
> We certainly have no plans to abandon square bracket indexing, and I
> think we would probablly re-implement them if we were to start again.
> Whether we'd implement []IO is, of course, the big question! Time to
> run and hide :-).
>
> Morten

I've barely used squad since it was introduced in Dyalog and don't
actually remember using it back in my APL2 days in the eighties. What
amazed me with the Dyalog implementation was that removing the index
brackets and semicolons by using squad actually requires the addition
of axis brackets if you don't specify indices for all axes. Is this
the same in APL2? I've not used A+, or J for that matter. Do they
overcome the problem in similar ways?

Morten Kromberg

unread,
Nov 28, 2009, 4:28:48 PM11/28/09
to
On Nov 28, 8:36 pm, Phil Last <phil.l...@ntlworld.com> wrote:

> I've barely used squad since it was introduced in Dyalog and don't
> actually remember using it back in my APL2 days in the eighties. What
> amazed me with the Dyalog implementation was that removing the index
> brackets and semicolons by using squad actually requires the addition
> of axis brackets if you don't specify indices for all axes. Is this
> the same in APL2? I've not used A+, or J for that matter. Do they
> overcome the problem in similar ways?

I believe our implementation is identical to the APL2 "original" (it
was certainly intended to be, I think we would consider any difference
to be a bug). We added a monadic definition, which select all
elements: It is a "no-op" on arrays, but converts an object which is a
collection into an array containing all of its elements.

Our on-line help: http://www.dyalog.com/help/12.1/index.html?page=html%2Fproperties.htm

We have thought about allowing "short" left arguments for functions
like take and drop (work on as many leading axes as are provided). It
would possibly make make sense to do that for squad; I think this is
what J "from" does. Working on leading axes combines very nicely with
the rank operator, which essentially specifies a set of trailing axes
on which to work...

DaveW

unread,
Nov 28, 2009, 6:43:02 PM11/28/09
to
On Nov 27, 8:23 pm, phil chastney
<phil.hates.s...@amadeus.munged.eclipse.co.uk> wrote:

> Stan Clitherdawes wrote:
>
...
> could someone please explain to me, in words of one syllable or less,
> why brackets and parentheses produce such feelings of antipathy within
> the APL community?
...
(At the risk of walking in where angels fear to tread...)

I think the major objection to bracket indexing is that is the only
APL function construct where the syntax puts it to the RIGHT of the
object on which it (selection) is being performed (hence squad
indexing is seen as more APL-like). I don't remember whether Dyalog
allows commute to be used to switch the syntax (that's a subtle call
to Morten for assistance).

The second objection is the rank question (need for ";", completely
different axis specification syntax than that use by any other axis
selection, etc.)

Third is that the same symbol combination ([]) is used to denote the
axis argument for appropriate operators and functions.

All of these are, of course IMHO.

Stan Clitherdawes

unread,
Nov 29, 2009, 3:48:47 AM11/29/09
to
On Sat, 28 Nov 2009 11:36:07 -0800 (PST), Phil Last wrote:

> [... deleted ...] What


> amazed me with the Dyalog implementation was that removing the index
> brackets and semicolons by using squad actually requires the addition
> of axis brackets if you don't specify indices for all axes. Is this
> the same in APL2? I've not used A+, or J for that matter. Do they
> overcome the problem in similar ways?

That is common to both APL2 and Dyalog (APLX also - I think, as it follows
APL2 conventions quite closely). It's surprising that, so far as I know,
none of the implementors have followed up with either axis or rank (or
both) as primitive operators. Aside from J, where so much was rethought.

Morten Kromberg

unread,
Nov 29, 2009, 4:20:16 AM11/29/09
to
On Nov 29, 12:43 am, DaveW <d...@dmarcus.org> wrote:

> I don't remember whether Dyalog allows commute to be used to switch

> the syntax?

Commute cannot be used with bracket indexing - which is not "a
function". As an operator, commute (⍨) can (of course) only be used
with functions:

x←⍳10
(x>5)/x
6 7 8 9 10
x/⍨x>5
6 7 8 9 10

(Dyalog APL being able to recognise / as a function in this case :-)

I personally DO NOT feel that expressions using commute are generally
easier to read than expressions using parentheses. Swapping the
arguments around in my head seems to requires at least the same amount
of mental effort for me as processing the parens. Part of that may
have something to do with the hideous symbol used for commute, of
course.

Solution: Write shorter expressions :-)

Which of the following is easiest to read?

x[⍋x]
(⊂⍋x)⌷x
x⌷⍨⊂⍋x

Björn Helgason, j-programming

unread,
Nov 29, 2009, 4:55:25 AM11/29/09
to

from, rank and amend in J are what many former APL:ers have some
initial struggle with.
Once learned they are easy.

Roger Hui

unread,
Nov 29, 2009, 7:04:13 AM11/29/09
to
One of Ken's master strokes in J was to redefine the dyad grade
(spelled /: in J instead of ⍋) so that x/:y is x indexed by
the grade of y , which means to sort y you say y/:y .
Sometime later in a presentation Chris Burke showed a list
of uses of ~ (commute). Now in J, as in Dyalog, f commute y is
y f y , and in Chris' list he had /:~y to sort y . Ken was
startled when he saw this. (He didn't know?! Which makes
the design of x/:y even more incredible.)

So the answer to your question

> Solution: Write shorter expressions :-)
>
> Which of the following is easiest to read?
>
> x[⍋x]
> (⊂⍋x)⌷x
> x⌷⍨⊂⍋x

is /:~ in J. In addition to being shorter,
/:~ sorts any array -- any rank, any type.

A few relevant essays:
http://www.jsoftware.com/jwiki/Essays/Reflexive
http://www.jsoftware.com/jwiki/Essays/Sorting_versus_Grading
http://www.jsoftware.com/jwiki/Essays/The_TAO_of_J

Roger Hui

unread,
Nov 29, 2009, 7:16:59 AM11/29/09
to
What the designers of later dialects could have done,
and still can do, to make "the language a little more
elegant" without losing compatibility and without requiring
the change of a single line of code, is to introduce
a new function, denoted by # (say), for doing compress/replicate.
Document the case array/ as being deprecated.

Then you don't have to make / an "ambiguous symbol".
You don't have to apologize for not being able to do b/¨y
(actually you can do b/¨y, but it's (b/)¨y). Instead,
fancy new operations are done using #, a proper and
perfectly respectable function. In particular,
replicate each is x#¨y.

p.s. And what is the monad #y? I am glad you asked. See:
http://www.vector.org.uk/?vol=24&no=2&art=insession

Stan Clitherdawes

unread,
Nov 29, 2009, 11:43:29 AM11/29/09
to
On Sun, 29 Nov 2009 01:20:16 -0800 (PST), Morten Kromberg wrote:

>[... deleted ...]


>
> Which of the following is easiest to read?
>
> x[⍋x]
> (⊂⍋x)⌷x
> x⌷⍨⊂⍋x

Something which I find helpful is associating meaningful names with
primitives - for example, "shape" and "reshape" are more communicative
verbalisations than "rho".

I've often found that "by" is a good alternative to "commute" - hence
reading your last example as "x indexed by upgrade x" (the enclose is of
course silent).

Which, to me, makes the last the easiest to read.

This approach may not be universally applicable, or liked.

Martin Neitzel

unread,
Nov 27, 2009, 10:53:12 AM11/27/09
to
>Good point.I overlooked that. That does raise the difficulty of identifying
>which strings get executed. I am unfamiliar with how comments hide executable
>code. Is there a good reason for such a thing?

In our APL group (back in the 80ies), we used to have two idioms for
conditional execution:

EXECUTE (boolean-expr) \ 'statement'
EXECUTE (boolean-expr) DROP 'LAMP statement'

In the latter case, you can have both together: an "\" hiding
in a "comment" hiding in a string.

I think both idioms not just our own device but were fairly common.

Martin Neitzel

0 new messages