Though J shares many concepts with APL, in many respects it is radically different, and almost all APL constructions that are in J differ in some way. These differences can be a stumbling block to the newcomer who thinks that J is simply an ASCII version of APL, prompting questions such as:
J uses terms from English grammar, thus a function such as addition is a verb (because it performs an action), and an entity that modifies a verb is called an adverb. Many APL primitives that are also in J have been renamed to better describe their behavior in J. Thus APL reduce becomes insert, APL scan becomes prefix, and the new reverse scan is suffix.
J terminology should be used whenever clarity of expression is important. Other terms commonly used in programming such as data, variable, function, operator, can then be used in specific contexts, e.g. "functions" in Calculus.
J uses the 7-bit ASCII alphabet. It also makes non-essential use of the box-drawing characters in the 8-bit ASCII alphabet for display. Using ASCII avoids the many problems associated with using APL symbols. It allows J to be used on a variety of machines without special hardware or software, and permits easy communication between J and other systems.
Language primitives typically consist of a single ASCII symbol, optionally followed by either a dot or colon, e.g. the symbols #, #. and #: are all valid J primitives. The J spelling scheme is quite mnemonic; the vocabulary is a careful piece of design and bears study. Consider:
+ conjugate . plus +. real/imag . GCD (or) +: double . nor * signum . times *. length/angle . LCM (and) *: square . nand - negate . minus -. not . less -: halve . match % reciprocal . div by %. matrix inverse . matrix div %: sqrt . root
+. for or and *. for and make the analogy of or as logical addition and and as logical multiplication. +. is extended to the entire numeric domain as the GCD function and likewise *. for LCM. The monad -. is logical negation, not, and is extended to the entire numeric domain as the function 1&- (probability complement). The dyad -. is set difference.
There is no 1-1 mapping between J and APL symbols:
The J language is essentially a superset of APL. All the standard APL functions are included in one form or another. Extensions include:
J numeric and character arrays are the same as in APL. J also supports complex numbers, extended (arbitrary-precision) integers and rationals, sparse arrays, symbols and unicode.
Boxed arrays are the same as in SHARP APL. They are similar to the enclosed arrays in other APL systems, except that the box of a scalar is not the same as the scalar.
Boxed arrays must be explicitly created as such; J does not have strand notation. The following example uses the verb ; link to link items together into a boxed array. Note that J boxes output automatically:
1 2 3;10 20 J +-----+-----+ |1 2 3|10 20| +-----+-----+ (1 2 3) (10 20) APL 1 2 3 10 20
Infinity, negative infinity, and indeterminate (_ __ _.) have been added. Numeric constants can be specified in several more ways, akin to 4e2 for 400. Thus 3j4 is the number with real part 3 and imaginary part 4, 7ad90 is the number with magnitude 7 and angle 90 degrees, 1.5ar_1 is the number with magnitude 1.5 and angle minus pi radians, 1r3 is the fraction one-third, etc.
J does not support heterogeneous arrays.
Verbs correspond to APL's functions.
J makes no distinction between primitive verbs and user-defined verbs, unlike APL, where some facilities (such as the axis operator) are only available for primitive functions.
There are no niladic verbs. This allows verbs to be assigned, if no argument is given. This function assignment is also available in APLW, but there can only work with verbs that are not niladic. The J equivalent of an APL niladic function is a monadic verb that ignores its argument, which nevertheless must be given.
If you enter the name of a verb alone, its definition is displayed (this is true of any J object).
All verbs are ambivalent, though the monadic or dyadic domain may be empty. If you invoke a verb with an empty domain, the result is domain error and not SYNTAX ERROR.
The left and right arguments of an explicitly defined verb are x. and y. .
All verbs return a result, which is the result of the last statement executed (other than test statements in control structures). Statements in defined verbs that are not assignments do not display their results in the session.
There is no equivalent to APL's list of local names in the function header. Indeed, J definitions do not have a header, since there is no need for one.
Adverbs and conjunctions correspond to APL's monadic and dyadic operators. The separate names for the two classes of operators reflect the importance of operators in J.
The result of an adverb is typically a verb; the result of a conjunction given one argument is typically an adverb, and given both arguments is typically a verb. However, adverbs and conjunctions may return any type of object.
Since a verb can have one or two arguments, and an operator argument can be a noun or a verb, then an adverb can have up to 4 cases, and a conjunction up to 8 cases:
n adv y m conj n y u conj n y x n adv y x m conj n y x u conj n y v adv y m conj v y u conj v y x v adv y x m conj v y x u conj v y
All these possibilities are in APL as well as J, but are exploited more systematically and more extensively in J.
Execution control is provided by control words, if. else. while. etc. There is no equivalent to APL's computed goto .
APL*PLUS III and Dyalog APLW have also added control words, thus making redundant, though it has been preserved for compatibility. J control words differ in two major respects, in that they are stream and block oriented: control words can occur in any part of a line of code, and they group the code into blocks. For example, compare:
:if statement-is-true APL
...
:else
...
:end
if. block-is-true do. ... else. ... end. J
where the APL statement is a single statement which must
return 0 or 1, whereas the J block can be any number of
J sentences (which may themselves contain control words). A J
block is true if the first element of the result is non-zero.
The power conjunction ^: provides another form of execution control. In the phrase v^:n y, the verb v is applied n times to the array y. Here, n may be an array of powers; infinite powers specify the limit of application of v. For example:
newton=. -:@(+ 2e4&%)
newton newton newton 1
2502.62
newton ^:3 [ 1
2502.62
newton ^:(i.3 5) [ 1
1 10000.5 5001.25 2502.62 1255.31
635.62 333.543 196.753 149.202 141.624
141.422 141.421 141.421 141.421 141.421
newton ^:_ [ 1
141.421
The agenda conjunction @. provides for if-then-else and case statements.
There is no equivalent of APL's diamond separator used to enter several statements on a single line. However, you can obtain similar behavior using the verb [ same which returns its left argument. Using this, statements are evaluated right to left.
Index origin is 0 throughout. There is no equivalent to APL's quadIO. (APL expressions used here assume quadIO<-0.) , which also use ordinary text files for program development. The focus on script files also eliminates the many problems associated with workspaces, such as the inability to browse through workspaces or to update one workspace with values from another.
The flat APL workspace is replaced by locales which allow you to partition the names in use. Thus, name conflicts are avoided when loading two applications at the same time, and commonly-used utility functions can be made available without their names cluttering up listings of work in progress. The idea is similar to the namespaces of Dyalog APL, though the implement differs in many respects.
The base (or no-name) locale is the default locale. The z locale is the parent locale. Definitions stored in either of these locales can be referenced directly, without specifying the locale name. Utility functions are typically stored in the z locale.
The functionality of APL's System Functions, System Variables and System Commands is provided by the foreign conjunction !: . This conjunction is defined for a variety of numeric arguments, grouped by type. For example, 1!:1 reads a file, and 1!:2 writes to a file.
The foreign conjunction builds ordinary J verbs !: is a conjunction syntactically like any other, and there is nothing special about the syntax of the resultant verbs, unlike the special syntax used in APL for System Commands, and for some System Functions. You can assign a name to any J verb derived from the foreign conjunction, but you could not, for example, provide a cover function for quadFMT