Tuesday, April 20, 2010

Using J : Part I - A Super Calculator

J is a VERY complex language, which takes a lot of effort to master, but doing simple things with it is easy. In this post I will demonstrate how it can be used as an advanced calculator.

If you type '2+2' into J you will get the expected result of '4'.

Similarly '3-2'' will give the expended '1', '2*3' yields the expected '6'.

J does not use '/' for division, instead it uses '%'. This is the first of many idiosyncrasies. So '6%2' yields '3'.

The next idiosyncrasy in J is the order that operators are evaluated in. As long as you only perform one operation per line there is no question about order, but is you put multiple operations together in a single line than the order of evaluation can be important. What is '5-3-2'? Is it 4 or is it 0? In J it is 4, because J works from right to left when evaluating. This means that '5*2+3' is 25, not 13 as you might expect. If you want any evaluation order other than strict right to left you must use parenthesis. '(5-3)-2' is 0 and '(5*2)+3' is 13.

To see the next idiosyncrasy, enter '2-3'. Instead of the expected '-1', you get '_1'. The reason for this is that unlike most languages, J does not use the same notation to indicate the unary operator (called a 'monadic verb' in J) additive inverse and a negative number. In J '-1' is a verb ('-') followed by a noun ('1') the result of this computation is '_1', which is just a noun.

Which brings me to the subject of the representation of numbers.

The simplest way to represent a floating point number is with a decimal point like this '34.87', with the one caveat that a number can not start with a '.', so you must include the leading 0 if the number is between 1 and _1. Another common way to represent is in exponential form. In J exponential form is written as two numbers separated with an 'e' no spaces allowed. The second number must be an integer. The result is the first number multiplied by 10 raised to the power of the second number. So '1.234e3' is the same as 1234.

Many programming languages let you express integers in bases other than ten, must often only bases 2, 8 & 16. J lets you express floating point numbers in any base (however I have not figured out how to express digits representing values greater than z which represents 35). To express a number in a base other than 10 first give the base then 'b' then the number represented in that base. It is interesting to note that the base does not need to be an integer. I have not yet though of any use for this feature, but you may be able to.

Two other unusual representations are supported by J. Exponential notation in bases Pi and e, 1p1 is Pi, 2p1 is 2*Pi, 1p2 is Pi squared, 2p2 is twice Pi Squared, etc. Similarly 1x1 is e (the base of natural logarithms, 2.71828 . . .) , 2x1 is 2e, 1x2 is e squared, etc.

Two other important numbers you might find useful are '_' and '__' which are the values the limit of 1 % x as x approaches 0 and the value of the limit of _1%x as x approaches 0. It is interesting to note that J believes that '0%0' is '0'.

Sometime you want more precision that you can get with floating point. If I enter the integer 1 J will assume I mean a floating point number very close to the integer 1. If I want the integer 1 I type '1x' for 1 exact. Now type '1x % 2' and see the results. '1r2' is a rational number with a numerator of 1 and a denominator of 2. 2r3 is two thirds.

J also supports complex numbers which are represented by the real and imaginary parts separated by a lowercase j. For example 2 + 4i is written as '2j4'.

You can give something an alias. For example, if you would rather use 'Pi' than '1p1' you could type 'Pi =: 1p1' and then any time you type 'Pi" it will be the same as if you had typed '1p1'. Any thing can be given an alias. If you type 'Plus =: +' then you can type '2 Plus 2' to get 4.

As you have seen '-' can be used as either a binary operator (called a 'dyadic verb' in J) is in '3-2' or as a unary operator (called a 'monadic verb' in J) as in '-2'. This is fairly common, But in J nearly all verbs have both a monodic and dyadic form.

The verb '%' has the dyadic form 'divide' and the monadic form 'reciprocal' so '%2' yields '0.5' and '%2x' yields '1r2'.

The verb '*' has the dyadic form 'times' and the monadic for 'signum' which returns '1' if the argument is positive, '_1' if it is negative and '0' if it is '0'.

The verb '+' has the dyadic form 'plus' and the monadic form 'conjugate'. Conjugating leave it unchanged, But when you conjugate a complex number it changes the sign of the imaginary component.

The square root operator (monadic verb) is '%:'. The dyadic form of %: is 'Root'. '3 %: 8' yields the third root of 8, or 2. One thing that does confuse me is how it choses which branch of the root to take. '3 %: _8' yields '1j1.73205' not '_2' as I would expect.

The power operator is '^'. In its dyadic form it raised its first operand to the power of its second operand. So '2^3' yields 8. In it monadic form it is called 'Exponential' and it raises Euler's number (the base of natural logarithms, e) to the given power.

The log operator is '^.' The Monadic form yield the natural log. The dyadic form yields the log given the bases. To get the common log of 100 us '10 ^. 100'. You can define a monadic verb to take the common log 'log =: 10&^.'. The '&' binds the left operand of 10 to the operator '^.'.

The residue operator is '|'. Residue is like mod, except that the order of the operand is reversed. If want the traditional mod operator it is easy to define 'mod =: |~'. Now you can use 'mod' like an any built in operator, '187 mod 10' yields '7', just as you would expect. The adverb '~' commutes the operands to the verb it modifies. The dyadic form of '|' is the magnitude, or the distance from zero, '|2' yields 2, as does '|_2', '|3j4' yields 5.

The factorial operator is '!', its dyadic form is called 'out of' or 'combinations', 'x!y' is '(!y)%(!x)*(!y-x)'.

Any good calculator needs to provide trigonometric functions. J does this in an unusual manner. The operator 'o.' is used. In it monadic form it simply multiplies a value by Pi. The dyadic form provides the trigonometric functions: '1o.' is the sine function; '_1o.' is the arcsine function; '2o.' and '_2o.' are cos and arccos respectively; '3o.' & '_3o.' are tan & arctan. The hyperbolic function are similar using 5, 6 & 7 for sinh, cosh and tanh. You may want to define the monadic following verbs:

  • sin=:1&o.
  • asin=:_1&o.
  • cos=:2&o.
  • acos=:_2&o.
  • tan=:3&o.
  • atan=:_3&o.
  • sinh=:5&o.
  • asinh=:_5&o.
  • cosh=:6&o.
  • acosh=:_6&o.
  • tanh=:7&o.
  • atanh=:_7&o.
the '&' operator binds an operand to an operator. I hope to discuss it in detail in a future post. Of course this assumes the angle is measured in radians. If you have it in degrees you need to multiply it by (1p1%180).

This gives you a good start, but it has not really scratched the suffice of the true power of J. Arrays are the heart of J, I hope to write about them soon. If you really want to get the full power out of J you will need to grok tacit programming, but you can go far without it.

Labels: , ,

2 Comments:

Anonymous SaferAddition said...

So, writing 5 + _3 + _2 would be safer since it brings the expected result without thinking right-left-ly!

Tuesday, April 27, 2010 at 8:20:00 AM UTC  
Blogger Ed said...

Not a bad idea.

Tuesday, April 27, 2010 at 10:54:00 AM UTC  

Post a Comment

<< Home