J (programming language)

Last updated
J
J (programming language) icon.png
Paradigm Array, functional, object-oriented (class-based, prototype-based), function-level, tacit
Designed by Kenneth E. Iverson, Roger Hui
Developer JSoftware
First appeared1990;33 years ago (1990)
Stable release
J9.4 / 1 March 2023;8 months ago (2023-03-01) [1]
Typing discipline dynamic
OS Cross-platform: Windows, Linux, macOS, Android, iOS, Raspberry Pi [2]
License GPLv3
Website www.jsoftware.com
Major implementations
J
Influenced by
APL, FL
Influenced
NumPy, [3] SuperCollider [4]

The J programming language, developed in the early 1990s by Kenneth E. Iverson and Roger Hui, [5] [6] is an array programming language based primarily on APL (also by Iverson).

Contents

To avoid repeating the APL special-character problem, J uses only the basic ASCII character set, resorting to the use of the dot and colon as inflections [7] to form short words similar to digraphs . Most such primary (or primitive) J words serve as mathematical symbols, with the dot or colon extending the meaning of the basic characters available. Also, many characters which in other languages often must be paired (such as [] {} "" `` or <>) are treated by J as stand-alone words or, when inflected, as single-character roots of multi-character words.

J is a very terse array programming language, and is most suited to mathematical and statistical programming, especially when performing operations on matrices. It has also been used in extreme programming [8] and network performance analysis. [9]

Like John Backus's languages FP and FL, J supports function-level programming via its tacit programming features.

Unlike most languages that support object-oriented programming, J's flexible hierarchical namespace scheme (where every name exists in a specific locale) can be effectively used as a framework for both class-based and prototype-based object-oriented programming.

Since March 2011, J is free and open-source software under the GNU General Public License version 3 (GPLv3). [10] [11] [12] One may also purchase source under a negotiated license. [13]

Examples

J permits point-free style and function composition. Thus, its programs can be very terse and are considered difficult to read by some programmers.

The "Hello, World!" program in J is:

'Hello, World!'

This implementation of hello world reflects the traditional use of J – programs are entered into a J interpreter session, and the results of expressions are displayed. It's also possible to arrange for J scripts to be executed as standalone programs. Here's how this might look on a Unix system:

#!/bin/jcecho'Hello, world!'exit''

(Note that current j implementations install either jconsole or (because jconsole is used by java), ijconsole and likely install this to /usr/bin or some other directory (perhaps the Application directory on OSX). So, there's a system dependency here which the user would have to solve.)

Historically, APL used / to indicate the fold, so +/1 2 3 was equivalent to 1+2+3. Meanwhile, division was represented with the mathematical division symbol (÷).

Because ASCII does not include a division symbol per se, J uses % to represent division, as a visual approximation or reminder. (This illustrates something of the mnemonic character of J's tokens, and some of the quandaries imposed by the use of ASCII.)

Defining a J function named avg to calculate the average of a list of numbers yields:

avg=:+/%#

This is a test execution of the function:

avg12342.5

Above, avg is defined using a train of three verbs (+/, %, and #) termed a fork. Specifically, (V0 V1 V2) Ny is the same as (V0(Ny)) V1 (V2(Ny)) which shows some of the power of J. (Here V0, V1, and V2 denote verbs and Ny denotes a noun.)

Some examples of using avg:

v=:?.20$100NB. a random vectorv46 55 79 52 54 39 60 57 60 94 46 78 13 18 51 92 78 60 90 62avgv59.2
4avg\vNB. moving average on periods of size 458 60 56 51.25 52.5 54 67.75 64.25 69.5 57.75 38.75 40 43.5 59.75 70.25 80 72.5
m=:?.45$50NB. a random matrixm46  5 29  2  4 39 10  7 10 44 46 28 13 18  1 42 28 10 40 12
avg"1mNB. apply avg to each rank 1 subarray (each row) of m17.2 22 21.2 26.4

Rank is a crucial concept in J. Its significance in J is similar to the significance of select in SQL and of while in C.

Implementing quicksort, from the J Dictionary yields:

sel=:adverbdef'u # ['quicksort=:verbdefineif.1>:#ydo.yelse.(quicksorty<sele),(y=sele),quicksorty>sele=.y{~?#yend.)

The following is an implementation of quicksort demonstrating tacit programming. The latter involves composing functions together and not referring explicitly to any variables. J's support for forks and hooks dictates rules on how arguments applied to this function will be applied to its component functions.

quicksort=:(($:@(<#[),(=#[),$:@(>#[))({~?@#))^:(1<#)

Sorting in J is usually accomplished using the built-in (primitive) verbs /: (sort up) and \: (sort down). User-defined sorts such as quicksort, above, typically are for illustration only.

The following example demonstrates the usage of the self-reference verb $: to recursively calculate fibonacci numbers:

1:`($:@-&2+$:@<:)@.(>&2)

This recursion can also be accomplished by referring to the verb by name, although this is of course only possible if the verb is named:

fibonacci=:1:`(fibonacci@-&2+fibonacci@<:)@.(>&2)

The following expression exhibits pi with n digits and demonstrates the extended precision abilities of J:

n=:50NB. set n as the number of digits required<.@o.10x^nNB. extended precision 10 to the nth * pi314159265358979323846264338327950288419716939937510

Verbs and Modifiers

A program or routine - something that takes data as input and produces data as output - is called a verb. J has a rich set of predefined verbs, all of which work on multiple data types automatically: for example, the verb i. searches within arrays of any size to find matches:

314159i.31NB. find the index of the first occurrence of 3, and of 101314159i:31NB. find the index of the last occurrence of 3, and of 103

User programs can be named and used wherever primitives are allowed.

The power of J comes largely from its modifiers: symbols that take nouns and verbs as operands and apply the operands in a specified way. For example, the modifier / takes one operand, a verb to its left, and produces a verb that applies that verb between each item of its argument. That is, +/ is a verb, defined as 'apply + between the items of your argument' Thus, the sentence

+/12345

produces the effect of

1+2+3+4+5+/1234515

J has roughly two dozen of these modifiers. All of them can apply to any verb, even a user-written verb, and users may write their own modifiers. While modifiers are powerful individually, allowing

some of the modifiers control the order in which components are executed, allowing modifiers to be combined in any order to produce the unlimited variety of operations needed for practical programming.

Data types and structures

J supports three simple types:

Of these, numeric has the most variants.

One of J's numeric types is the bit. There are two bit values: 0, and 1. Also, bits can be formed into lists. For example, 1 0 1 0 1 1 0 0 is a list of eight bits. Syntactically, the J parser treats that as one word. (The space character is recognized as a word-forming character between what would otherwise be numeric words.) Lists of arbitrary length are supported.

Further, J supports all the usual binary operations on these lists, such as and, or, exclusive or, rotate, shift, not, etc. For example,

  1 0 0 1 0 0 1 0 +. 0 1 0 1 1 0 1 0     NB. or1 1 0 1 1 0 1 0
  3 |. 1 0 1 1 0 0 1 1 1 1 1             NB. rotate1 0 0 1 1 1 1 1 1 0 1

J also supports higher order arrays of bits. They can be formed into two-dimensional, three-dimensional, etc. arrays. The above operations perform equally well on these arrays.

Other numeric types include integer (e.g., 3, 42), floating point (3.14, 8.8e22), complex (0j1, 2.5j3e88), extended precision integer (12345678901234567890x), and (extended precision) rational fraction (1r2, 3r4). As with bits, these can be formed into lists or arbitrarily dimensioned arrays. As with bits, operations are performed on all numbers in an array.

Lists of bits can be converted to integer using the #. verb. Integers can be converted to lists of bits using the #: verb. (When parsing J, . (period) and : (colon) are word-forming characters. They are never tokens alone, unless preceded by whitespace characters.)

J also supports the literal (character) type. Literals are enclosed in quotes, for example, 'a' or 'b'. Lists of literals are also supported using the usual convention of putting multiple characters in quotes, such as 'abcdefg'. Typically, individual literals are 8-bits wide (ASCII), but J also supports other literals (Unicode). Numeric and boolean operations are not supported on literals, but collection-oriented operations (such as rotate) are supported.

Finally, there is a boxed data type. Typically, data is put in a box using the < operation (with no left argument; if there's a left argument, this would be the less than operation). This is analogous to C's & operation (with no left argument). However, where the result of C's & has reference semantics, the result of J's < has value semantics. In other words, < is a function and it produces a result. The result has 0 dimensions, regardless of the structure of the contained data. From the viewpoint of a J programmer, <puts the data into a box and allows working with an array of boxes (it can be assembled with other boxes, and/or more copies can be made of the box).

  <1 0 0 1 0 +---------+ |1 0 0 1 0| +---------+

The only collection type offered by J is the arbitrarily dimensioned array. Most algorithms can be expressed very concisely using operations on these arrays.

J's arrays are homogeneously typed, for example the list 1 2 3 is a list of integers despite 1 being a bit. For the most part, these sorts of type issues are transparent to programmers. Only certain specialized operations reveal differences in type. For example, the list 1.0 0.0 1.0 0.0 would be treated exactly the same, by most operations, as the list 1 0 1 0 .

J also supports sparse numeric arrays where non-zero values are stored with their indices. This is an efficient mechanism where relatively few values are non-zero.

J also supports objects and classes, [14] but these are an artifact of the way things are named, and are not data types. Instead, boxed literals are used to refer to objects (and classes). J data has value semantics, but objects and classes need reference semantics.[ citation needed ]

Another pseudo-type—associated with name, rather than value—is the memory mapped file.

Debugging

Dissecting the Collatz sequence starting from 6 Dissect example Collatz.png
Dissecting the Collatz sequence starting from 6

J has the usual facilities for stopping on error or at specified places within verbs. It also has a unique visual debugger, called Dissect, that gives a 2-D interactive display of the execution of a single J sentence. Because a single sentence of J performs as much computation as an entire subroutine in lower-level languages, the visual display is quite helpful.

Documentation

J's documentation includes a dictionary, with words in J identified as nouns, verbs, modifiers, and so on. Primary words are listed in the vocabulary, in which their respective parts of speech are indicated using markup. Note that verbs have two forms: monadic (arguments only on the right) and dyadic (arguments on the left and on the right). For example, in '-1' the hyphen is a monadic verb, and in '3-2' the hyphen is a dyadic verb. The monadic definition is mostly independent of the dyadic definition, regardless of whether the verb is a primitive verb or a derived verb.

Control structures

J provides control structures (details here) similar to other procedural languages. Prominent control words in each category include:

See also

Related Research Articles

<span class="mw-page-title-main">APL (programming language)</span> Functional programming language for arrays

APL is a programming language developed in the 1960s by Kenneth E. Iverson. Its central datatype is the multidimensional array. It uses a large range of special graphic symbols to represent most functions and operators, leading to very concise code. It has been an important influence on the development of concept modeling, spreadsheets, functional programming, and computer math packages. It has also inspired several other programming languages.

C is a general-purpose computer programming language. It was created in the 1970s by Dennis Ritchie, and remains very widely used and influential. By design, C's features cleanly reflect the capabilities of the targeted CPUs. It has found lasting use in operating systems, device drivers, and protocol stacks, but its use in application software has been decreasing. C is commonly used on computer architectures that range from the largest supercomputers to the smallest microcontrollers and embedded systems.

In computer science, an integer is a datum of integral data type, a data type that represents some range of mathematical integers. Integral data types may be of different sizes and may or may not be allowed to contain negative values. Integers are commonly represented in a computer as a group of binary digits (bits). The size of the grouping varies so the set of integer sizes available varies between different types of computers. Computer hardware nearly always provides a way to represent a processor register or memory address as an integer.

Nial is a high-level array programming language developed from about 1981 by Mike Jenkins of Queen's University, Kingston, Ontario, Canada. Jenkins co-created the Jenkins–Traub algorithm.

<span class="mw-page-title-main">Data type</span> Attribute of data

In computer science and computer programming, a data type is a collection or grouping of data values, usually specified by a set of possible values, a set of allowed operations on these values, and/or a representation of these values as machine types. A data type specification in a program constrains the possible values that an expression, such as a variable or a function call, might take. On literal data, it tells the compiler or interpreter how the programmer intends to use the data. Most programming languages support basic data types of integer numbers, floating-point numbers, characters and Booleans.

<span class="mw-page-title-main">Kenneth E. Iverson</span> Canadian computer scientist (1920–2004)

Kenneth Eugene Iverson was a Canadian computer scientist noted for the development of the programming language APL. He was honored with the Turing Award in 1979 "for his pioneering effort in programming languages and mathematical notation resulting in what the computing field now knows as APL; for his contributions to the implementation of interactive systems, to educational uses of APL, and to programming language theory and practice".

In computer science, primitive data types are a set of basic data types from which all other data types are constructed. Specifically it often refers to the limited set of data representations in use by a particular processor, which all compiled programs must use. Most processors support a similar set of primitive data types, although the specific representations vary. More generally, "primitive data types" may refer to the standard data types built into a programming language. Data types which are not primitive are referred to as derived or composite.

<span class="mw-page-title-main">C syntax</span> Set of rules defining correctly structured programs

The syntax of the C programming language is the set of rules governing writing of software in C. It is designed to allow for programs that are extremely terse, have a close relationship with the resulting object code, and yet provide relatively high-level data abstraction. C was the first widely successful high-level language for portable operating-system development.

<span class="mw-page-title-main">C99</span> C programming language standard, 1999 revision

C99 is an informal name for ISO/IEC 9899:1999, a past version of the C programming language standard. It extends the previous version (C90) with new features for the language and the standard library, and helps implementations make better use of available computer hardware, such as IEEE 754-1985 floating-point arithmetic, and compiler technology. The C11 version of the C programming language standard, published in 2011, replaces C99.

K is a proprietary array processing programming language developed by Arthur Whitney and commercialized by Kx Systems. The language serves as the foundation for kdb+, an in-memory, column-based database, and other related financial products. The language, originally developed in 1993, is a variant of APL and contains elements of Scheme. Advocates of the language emphasize its speed, facility in handling arrays, and expressive syntax.

In computer programming, a one-liner program originally was textual input to the command line of an operating system shell that performed some function in just one line of input. In the present day, a one-liner can be

F-Script is an object-oriented scripting programming language for Apple's macOS operating system developed by Philippe Mougin. F-Script is an interactive language based on Smalltalk, using macOS's native Cocoa API.

<span class="mw-page-title-main">Raku (programming language)</span> Programming language derived from Perl

Raku is a member of the Perl family of programming languages. Formerly known as Perl 6, it was renamed in October 2019. Raku introduces elements of many modern and historical languages. Compatibility with Perl was not a goal, though a compatibility mode is part of the specification. The design process for Raku began in 2000.

A bit array is an array data structure that compactly stores bits. It can be used to implement a simple set data structure. A bit array is effective at exploiting bit-level parallelism in hardware to perform operations quickly. A typical bit array stores kw bits, where w is the number of bits in the unit of storage, such as a byte or word, and k is some nonnegative integer. If w does not divide the number of bits to be stored, some space is wasted due to internal fragmentation.

The computer programming languages C and Pascal have similar times of origin, influences, and purposes. Both were used to design their own compilers early in their lifetimes. The original Pascal definition appeared in 1969 and a first compiler in 1970. The first version of C appeared in 1972.

Rank is a generalization of looping as used in scalar (non-array-oriented) programming languages. It is also a generalization of mapcar in the language Lisp and map in modern functional programming languages, and a generalization of scalar extension, inner (matrix) product, and outer product in APL\360. The canonical implementation of rank may be the language J, but it is also available in Dyalog APL, the International Organization for Standardization (ISO) technical standard on Extended APL, and NARS2000.

The programming language APL is distinctive in being symbolic rather than lexical: its primitives are denoted by symbols, not words. These symbols were originally devised as a mathematical notation to describe algorithms. APL programmers often assign informal names when discussing functions and operators but the core functions and operators provided by the language are denoted by non-textual symbols.

This is an overview of Fortran 95 language features. Included are the additional features of TR-15581:Enhanced Data Type Facilities, which have been universally implemented. Old features that have been superseded by new ones are not described – few of those historic features are used in modern programs although most have been retained in the language to maintain backward compatibility. The current standard is Fortran 2018; many of its new features are still being implemented in compilers. The additional features of Fortran 2003, Fortran 2008 and Fortran 2018 are described by Metcalf, Reid and Cohen.

<span class="mw-page-title-main">Speakeasy (computational environment)</span> Computer software environment with own programming language

Speakeasy was a numerical computing interactive environment also featuring an interpreted programming language. It was initially developed for internal use at the Physics Division of Argonne National Laboratory by the theoretical physicist Stanley Cohen. He eventually founded Speakeasy Computing Corporation to make the program available commercially.

The structure of the Perl programming language encompasses both the syntactical rules of the language and the general ways in which programs are organized. Perl's design philosophy is expressed in the commonly cited motto "there's more than one way to do it". As a multi-paradigm, dynamically typed language, Perl allows a great degree of flexibility in program design. Perl also encourages modularization; this has been attributed to the component-based design structure of its Unix roots, and is responsible for the size of the CPAN archive, a community-maintained repository of more than 100,000 modules.

References

  1. "J9.4 released on March 1st, 2023".
  2. "Jsoftware".
  3. Wes McKinney at 2012 meeting Python for Data Analysis
  4. SuperCollider documentation, Adverbs for Binary Operators
  5. A Personal View of APL, 1991 essay by K.E. Iverson (archived link)
  6. Overview of J history by Roger Hui (19 March 2002)
  7. J NuVoc Words
  8. Bussell, Brian; Taylor, Stephen (2006), "Software Development as a Collaborative Writing Project", Extreme programming and agile processes in software engineering, Oulu, Finland: Springer, pp. 21–31, ISBN   978-3-540-35094-1 {{citation}}: Missing or empty |title= (help)
  9. Holt, Alan (2007), Network Performance Analysis: Using the J Programming Language, Springer, ISBN   978-1-84628-822-7
  10. Jsoftware's source download page
  11. Eric Iverson (1 March 2011). "J Source GPL". J programming mailing list. Archived from the original on 23 September 2016. Retrieved 24 June 2015.
  12. openj on GitHub
  13. Jsoftware's sourcing policy
  14. Chapter 25: Object-Oriented Programming