Here I shall talk about a powerful calculator called J. In fact,
it is so powerful that we should better not call it a
calculator. It is a powerful programming language. But it is so
concise that it looks more like a calculator than a programming
language.
You have all the standard arithmetic operations, +
means addition, - is subtraction and * is
multiplication. But the symbol for division is %. A bit of
a surprise, but not much. The symbol ^ is for
exponentiation. You can use ( and ) as usual.
Nothing particularly strange so far. Now comes the first
shock. All computations are done right-to-left. Thus
2+3*5 and 3*5+2 will produce different
results. Irritating? Well, not quite. Actually, it saves typing a
lot of ()'s. In usual notation we have to plan where to
put the ()'s, and then have to actually type them. In J we
have to plan the order, and there is nothing to type.
exp(x) is ^. Oops, how
can that be? Did we not say just a moment ago that ^ is
for raising to power? Well, yes. But if you type ^3, then
clearly there is no number to the left of ^. So J supplies
e there. And since
exp(x) is indeed some form of power, it is
not much difficult to remember either!
J uses rather short names. They are easy to type (almost like
pressing a single button in a calculator), but a bit cryptic. J
tries to help by using similar symbols for similar functions. For
example, ln(x) is closely related to exp(x), and is denoted in J
by ^. The extra period is called an inflection. There is
another inflection, the colon. Thus if s is a symbol then
typically s. and s: are two related symbols. And each has a monad
meaning and a dyad meaning. Thus with each symbol J can associate
6 meanings.
Here is an example of such similar symbols. > means
greater than. No surprise here. Closely relate with is
greater-than-or-equal which is denoted by >:. If you want
to compute maximum of two numbers use >. as a dyad.
Ceiling is computed by >.. You have the obvious analogues
for <. Of course, it is rather tedious to memorise all
the 6 meanings attached to a symbol. It is somewhat like trying
to improve your vocabulary by cramming a dictionary. But it is
good to know.
If we want to compute absolute value, then use |. Yes,
just a single vertical bar! If we want to get remainder, then
again the same symbol is used, but as 3 | 5.
You can compute factorial or choose using !.
You may compute $\sin x$, $\cos x$ etc in a rather
remarkable way using the same verb o.. For example, 1
o. x is $\sin x$, while 2 o. x is $\cos x$
and 3 o. x is $\tan x$. If these look irritating you
may
load 'trig' and write more conventionally sin
x, cos x etc. If $\sin x$ is 1 o. x then
what should be the command for $\sin ^{-1}x$? It is _1
o. x.
J has some functions that are often not available in a
calculator. These are not terribly important, but often comes
handy. Let's get acquainted with a few such. % is for
reciprocal.
If I type 2+%3 that
will mean two plus one-third.
%: will compute square root.
4 ^. 56 will compute log of
56 to the base 4. Not many calculators come equipped with a log
for arbit bases.
A rather stunning function is #:. Used as a monad it
produces binary representations of integers. As a dyad it can
fold into hierarchical unit systems. For example,
60 seconds make a minute, 60 minutes an hour, 24 hours a day.
You can convert 126547 seconds to day, hr, min, sec as
24 60 60 #: 126547.
Of course, you may convert 45678 to base 7 (showing least
significant 4 digits) as 7 7 7 7 #: 45678
You can convert it back by using the related symbol #..
J can handle complex numbers. They are written like 1j2.
Rational numbers are written like 1r2.
Most modern languages allow lists. All elements of a list must of
the same type (numeric, character, lists or boxes, that we shall
talk about in a moment). You cannot mix
these. Also, if one elment is list all others must also be lists
of the same type and composition. A string is just list of
characters. Thus you cannot have a list with one element "emacs"
and another "vim", as these differ in size. But this will hardly
cause any problem, as J can pad the shorter one with blanks.
Sometimes hwever, you want to have a list with mixed types (or
strings with different lengths without having to pad with
blanks). Then boxes come handy. A box (whatever it may contain)
is always considered a single entity.
It is important to understand that a box may contain a list and
list may have a box as its element. But all elements in the same
list must be of the same type.
Let us start by understanding how to create lists.
The simplest way is to actually write the things one after
another. No delimiter of any sort is required.
Of course long lists are not easily created like this. So we have
some convenience methods: i. 4 and 4 # 2. These
also allow creation of lists of lists, etc.
Two lists may be combined in two different ways to produce a new
list. One is by appending using ,. For this both the lists
must have elements of identical structure (else padding will be
used). The other technique is to create a new doubleton
list with the input lists its elements. This is achieved with ,:.
# finds the length of a list. $ finds the shape.
A list may be considered as a map from index to element. This map
may be evaluated by {. Negative indices count from
end. Vector subscripting allowed. The inverse map is evaluted
by i.. For example 'abac' i. 'a' returns 0. Only
the position of the first occurence is reported. The
command e. checks containment.
We can subset a list as 1 0 0 1 1 # list. The boolean
vector may be created using the boolean operators.
If the subset is a pefix or suffix then {. (take)
or }. (drop) may be used.
A box is a data type that may contain anything. Whatever may its
content be, a box is always a single entity. We may have a list
of boxes that contain different types of objects. If you want to
have a list with the first element 'Shakespeare' and the second
element the entire text of Hamlet, then J will pad 'Shakespeare'
with a huge number of trailing blanks to make it as long as the
second element. This is rarely desireable. But if you put
'Shakespeare' in one box, and the text of Hamlet into another,
then you can create a list of these two boxes.
Something is put in a box like <'Shakespeare'. A box is
opened like >box. An empty box may be created using <i.0.
As boxing is most often followed by making a list of them, there
is a convenience method ; that is used like
'Shakespeare' ; 1 2 3 ; 29.
? 10 generates an unif random number from {0,...,9}.
(You may add 1 to it by >:). If you want an SRSWR of size
2 from this population then use ? 10 10. For an SRSWR of
size $n$ use ? n # 10.
SRSWOR of size $n$ from the same population may be drawn
using n ? 10.