[comp.lang.apl] what is j?

"greg trice" <greg.trice@canrem.uucp> (05/13/91)

  I've only recently started to read this group, and I'm mystified by
all the references to J. I assume it is a language, if so, what
relationship does it have to APL? I've used APL for many years and I've
never seen any other language that remotely resembled it. Is J such an
animal? Perhaps for the benefit of those new to J somebody could post a
listing showing where APL and J differ. I'm assuming J has some
relationship to APL because why would it be discussed here otherwise?

                        -Greg Trice- (greg.trice@canrem.uucp)
--
Canada Remote Systems.  Toronto, Ontario
NorthAmeriNet Host

rockwell@socrates.umd.edu (Raul Rockwell) (05/14/91)

Greg Trice:
     I've only recently started to read this group, and I'm mystified
   by all the references to J. I assume it is a language, if so, what
   relationship does it have to APL? I've used APL for many years and
   I've never seen any other language that remotely resembled it. Is J
   such an animal? Perhaps for the benefit of those new to J somebody
   could post a listing showing where APL and J differ. I'm assuming J
   has some relationship to APL because why would it be discussed here
   otherwise?

:-)

Well, it might help if I pointed out that Ken Iverson (and others)
designed J.  If you want more information, note that J is distributed
by Iverson Software, Inc.
   33 Major Street
   Toronto, Ontario
   M5S 2K9

Or, on the net, you can check out
   watserv1.waterloo.edu:languages/apl/j

The most noticeable differences between J and APL are:
   J uses ascii, rather than the APL character set
   J assignment is more powerful than APL
   J has a number of operators and functions which (as a general rule)
     are not present in APL.

I believe one way of describing the differences is to say that J is a
dialect of APL.  (If you're familiar with I.P. Sharp APL, J is closer
to that than, say APL2).

However, 
   +/1 2 3
6
in both languages.

Perhaps a better example of the differences is iota and reshape.  In
APL,  iota 5 gives either
1 2 3 4 5
or
0 1 2 3 4

In J, iota is replaces with 'i.', and  i. 5 yields
0 1 2 3 4

In APL, 2 rho 3 2 rho iota 6 (I'm going to assume quadIO is 0) yields:
0 1


In J, reshape is indicated by $, and  2 $ 3 2 $ i. 6 yields
0 1
2 3

but   2 $, 3 2 $, i.6   yields
0 1

($ reshapes along the first dimension, and you must ravel higher
ranked arrays if you want exactly the same behavior as APL).


There are lots more differences (for instance, J uses assignment to
generate functions, rather than the del editor), but the best way to
find out what they are is plunk down 24 dollars and get a copy of the
current version of the language (and the documentation), then work
your way through the tutorials.  (Or ftp to watserv1, but you don't
get much in the way of docs from there :-(

Raul Rockwell

hui@yrloc.ipsa.reuter.COM (Roger Hui) (05/15/91)

J is a dialect of APL defined by Ken Iverson's "A Dictionary of J".
It first became available at the APL90 conference in Copenhagen.
Salient characteristics:

- Shareware, available on a wide variety of machines: PC, Mac, Sun Sparc,
    Sun 3, AT&T 3B1, MIPS, SGI, Atari ST, IBM RS6000, NeXT, ...
- ASCII spelling (0-127, no special characters)
- Complex numbers; boxed arrays; etc.
- Equivalents to all the functions and operators in Sharp APL
- Adverbs and conjunctions (operators) accept any verb (function)
- User-defined adverbs and conjunctions
- Access to "native" files and other external facilities
- LinkJ permits calling between J and C

-----------------------------------------------------------------
Roger Hui
Iverson Software Inc., 33 Major Street, Toronto, Ontario  M5S 2K9
(416) 925 6096

kingsley@hpwrce.HP.COM (Kingsley Morse) (05/17/91)

Is J compiled or interpreted?

Is J available on HP platforms? Under X windows?

How is Iverson Software making any money by selling it for $25?

hui@yrloc.ipsa.reuter.COM (Roger Hui) (05/18/91)

a) J is an interpreter, but the subclass of verbs known as tacit 
definitions are compiled.  For example, the following verbs are compiled:
   square =. ^&2
   sqrt   =. ^&0.5
   norm   =. sqrt & (+/) & square

b) J is not yet available on any HP platform. If there is a demand
for such a port, then the main obstacle would be getting access 
to a machine to do the port. The system is written in C, and by now 
most of the portability bugs have been found.

There is no direct support for X Windows, but the related product
LinkJ allows calling between J and C.

c) How is Iverson Software making any money by selling it for $25?
Good question. However, you could have asked a better question,
because we are selling it for only $24.

-----------------------------------------------------------------
Roger Hui
Iverson Software Inc., 33 Major Street, Toronto, Ontario  M5S 2K9
(416) 925 6096

rbe@yrloc.ipsa.reuter.COM (Robert Bernecky) (05/18/91)

In article <1991May18.004902.29060@yrloc.ipsa.reuter.COM> hui@yrloc.ipsa.reuter.COM (Roger Hui) writes:
>a) J is an interpreter, but the subclass of verbs known as tacit 
>definitions are compiled.  For example, the following verbs are compiled:
>   square =. ^&2
>   sqrt   =. ^&0.5
>   norm   =. sqrt & (+/) & square
>

Umm, err. "The following verbs are compiled". Please Explain. 
My understanding ofcompilation is that you take advantage of knowledge about
data types, rank, shape, etc,  to produce highly efficient code.
Please tell me HOW J achieves this in tacit definition. It seems to me
that tacit definition appears to be more like C macro expansion than
compilation: e.g., destruction of any evidence of what you originally
wrote, rather than true compilation(Destruction plus substantial
performance improvement).

Furthermore, it appears to my naive view that Tacit Defn also 
makes it impossiblw to debug a system unless you have maintained 
source files for everything. For example, if you have  a defn for 
a function "foo" which calls  "mean",and you define it using tacit defn,
and LATER discover a bug in "mean", you end up fixing "mean", BUT

"foo" is NOT fixed unless you recompile the universe.

This strikes me as :

a. making Real Programs, rather than Toy Programs, harder to develop
   and debug.

b. Increasing the liklihood of bugs in Real Programs.

Bob

Robert Bernecky      rbe@yrloc.ipsa.reuter.com  bernecky@itrchq.itrc.on.ca 
Snake Island Research Inc  (416) 368-6944   FAX: (416) 360-4694 
18 Fifth Street, Ward's Island
Toronto, Ontario M5J 2B9 
Canada

hui@yrloc.ipsa.reuter.COM (Roger Hui) (05/18/91)

Reply to article by Robert Bernecky, 1991 May 18:

>Umm, err. "The following verbs are compiled". Please Explain. 
>My understanding ofcompilation is that you take advantage of knowledge about
>data types, rank, shape, etc,  to produce highly efficient code.
>Please tell me HOW J achieves this in tacit definition. It seems to me
>that tacit definition appears to be more like C macro expansion than
>compilation: e.g., destruction of any evidence of what you originally
>wrote, rather than true compilation(Destruction plus substantial
>performance improvement).

The verbs I cited are "compiled", in the sense that they are re-executed
without having to reparse the source.  The original question was "Is J
compiled or interpreted?", and I believe my description of J as an
interpreter with certain things compiled is fair and accurate.

Re your parenthetical definition of "true compilation" -- destruction
plus substantial performance improvement:  Some compilers bill themselves
as "optimizing compilers".  Does this mean that non-optimizing
compilers are not performing "true compilation"?  Whether something is 
a compiler is a matter of what methods are used to execute sentences.
While compiled code generally perform better than interpreted code,
the performance improvement is not a defining characteristic of a compiler.

As it happens, the technique that J uses for tacit defns does result in
measurable performance improvement, relative to the equivalent explicit defn.

>Furthermore, it appears to my naive view that Tacit Defn also 
>makes it impossiblw to debug a system unless you have maintained 
>source files for everything. For example, if you have  a defn for 
>a function "foo" which calls  "mean",and you define it using tacit defn,
>and LATER discover a bug in "mean", you end up fixing "mean", BUT
>"foo" is NOT fixed unless you recompile the universe.
>
>This strikes me as :
>a. making Real Programs, rather than Toy Programs, harder to develop and debug.
>b. Increasing the liklihood of bugs in Real Programs.

Well, one does maintain source files for C or Fortran or Pascal programs;
and if there is no "make" facility, then one would possibly recompile
everything.  (Does "true compilation" require a "make" facility?)  As well, 
the evoke (~) adverb in J allows avoiding this complete recompilation.

I am sure that YOUR compiler would address these issues.  Perhaps we can 
carry out further discussions offline.

-----------------------------------------------------------------
Roger Hui
Iverson Software Inc., 33 Major Street, Toronto, Ontario  M5S 2K9
(416) 925 6096

rockwell@socrates.umd.edu (Raul Rockwell) (05/18/91)

Roger Hui:
   >a) J is an interpreter, but the subclass of verbs known as tacit
   >definitions are compiled.  For example, the following verbs are
   >compiled:
   >   square =. ^&2
   >   sqrt   =. ^&0.5
   >   norm   =. sqrt & (+/) & square

Robert Bernecky:
   Umm, err. "The following verbs are compiled". Please Explain.  My
   understanding ofcompilation is that you take advantage of knowledge
   about data types, rank, shape, etc, to produce highly efficient
   code.

   Please tell me HOW J achieves this in tacit definition.

Don't forget knowledge of data values and, similarly, function
properties.  One of my favorite compiled functions, SORTCUT, is an
implementation of  '':(+/  @  (<:/)  &  (>./\) )"1

Now, the pre-processor and the main computation are both O(n^2), where
n is the number of elements in a list, but SORTCUT is O(n) :-)
It is true you get speedups from knowing type, rank, etc., but in this
case the big speed ups come from (*) knowing that >. is associative,
and (*) knowing that the result of >./\ is nondecreasing.

   Furthermore, it appears to my naive view that Tacit Defn also makes
   it impossible to debug a system unless you have maintained source
   files for everything.

er... but that's already covered by the language semantics.  Isn't it?

Raul Rockwell

rbe@yrloc.ipsa.reuter.COM (Robert Bernecky) (05/20/91)

In article <ROCKWELL.91May18095711@socrates.umd.edu> rockwell@socrates.umd.edu (Raul Rockwell) writes:
>properties.  One of my favorite compiled functions, SORTCUT, is an
>implementation of  '':(+/  @  (<:/)  &  (>./\) )"1
>
>Now, the pre-processor and the main computation are both O(n^2), where
>n is the number of elements in a list, but SORTCUT is O(n) :-)
>It is true you get speedups from knowing type, rank, etc., but in this
>case the big speed ups come from (*) knowing that >. is associative,


I think my objection to Roger's use of the term "compiled" might be
addressed in a way which also covers your computational complexity argument
by  a definition of the following nature:

Compilation: The process of translating an algorithm expressed in an
  arbitrary notation into another notation which has execution speed
  properties which approximate those of hand-written assembler code.


Now, there ARE problems with this definition:
a. Whose assembler code?

b. Assembler code written for a RISC machine, without attention to 
   code-scheduling issues, might execute worse than that resulting
   from a C compiler.

The point I want to make is that I think of compiled code as being
something that runs about the same speed as the same algorithm coded
in C, the above statement notwithstanding. Ten or a hundred times
slower doesn't count.

Bob

hui@yrloc.ipsa.reuter.COM (Roger Hui) (05/20/91)

Robert Bernecky writes:

>The point I want to make is that I think of compiled code as being
>something that runs about the same speed as the same algorithm coded
>in C, the above statement notwithstanding. Ten or a hundred times
>slower doesn't count.

Bob, you should try timing  nub0 =. ~.  against  nub1 =. #~ i.@# = i.~
The former, being primitive, is coded in C; the latter is an example
of a "compiled" tacit definition.

-----------------------------------------------------------------
Roger Hui
Iverson Software Inc., 33 Major Street, Toronto, Ontario  M5S 2K9
(416) 925 6096

rockwell@socrates.umd.edu (Raul Rockwell) (05/20/91)

Robert Bernecky:
   I think my objection to Roger's use of the term "compiled" might be
   addressed in a way which also covers your computational complexity
   argument by a definition of the following nature:

   Compilation: The process of translating an algorithm expressed in
      an arbitrary notation into another notation which has execution
      speed properties which approximate those of hand-written
      assembler code.

Hmmm... but that doesn't conflict with

Roger Hui:
   ... the subclass of verbs known as tacit definitions are compiled.
   For example, the following verbs are compiled: 
      square =. ^&2
      ...

After all,  ^&2  is an algorithm (though rather minimalist :-), and it
is getting translated.  You could also say that the code for ^&2 was
compiled at the same time the interpreter was compiled, that fits
right in with what he said.  Seems perfectly clear.

Now if he was speaking and introducing new concepts left and right, as
the ISI people seem to do, I'd hope that he elucidated the concepts a
bit more (or that a transcript would become available so I could see
what I missed when I was thinking :-).

But (in my case, at least) this concept is an old familiar one:
compilation (including partial compilation) as a form of partial
evaluation.  Technically, you could consider any constructed J verb as
compiled, with a probable exception in the case of  :  and ".

That reminds me.  Has anyone besides me noticed that the transitive
form of | is the same as the transitive form of #: (except for rank).
Has anyone noticed any other verbs which differ only in rank?

Raul Rockwell