APL2 In Depth; Norman D Thomson and Raymond P Polivka; Springer-Verlag 1995; ISBN 0-387-94213-0; 264 pages, soft-cover.
[About fonts; this document makes (minor) use of the IBM Courier APL2 font; you may need to install this font to achieve fully effective viewing of the page. Display of the font has been verified with Internet Explorer 4, but not with other browsers.]
There never really has been an accepted successor to Gilman & Rose’s "APL- An Interactive Approach", and one of the consequences of this has been that, even now, the extended capabilities which were introduced by Sharp APL, STSC’s NARS, and APL2 are still regarded in many quarters at best as an optional extra for APL, and at worst as something to be treated with the utmost circumspection.
There are very few deep explorations of the potential offered by modern APL, and this is a gap which the current volume attempts to fill. Nevertheless, from the first sentence of the preface to the back cover propaganda it is still (to this reader) very much marred by an approach which is most easily summarised as "learn flat APL then do a converter course".
This is a practical book rather than a theoretic one; we see this clearly when on page 2 depth is defined in terms of the visual data display offered by the ubiquitous DISPLAY function. The APL Language Reference manual is even less rigorous, and this is something which I’ve only really come to notice as the time since I was regularly using APL2 full time. There’s a great deal which the practitioner ‘just knows’ and which has never been comprehensively gathered into a single place.
For example, it was many years before I saw Phil Benkard’s very succinct explanation of enclose and how it was just a notational convenience:
( â Z ) Ï ( Z ÿ Z ) [ 1 ]
Which is something which I still don’t see in the mainstream APL2 reference material. Of course, IBM is not necessarily the worst offender in neglecting theoretic background on language features.
The chapter covers the essentials of APL2 data structuring and the associated functions. I do tend to get upset when I see an assumption of index origin one used throughout.
One of APL2’s most significant innovations (I think) was the introduction of the indexing function, which is adequately covered from an expository viewpoint, but ought (I think) to have had its liberating effect more thoroughly explained. But I think this is a criticism of the APL world as a whole, too fragmented and not alert enough to unite on clearly advantageous technical innovations.
A characteristic of APL2 which this chapter brings so clearly to mind is the ‘specialness’ of so much of APL2, in the sense of having so many special case rules (an index operator which seems to change its behaviour depending on the function to which it is applied). To be successful with APL2 there’s a lot to learn.
It never fails to astonish me how many people call themselves competent in APL yet cannot distinguish between a function and an operator (often compounding the crime by referring to functions as operators "because it's easier for people to understand". Naturally, authors with the credentials of Thomson and Polivka do not perpetuate this nonsense.
The chapter is a quiet exploration mostly of "each" which lays more emphasis on the pervasive nature of scalar functions than in the APL2 reference material, and on the way that scalar extension allows operators to be applied to a wider variety of primitives.
Again we note the profusion of "APL2 rules" and the confusion which arose when APL2 redefined / to be an operator rather than a function.
By this stage in the book the reader has sufficient knowledge that it becomes possible to begin considering the requirements of an actual application, and this chapter covers two examples of the way that data might most effectively be organised at the workspace level for APL2 applications.
I think that it’s unfortunate that the sample functions are really devoid of commenting and that the text is equally silent on the topic. One of the important practical skills of the APL programmer (developing commercially critical or exploitable applications) is knowing how and when to comment effectively. Most seem to comment too much, especially when driven by uncomprehending ‘management’. I believe that it’s essential that every defined function or operator start with a comment about its purpose, and that one of APL2’s advantages over VSAPL was introducing end-of-line commenting. I think that an important part of an introductory text such as this one is to serve as a role model for acceptable commercial practice; purpose comments are scarcely in evidence and end-of-line comments might have been more amply provided for expository purposes.
This chapter effectively deepens the material covered in the first two chapters, particularly emphasising the role of scalar extension when operators are applied and also taking some time to explore the important question of prototypes and fill functions.
The question of fill functions brings up the important issue of the compatibility of APL2 across the various platforms on which it has been implemented over the years.
Being able to define operators is an important aspect of APL2 which seems to be less used in practice than it might be; it seems right that this chapter should be relatively lengthy.
The purist might have wanted a greater emphasis on the fact that what the programmer really defines are derived functions.
A strength of APL2 has always been that there have been the theorists and, although some of the J camp might protest, these theoretic ideas are implemented in practice a great deal more rigorously than sometimes seems to be the case for some of the "APL2-like" products. Binding rules are a case in point; they are one of the "ten things you need to know to be a good APL2 programmer".
Some of the other good things in this chapter are sections on composition and recursion
An arguably less admirable section covers operators to emulate some of the control structures of scalar programming languages; which seems to be a case of making a virtue out of necessity. I think that my chief regret about APL2 is that it appears to be stuck in a time warp of its own making, while it was revolutionary when first introduced it has failed to evolve in the way of most of the other APL implementations. Control structures (flawed though they unquestionably are) are an example of this, and no amount of toying with user-defined operators is going to remedy this.
And, in this vein, I think it’s unfortunate that APL2 has failed to embrace many of the most common user-defined operators as language primitives. A major advantage of the APL character set is that it makes quite clear what comes with the language and what was written as an add-on; if I see 2-~3 in Dyalog APL (for example) I know precisely what’s intended, but if I see 2 - COMMUTE 3 in APL2 I have to know (or find out) what COMMUTE means and whether the author has done a proper job in writing it.
Chapter 6 provides a similar consolidation and exposition role as Chapter 3; applying the additional material of preceding chapters to real-application situations.
The topics are tree- and network-structured data and code for manipulating this sort of data. Although the material is mostly unexceptionable it does seem unfortunate that the question of scalability is not addressed. Many of the algorithms are fine for exposition on small-scale test cases but are unlikely to be practicable in real situations for those of us who do not have access to infinite workspaces.
A strong point of the book is that it has copious exercises for the reader (120, mostly multi-part) none of which should take so long to perform as to become tedious.
The suggested solutions are reasonable and often supported by further explanation. When dealing with APL2 stalwarts one always has to be on the lookout for unpleasantnesses such as APL2 statement-joinery. Fortunately not a lot of it is on display, but the side-effect data display in Solutions 1a/3 surely should not go without remark.
A useful summary, if not exhaustive (this might have been a good place for Benkard’s Identity).
"APL2 In Depth" might best be considered as a continuation to "APL2 At A Glance" with which it shares one co-author (Polivka); it expands on, and complements, much of the language reference material of the product manuals. Possibly it could have gone rather further than this in terms of commenting on language elements and exploring alternative ways of achieving the same results.
What the book does not explore are two aspects which are vital if APL2 is being applied outside the context of being a souped-up personal calculator, file-based data storage and user interfaces.
While the latter may be contentious and is certainly (in its Windows-ish GUI incarnation) too recent for the book’s authorship date, omitting any consideration of long-term data storage issues does appear to be a serious oversight. Users of other APL products have long gone overboard criticising IBM’s APL products for their omission of an explicit component filing system and it would have been good to see some IBM insiders redressing the balance, particularly in terms of APL2 co-existing and co-operating with mainstream data handling mechanisms. But perhaps that was outside the authors’ remit, and offers scope for some sort of future text.
If you are an APL2 regular this book may not add a lot to what you already know; if you are just starting with APL2 or need a refresher because your APL2 shares time with other programming the book is probably valuable. There are all too few texts about any variety of APL, and if the book gives you an insight which gains more than an hour of consulting time you will be ahead.
Copyright © Dick Bowman 1998-2013; latest update 14 March 2013 (repaired links)
Return to the JAPL Contents page