Home > Archive > APL > June 2006 > Axis specification in APL2
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Axis specification in APL2
|
|
| brian.b.mcguinness@lmco.com 2006-05-19, 6:56 pm |
| I was looking at axis specification for ravel, take, and so on in APL2
and wondering if this could be made more consistent and general. For
example, you can ravel or take over multiple dimensions; why not also
reduce over multiple dimensions, e.g. +/[1 4 5] A. For example, +/[1
2] M for a matrix M would be equivalent to +/+/M. So if you specified
N axes to reduce over, the result would have N fewer axes than the
argument array.
--- Brian
| |
|
| Look at SHARP APL and J's rank conjunction. It does about 99% of what
the
APL2 bracket axis specification stuff does, BUT:
1. It is simply one more conjunction. It is NOT ad hoc notation, as the
bracket
axis stuff is.
2. It has identical semantics on ALL functions, whether primitive,
derived, or defined.
3. It doesn't have any entangling alliances with quad-io, as the axis
bracket stuff does.
You'd write your +/[1 2]M example in J as:
"sum composedwith ravel rank 2 M"
I think that's written this way:
+/ @ , "2 M
| |
| brian.b.mcguinness@lmco.com 2006-05-22, 7:57 am |
| I have experimented with rank in Sharp APL for Linux but
haven't had a chance to learn J, so I'm not familiar with the
composition operator. Originally, I was wondering what
would happen if Sharp APL rank was added to APL2; how
would rank and axis interact? Since various APLs have
introduced an index function to replace the syntactically
messy bracket indexing, I was also wondering about the
possibility of replacing bracket axis with an axis operator
having a syntax similar to Sharp APL rank. In that sense
I was thinking that axis could be made more regular so
that it would be applied in much the same way as rank.
For example, why can't you ravel over any arbitrary group
of dimensions of an array so long as you define a
convention for where to place the merged axes in the
shape of the result?
But it seems as if you're saying that having both axis and rank
wouldn't be worth the necessary additional complexity of the
interpreter as there is too much duplication of functionality,
especially if composition is available.
--- Brian
| |
|
|
brian.b.mcguinness@lmco.com wrote:
> I have experimented with rank in Sharp APL for Linux but
> haven't had a chance to learn J, so I'm not familiar with the
> composition operator. Originally, I was wondering what
> would happen if Sharp APL rank was added to APL2; how
> would rank and axis interact? Since various APLs have
With rank, there is NO need (or benefit) to have the bracket axis
notation any more. Period. end of story. As I said earlier, the
rank conjunction is both general and consistent, with identical
semantics
on ALL verbs (functions), primitive, derived, or user-defined.
To see why this is A Good Thing, get thee hither and look at the
APL2 definition of RAVEL, the function that takes generates a vector
from any array. The definition is basically one sentence. Now, go and
read the APL definition of RAVEL-WITH-AXIS. This definition takes,
if I recall correctly THREE pages. Furthermore, that definition is
completely unique to RAVEL, and has nothing in common with other
functions. Rank, on the other hand, works identically on everything.
> introduced an index function to replace the syntactically
> messy bracket indexing, I was also wondering about the
> possibility of replacing bracket axis with an axis operator
> having a syntax similar to Sharp APL rank. In that sense
Sure. Go look at my "AN Introduction to Function Rank" (APL88) on the
ACM web site. I'm looking for a copy here on my machine, but
it seems to have take a walk... The first page of this article
gives examples of function rank conjunction vs axis notation.
> I was thinking that axis could be made more regular so
> that it would be applied in much the same way as rank.
> For example, why can't you ravel over any arbitrary group
> of dimensions of an array so long as you define a
> convention for where to place the merged axes in the
> shape of the result?
Ken Iverson and I spent a considerable amount of time trying to design
such a definition, but never came up with anything we liked. Basically,
there were
these issues:
- where do cell axes come from in the arguments?
- where do (f cell) axes go in the result?
A completely general definition led to esthetically unpleasant and
largely unreadable
notations, with little PRACTICAL benefit for all the mechanism it
required.
Similarly, the ability to collect disjoint argument axes into a cell
resulted in
a complicated notation that, again, had little merit for the majority
of cases
we looked at.
Finally, specifying placement of result axes was similarly
over-complicated.
This led to several design decisions:
1. Cell specification was a scalar, specifying the number of right-more
axes in the
argument that would constitute a cell. I.e., if you wrote "F rank k Y",
the cells
which F applied to were rank-k cells of Y. If Y was of shape 2 3 4 5 6,
and k was 2,
the cells would be the subarrays of Y of shape 5 6. The "frame" would
be formed
from the remaining axes of Y, so the result would be of shape:
2 3 4, shape(f cell)
2. As you can see, we discarded the notation of disjoint cells
entirely. This makes
sense in a functional language, where you can achieve the same end via
compositions
with transpose. In fact, J includes a transpose adverb, which I suspect
is of marginal value
given the existence of a transpose primitive, but haven't really
thought this one through.
3. Similarly, we discarded ideas of user-specified result placement.
Rather, we merely
extended the concept, already present in APL, of laminating result
cells along leading
axes, as in the "frame" description, above.
I have my doubts as to the benefits in real applications of the cell
rank and shape
padding provided by the function rank concept in J. I think it may be
overkill, and
may hide application bugs under the covers. I think such padding should
be
provided explicitly, by an appropriate function.
> But it seems as if you're saying that having both axis and rank
> wouldn't be worth the necessary additional complexity of the
> interpreter as there is too much duplication of functionality,
> especially if composition is available.
The axis notation (it's not even a function/verb or
conjunction/adverb/operator - just
somebody's idea of "convenience.") is entirely subsumed by the rank
conjunction,
except for a few oddball cases that are trivially handled by more
conventional
idioms. That's why J doesn't have any axis stuff in it.
Bob
| |
| David Liebtag 2006-05-28, 6:57 pm |
| Boy, this is one area where I agree completely I wish APL2 had the rank
operator. Useful, simple, easy, and elegant. Just plain overall more
APLish than axis specification.
David Liebtag
| |
| me@privacy.net 2006-05-28, 6:57 pm |
| In <1148847154.213721@r2d2.vermontel.net>, on 05/28/2006
at 04:13 PM, "David Liebtag" <liebtag@us.ibm.com> said:
>Boy, this is one area where I agree completely I wish APL2 had the rank
>operator. Useful, simple, easy, and elegant. Just plain overall more
>APLish than axis specification.
Errr.... Aren't you the guy that could add the rank operator to APL2? It
does sound like a useful addition to the language. The axis stuff could
then become deprecated as it is superceded by rank.
-- Dave
-----------------------------------------------------------
dhdurgee<at>verizon<dot>net
-----------------------------------------------------------
| |
| Randy MacDonald 2006-05-29, 7:57 am |
| "rbe" <bernecky@acm.org> wrote in news:1148844185.809977.57690
@i39g2000cwa.googlegroups.com:
> With rank, there is NO need (or benefit) to have the bracket axis
> notation any more. Period. end of story.
Okay, how do you do this with rank:
{rho}{rho}X
2
{rho}{rho}Y
3
X+[1 3]Y
IIRC, this _used_ to be in J, but no more.
--
------------------------------------------------------------------------
|\/| Randy A MacDonald | APL: If you can say it, it's done.. (ram)
|/\| ramacd@nbnet.nb.ca |
|\ | |If you cannot describe what you are doing
BSc(Math) UNBF'83 žas a process, you don't know what you're doing.
Sapere Aude | - W. E. Deming
Natural Born APL'er | Demo website: http://156.34.92.157/
-----------------------------------------------------(INTP)----{ gnat }-
| |
|
|
From: Randy MacDonald - view profile
Date: Mon, May 29 2006 9:55 am
Email: Randy MacDonald <ram...@nbnet.nb.ca>
Groups: comp.lang.apl
Not yet rated
Rating:
show options
Reply | Reply to Author | Forward | Print | Individual Message | Show
original | Report Abuse | Find messages by this author
"rbe" <berne...@acm.org> wrote in news:1148844185.809977.57690
@i39g2000cwa.googlegroups.com:
> With rank, there is NO need (or benefit) to have the bracket axis
> notation any more. Period. end of story.
Okay, how do you do this with rank:
{rho}{rho}X
2
{rho}{rho}Y
3
X+[1 3]Y
A few comments:
1. Randy: I don't have access to an APL2 system at the moment. Please
post simple data and result for same. I think a conjunction of rank
with the
transpose conjunction (whose name I forget) might do the trick for you.
I did say that rank does about 99% of what the APL2 axis brackets do,
not 100%...
2. Brian said: "
But it seems as if you're saying that having both axis and rank
wouldn't be worth the necessary additional complexity of the
interpreter as there is too much duplication of functionality,
especially if composition is available."
I missed Brian's note in my earlier post. It had less to do with
interpreter
complexity than with human issues - the complexity of the user
specification of
the operation. Ken and I felt that a simple, clean specification of the
operation --
effectively specifying the frame/cell split axis - did 99% of the
required work,
and that with function composition available, there was no need to
bring other
facilities (e.g., transpose) into the semantics of that rank
conjunction.
I think this view has vindicated itself in practice, as a look at
production J and SHARP APL applications reveals.
I'll be buried in research in the UK, so likely can't respond
instantly here, but maybe some kindly J/SAPL fan can post a J
expression for Randy's edification of the above.
Bob
| |
| Eric Landau 2006-05-30, 6:57 pm |
| In article <1148844185.809977.57690@i39g2000cwa.googlegroups.com>, "rbe"
<bernecky@acm.org> wrote:
>With rank, there is NO need (or benefit) to have the bracket axis
>notation any more. Period. end of story.
comp.lang.apl readers will understand that there's no *need* for bracket
notation any more, but there is certainly some benefit to it for those
of us who, given the choice, prefer to write code in such a way as to
make it easier for non- or novice APLers to follow. Try walking a
non-programming user through code that uses a rank operator, then try
the same exercise with code that uses bracket notation, and the benefit
will be obvious.
Eric Landau, APL Solutions, Inc.
"Sacred cows make the tastiest hamburger." - Abbie Hoffman
| |
| phil chastney 2006-05-31, 3:57 am |
| Eric Landau wrote:
> In article <1148844185.809977.57690@i39g2000cwa.googlegroups.com>, "rbe"
> <bernecky@acm.org> wrote:
>
>
> comp.lang.apl readers will understand that there's no *need* for bracket
> notation any more, but there is certainly some benefit to it for those
> of us who, given the choice, prefer to write code in such a way as to
> make it easier for non- or novice APLers to follow. Try walking a
> non-programming user through code that uses a rank operator, then try
> the same exercise with code that uses bracket notation, and the benefit
> will be obvious.
I accept that, for convenience, the average kitchen, the average toolbox
and the average programming language come equipped with tools with
overlapping uses -- few artists equip themselves with a minimal set of
tools (quite the reverse, I would have said)
I am less convinced by your second statement: try walking a non-musician
through sheet music, or a non-engineer through a circuit diagram (hell,
they glaze over at the sight of a diagram of a two-way switch, never
mind BC108), or try taking a city kid through navigation with map and
compass -- if they can't understand the concepts, they won't understand
the notation
somebody (David Barron, as it happens) said Cobol was based on the false
assumprion that a manager who could understand "ADD A TO B GIVING C"
would be unable to understand "A <- B + C" -- but isn't that just what
you're proposing here?
regards . . . /phil
| |
| Eric Landau 2006-05-31, 6:57 pm |
| In article <Phdfg.146347$a86.37223@fe01.news.easynews.com>, phil
chastney <phil.hates.spam@amadeus-info.munged.freeserve.co.uk> wrote:
>Eric Landau wrote:
>
>
>I accept that, for convenience, the average kitchen, the average toolbox
>and the average programming language come equipped with tools with
>overlapping uses -- few artists equip themselves with a minimal set of
>tools (quite the reverse, I would have said)
>
>I am less convinced by your second statement: try walking a non-musician
>through sheet music, or a non-engineer through a circuit diagram (hell,
>they glaze over at the sight of a diagram of a two-way switch, never
>mind BC108), or try taking a city kid through navigation with map and
>compass -- if they can't understand the concepts, they won't understand
>the notation
>
>somebody (David Barron, as it happens) said Cobol was based on the false
>assumprion that a manager who could understand "ADD A TO B GIVING C"
>would be unable to understand "A <- B + C" -- but isn't that just what
>you're proposing here?
APL, unlike other computer languages, was designed for real people, not
just programmers, and is much easier for quantitatively oriented users
who don't program to follow than most. It goes out of its way to use
"people-standard" notation where it can rather than
"programming-language standard" notation -- hence our rather "unusual"
glyphs for multiply and divide. Bracket notation is part of this; if a
user can grasp the concept of, say, a two-dimensinal array, he will
recognize "X[i;j]" without having to be taught what it means.
The COBOL user who immediately recognizes "A <- B + C" as equivalent to
"ADD A TO B GIVING C" does so only because he doesn't have to be told
what "+" represents. He will, as well, immediately recognize what "A[I]
<- B[I] + C[I]" means, even if he knows nothing of programming
languages (OK, you may have to explain "<-", but those APL glyphs are
so brilliantly mnemonic!).
One of the reasons I use APL is that I can be confident that a user
who understands enough about the calculations he requires to specify
what my code will do will be able to follow that code without having to
learn enough obscura to write it himself. This, BTW, is the main reason
why I do not care much for J, which confers no such benefit.
Eric Landau, APL Solutions, Inc.
"Sacred cows make the tastiest hamburger." - Abbie Hoffman
| |
| cdburke@gmail.com 2006-06-01, 3:56 am |
| I think Eric's claim that the APL axis operator and its bracket
notation is somehow easier for the newcomer to understand than J's rank
operator, is simply incorrect.
They do different things, so it is no surprise that they look
different. But consider the notation:
A foo[2] B APL
A foo"2 B J
Which really is superior? Are they not equally acceptable? What about :
A foo[1;2] B APL
A foo"1 2 B J
Now try to explain them. In the APL case, ignore the fact that the axis
operator depends on quadIO, that it does not apply to defined
functions, and that you cannot specify left and right axes separately.
What is it supposed to do? Eric claims that this is obvious to a
newcomer, but if so, why is it not fully implemented?
The reality is that what axis is supposed to do is not at all obvious,
hence APL systems only support it partially, and with behaviour
dependant on the function. What is "obvious" to the newcomer is
baffling to the guru.
In the J case, what it does is well defined, is supported by the
implementation, and the same definition applies to all verbs.
Chris
| |
| Morten Kromberg 2006-06-01, 3:56 am |
| For what it's worth... Dyalog is looking closely at Rank. We chickened
out of doing it in version 11.0 because there was more than enough
going into that release already. But we've been using it a little as a
tool of thought in the design of the OO stuff (thinking about the rank
of getter or setter functions for properties and seeing how the
introduction of rank will give us flexibility to simplify and/or
optimise the writing of classes in APL and paint ourselves out of a few
what would otherwise be corners). I can't promise when we'll put it in
but I can say that it is high on the list of potential language
enhancements that we are planning for the next few releases.
Morten Kromberg
Dyalog Ltd.
me@privacy.net wrote:
> In <1148847154.213721@r2d2.vermontel.net>, on 05/28/2006
> at 04:13 PM, "David Liebtag" <liebtag@us.ibm.com> said:
>
>
> Errr.... Aren't you the guy that could add the rank operator to APL2? It
> does sound like a useful addition to the language. The axis stuff could
> then become deprecated as it is superceded by rank.
>
> -- Dave
> -----------------------------------------------------------
> dhdurgee<at>verizon<dot>net
> -----------------------------------------------------------
| |
| Martin Turner 2006-06-01, 3:56 am |
| > "rbe" <berne...@acm.org> wrote in news:1148844185.809977.57690
> @i39g2000cwa.googlegroups.com:
>
>
> Okay, how do you do this with rank:
>
> {rho}{rho}X
> 2
> {rho}{rho}Y
> 3
> X+[1 3]Y
>
>
> A few comments:
> 1. Randy: I don't have access to an APL2 system at the moment. Please
> post simple data and result for same. I think a conjunction of rank
> with the
> transpose conjunction (whose name I forget) might do the trick for you.
> I did say that rank does about 99% of what the APL2 axis brackets do,
> not 100%...
>
> --- Text cut here ---
Randy's point is that the rank operator works on contiguous axes only. To
work on non-contiguous axes (eg 1 and 3) one must re-arrange one or other of
the arguments.
His example was ...
Given:
#io {is} 1
x {is} 2 3 {rho} {iota} 6
y {is} 2 4 3 {rho} {iota} 24
How to obtain:
2 4 6
5 7 9
8 10 12
11 13 15
17 19 21
20 22 24
23 25 27
26 28 30
Brown: x +[1 3] y
Iverson: 2 1 3 {transpose} x (+{paw}2 2) 2 1 3 {transpose}y
Bob's point is different. He argues that knowing axis operation of x +[1 3]
y, can one predict the behaviour of x function[1 3]y (eg x ,[1 3]y)? The
axis operator in APL2 seems to me to be erratic/complex, whereas the rank
operator is simple, powerful and elegant.
There is often a choice to be made between utility and beauty, but in this
case the rank operator seems to win on both counts.
| |
| phil chastney 2006-06-01, 7:56 am |
| cdburke@gmail.com wrote:
> I think Eric's claim that the APL axis operator and its bracket
> notation is somehow easier for the newcomer to understand than J's rank
> operator, is simply incorrect.
>
> They do different things, so it is no surprise that they look
> different. But consider the notation:
>
> A foo[2] B APL
> A foo"2 B J
>
> Which really is superior? Are they not equally acceptable? What about :
>
> A foo[1;2] B APL
> A foo"1 2 B J
>
> Now try to explain them. In the APL case, ignore the fact that the axis
> operator depends on quadIO, that it does not apply to defined
> functions, and that you cannot specify left and right axes separately.
> <snip>
but if the APL implementors and users were prepared to consider
a change, then the axis operator could be extended to all
primitive, derived and user-defined functions
if we amend your APL example to
A foo[1 2] B
then the axes specified are those of the right argument
the notation could be extended to
A foo[3; 1 2] B
and the axis specified before the semicolon is that of the left
argument, thus
A foo[3; ] B
specifies the left axis alone
the axis operator specifies which axes the function is applied over
(in effect, which loops are nested within which, at assembler level,
ignoring parallelism)
"transpose" physically places those elements last, so that the default
ordering of loops can be used
conceptually, the axis operator goes one step further than transpose in
that it first orders the elements for the default definition of "foo",
and then restores the original order after foo has been applied
I wrote a small interpreter which did just that -- each axis
specification was interpreted by a 3-phase process: (i) the "expose"
stage, where the elements were ordered using the transpose primitive,
(ii) the function application, pretty much as usual, and (iii) the
"repose" operation, where another transposition restored the original order
- note that the axes do not have to be contiguous
- in most cases it did everything I expected
- the axis operator could even be applied to the transpose function
in a consistent manner, though it was not something you would
want to have to explain to a third party
- reduction was a bit of a mess, and I gave up on lamination
- it was not clear what should happen with inner and outer products
- I experimented with an axis operator applied to the assignment
function, as a substitute for the transpose primitive, without
reaching any definite conclusions
- for one or two primitives, the results obtained were not the
same as the ad-hoc extensions specified in the standard
all in all, a very interesting exercise, but not really useful
as an extension to APL, if compatibilty with existing code is
to be maintained
we are all prisoners of history . . . /phil
| |
| Dick Bowman 2006-06-02, 3:57 am |
| phil chastney <phil.hates.spam@amadeus-info.munged.freeserve.co.uk>
wrote in news:QXyfg.87307$c92.54644@fe09.news.easynews.com:
> cdburke@gmail.com wrote:
>
> but if the APL implementors and users were prepared to consider
> a change, then the axis operator could be extended to all
> primitive, derived and user-defined functions
>
> [... deleted ...]
>
I think the objection to brackets as operator has been twofold - that it
is valid for only some functions, but also that the rule for each
function where it can be used is different. In other words, it's
neither universal nor consistent. Replacement by a more syntactically-
elegant alternative might need to address the latter (leaving us with
the mess that some old code - possibly quite a lot of old code -
wouldn't transparently cross over).
The other issue of applying rank where the axes are non-contiguous seems
to have significant performance issues if the only answer is to do some
transposition and de-transposition. Unless tranpose got a whole lot
more efficient than it was when Roy Sykes demonstrated it at the APL85
banquet.
But I would like to see brackets sent into the trashcan of history.
| |
| phil chastney 2006-06-02, 3:57 am |
| Dick Bowman wrote:
> phil chastney <phil.hates.spam@amadeus-info.munged.freeserve.co.uk>
> wrote in news:QXyfg.87307$c92.54644@fe09.news.easynews.com:
>
>
>
>
> I think the objection to brackets as operator has been twofold - that it
> is valid for only some functions, but also that the rule for each
> function where it can be used is different. In other words, it's
> neither universal nor consistent. Replacement by a more syntactically-
> elegant alternative might need to address the latter (leaving us with
> the mess that some old code - possibly quite a lot of old code -
> wouldn't transparently cross over).
I would agree -- one result of my experiment was to confirm, to my own
satisfaction, that the present definition of axis is not necessarily
beyond repair, but it does require a radical rethink and certainly does
not warrant extension to other functions in its present form
> The other issue of applying rank where the axes are non-contiguous seems
> to have significant performance issues if the only answer is to do some
> transposition and de-transposition. Unless tranpose got a whole lot
> more efficient than it was when Roy Sykes demonstrated it at the APL85
> banquet.
>
> But I would like to see brackets sent into the trashcan of history.
that would have to be done slowly -- Fortran, for instance, survives and
evolves by first deprecating then obsoleting unwanted features, whilst
introducing the replacement features alongside
I only used transposition as a means of formalising the definition of
axis, so machine efficiency wasn't really the issue, but I would observe
that, with a modest addition to the dope vector, transposition could be
achieved without physically re-arranging the elements
all the best . . . /phil
| |
| olegykj@yahoo.com 2006-06-17, 6:56 pm |
| One need not rearrange the arguments with J ranks
(Sharp APL too, I suppose).
X1 +"1"1 2 Y1
2 4 6
5 7 9
8 10 12
11 13 15
17 19 21
20 22 24
23 25 27
26 28 30
Where
X1=. 1+i.2 3
Y1=. 1+i.2 4 3
X1;Y1
+-----+--------+
|1 2 3| 1 2 3|
|4 5 6| 4 5 6|
| | 7 8 9|
| |10 11 12|
| | |
| |13 14 15|
| |16 17 18|
| |19 20 21|
| |22 23 24|
+-----+--------+
Martin Turner wrote:
>
> Randy's point is that the rank operator works on contiguous axes only. To
> work on non-contiguous axes (eg 1 and 3) one must re-arrange one or other of
> the arguments.
>
> His example was ...
>
> Given:
> #io {is} 1
> x {is} 2 3 {rho} {iota} 6
> y {is} 2 4 3 {rho} {iota} 24
>
> How to obtain:
> 2 4 6
> 5 7 9
> 8 10 12
> 11 13 15
>
> 17 19 21
> 20 22 24
> 23 25 27
> 26 28 30
>
>
> Brown: x +[1 3] y
>
> Iverson: 2 1 3 {transpose} x (+{paw}2 2) 2 1 3 {transpose}y
>
>
> Bob's point is different. He argues that knowing axis operation of x +[1 3]
> y, can one predict the behaviour of x function[1 3]y (eg x ,[1 3]y)? The
> axis operator in APL2 seems to me to be erratic/complex, whereas the rank
> operator is simple, powerful and elegant.
>
> There is often a choice to be made between utility and beauty, but in this
> case the rank operator seems to win on both counts.
|
|
|
|
|