Chris Burke [mailto:[EMAIL PROTECTED] wrote:
> Nevertheless, APL operators are special-cased. For example:
>
> A {gets} 2 3 {rho} {iota} 6
> {transpose}[1] A
>SYNTAX ERROR
First: As Bob pointed out, the bracket notation is not really an operator, it
is "special syntax" which applies in very different ways to different
functions. This is bad in terms of generality, but that doesn't mean it is not
easy to comprehend and use. For example, if you want to reduce the 2nd and 3rd
dimensions of a 4-dimensional array, I don't think that +/[2 3] is less elegant
than doing the same using rank - just less general. The "real" Dyalog operators
all accept user-defined functions in the same way as primitives, although
tacits clearly give J operators "more power" for computing things like function
inverses.
Second: You do not need to convince me of the elegance of rank. It is high up
on our "To Do" list at Dyalog, and I usually find myself arguing from your
position to the dyed-in-the-wool APL2 fans in our community. We would have done
them earlier but we've been very busy adding object oriented features and in
particular seamless integration with COM and Microsoft.Net in order to secure
the acceptance of APL as a tool which can be integrated with mainstream
computing platforms.
Interestingly, these efforts have given rise to powerful new language features
that J does not have, in particular the use of dot notation to work with
(nested) arrays of objects. For example, in Dyalog APL, I can extract the
entire contents of all open workbooks from Excel using the expressions:
'XL' ⎕WC 'OLEClient' 'Excel.Application'
XL.({squad}Workbooks).({squad}Sheets).UsedRange.Value2
The above returns a vector with one element per workbook, each element
containing an element per sheet in the corresponding book, and the leaves are
2-dimensional matrices containing data from the used range of each sheet). In
other words, Dyalog APL supports arrays of objects comfortably. This was hard
work, requiring the solution of the "empty frame" problem in a new guise (see
eg
http://www.dyalog.com/help/index.html?page=html%2Fempty%20arrays%20of%20instances%20why.htm),
and a bunch of interesting compromises between the array and object paradigms
(which I presented a paper on at OOPSLA'07 this year). We can argue about the
left-to-rightedness of it, and many other aspects of the notation - but it is
powerful and reasonably elegant - and actually makes APL appear more readable
to users of other languages without sacrificing ay power, as far as I can tell.
Using Microsoft.Net integration, you can now trivially turn APL functions into
objects that can be used by any other language (simply by using a menu item to
export your classes as .NET assemblies). For example, you can construct
WebServices using .Net mechanisms which are entirely familiar to corporations.
The fact that many of them will quickly abandon the use of .Net in favour of
lightweight APL WebServices implemented by the APL application itself simply
listening on a socket, as you can also do in J, is beside the point in terms of
"acceptance by management". If we want array languages to be more widely used,
we need to chose our battles carefully.
>From a an array language point of view, OO is obviously an idea which needs to
>be used sparingly, otherwise you quickly lose sight of the data for all the
>objects. But as an paradigm for integration, it works extremely well. The idea
>that APL is a tool which is safe for corporations to use is now significantly
>easier to sell; many plans that we know some large corporations had to
>eliminate APL seem to have been shelved. This was a more urgent concern to us
>than adding (even more) power to the language. It appears that we can now
>relax a bit and start looking at this (much more enjoyable) work.
> Rank works well in J because it is complemented with other features that are
> not yet in APL - item functions, prefix agreement, tolerant assembly. Without
> these, rank may not have the utility that it does in J.
This is clearly true, we'll have to see how much of this we can add when we do
rank. Shooting from the hip, prefix agreement and tolerant assembly seem
reasonable. But rank IS going to be worth having under any circumstances (as it
was in SHARP APL).
> Dfns are very useful and a nice step forward, but they correspond to J's
> explicit definition, not tacit definition, i.e. the following are
> essentially the same:
>
> avg=: 3 : '(+/y) % #y'
>
>and
>
> avg {gets} {(+/{omega}) {div} {rho}{omega}}
>
> The only significant difference here is that the J expression is just a
> normal part of the language (i.e. the result of an operator expression),
> whereas the APL is a special syntax that treats the curly braces as a
> function definition.
Yes and No... Technically yes: DFNS are "special syntax" which is roughly
equivalent to J explicit definitions (I'm not sure exactly what it is that
makes syntax "special" - are hooks and forks also "special syntax"?). In
practice, the picture is a little different. The reason why I feel that it is
relevant to compare DFNS to tacit definitions is that you see a lot of
"anonymous DFNS" used in places where you would use tacit functions in J. Using
your avg example, Dyaloggers will often write (using w for omega, % for divide,
# for shape):
{(+/w)%#w} data
Which feels very similar "in spirit" to using a tacit definition like:
(+/ % #) data
The difference being that {omega} is in there to help weak minds like mine
think about how the data is flowing through the expression. I realize that the
power and beauty of tacit definitions is closely linked to the fact that the
data does NOT appear in them, but when it comes to solving many problems, DFNS
give you a lot of bang for the buck, and they seem significantly more elegant
and readable than "3:". Of course, given the existence of tacits in J, it is
hard to argue whether 3: would get used in the same way if they were not there,
but somehow I think not.
Simple notation for error guards in DFNS also increase their utility. For
example, if any of my workbooks contain sheets with absolutely no data in them,
Excel will signal an error when we reference the Value2 property. But I can
write (using § for squad, w for omega, ¤ for diamond and $ for reshape):
XL.(§Workbooks).(§Sheets).UsedRange.{0::w ¤ Value2} 0 0$0
... And get an 0x0 numeric array wherever the reference to Value2 fails.
> J's tacit definitions correspond to APL's operator expressions; there
> are just more of them, and J also includes phrasal forms. Dyalog has
> already done a lot in this area, and presumably could do more.
The composition and commute operators are a step in this direction. We often
think about doing more, but as previously mentioned, we don't currently feel
that OUR user base would get sufficient benefit from this to justify the work
(and putting my devil's advocate hat on, adding significant potential for code
which can only be easily read by the interpreter). I realize that this is
possibly not a good guide for language design, but there are other priorities,
like being a responsive and reliable business partner. Our goal is to increase
the market share of APL, we have finite resources and must service customer
with teams of dozens of APL programmers (the biggest team has more than 100
developers), many of whom are already under strict rules about writing
maintainable code which restrict developers to a subset of what we already have
in the language.
As previously mentioned, lack of algorithmic punch is NOT what the majority of
APL users tend to complain about.
Morten
P.S. In case this is not clear, I feel that J is beautiful (OK, except for the
"spelling" :-), and have huge admiration for the work that Ken, Roger (and
Arthur, and Bob San, and many others) have done before and after 1990. But I
get twitchy when I read messages on J forums which seem to be insinuating that
J left APL in the dust 20 years ago. It has NOT, APL is very competitive, and
(at least some dialects) are moving forward quite fast both in terms of
integration, availability AND language features (in some areas, I would claim
we are moving FASTER than J). And with growing user communities (and revenues)
as the result. It isn't in the interest of the J community to argue this
either: If you belittle APL, you ultimately reduce J as well. I believe that
the continued commercial success of APL is important to the J community, it
should both provide a bit of extra work now and again and (whether or not you
believe J is significantly better ;-) it should increase the long term
catchment area for commercial uses of J. We should try to spend more time
cooperating on educating the world about the benefits of "infix array-oriented
functional languages" than we do arguing about which dialect is best.
Of course, we should never give up having a bit of respectful arguing from time
to time :-)
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm